├── README.md
├── test.c
├── lonesha256.h
└── LICENSE
/README.md:
--------------------------------------------------------------------------------
1 | ## Documentation
2 |
3 | This is a header-only library, as such most of its functional documentation is contained within the "header section" of the
4 | source code in the form of comments. It is highly recommended that you read said documentation before using this library.
5 |
6 | ## Features
7 |
8 | The lonesha256 library provides portable sha256 hashing in a single function, its features include:
9 |
10 | - No hard dependencies besides the standard library, making it fully portable
11 | - Avoids endianness issues by relying entirely on endian-agnostic operations
12 | - Simple hashing in a single function without any convoluted initialization
13 |
14 | ## Attribution
15 |
16 | You are not required to give attribution when using this library. If you want to give attribution anyway, either link to
17 | this repository, [my website](https://www.slopegames.com/), or credit me as [BareRose](https://github.com/BareRose).
18 | If you want to support me financially, consider giving to my [Patreon](https://www.patreon.com/slopegames).
19 |
20 | ## License
21 |
22 | Licensed under CC0 aka the most lawyer-friendly way of spelling "public domain".
--------------------------------------------------------------------------------
/test.c:
--------------------------------------------------------------------------------
1 | /*
2 | lonesha256.h test by comparison with known hashes of strings, also serves as usage example
3 |
4 | To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring
5 | rights to this software to the public domain worldwide. This software is distributed without any warranty.
6 | You should have received a copy of the CC0 Public Domain Dedication along with this software.
7 | If not, see .
8 | */
9 |
10 | /*
11 | Compile using "gcc test.c" or equivalent, then run from command line to see the results.
12 | If you find an error in this test or a test pair which lonesha256 fails, please open an issue.
13 | */
14 |
15 | //includes
16 | #define LONESHA256_STATIC
17 | #include "lonesha256.h"
18 | #include
19 |
20 | //structs
21 | struct pair {
22 | unsigned char* in; //input string
23 | unsigned char out[32]; //expected output
24 | };
25 |
26 | //known input/output pairs
27 | struct pair pairs[] = {
28 | //0: empty string
29 | {
30 | "",
31 | {0xE3, 0xB0, 0xC4, 0x42, 0x98, 0xFC, 0x1C, 0x14,
32 | 0x9A, 0xFB, 0xF4, 0xC8, 0x99, 0x6F, 0xB9, 0x24,
33 | 0x27, 0xAE, 0x41, 0xE4, 0x64, 0x9B, 0x93, 0x4C,
34 | 0xA4, 0x95, 0x99, 0x1B, 0x78, 0x52, 0xB8, 0x55}
35 | },
36 | //1: foobar string
37 | {
38 | "foobar",
39 | {0xC3, 0xAB, 0x8F, 0xF1, 0x37, 0x20, 0xE8, 0xAD,
40 | 0x90, 0x47, 0xDD, 0x39, 0x46, 0x6B, 0x3C, 0x89,
41 | 0x74, 0xE5, 0x92, 0xC2, 0xFA, 0x38, 0x3D, 0x4A,
42 | 0x39, 0x60, 0x71, 0x4C, 0xAE, 0xF0, 0xC4, 0xF2}
43 | },
44 | //2: quick brown fox
45 | {
46 | "The quick brown fox jumps over the lazy dog",
47 | {0xD7, 0xA8, 0xFB, 0xB3, 0x07, 0xD7, 0x80, 0x94,
48 | 0x69, 0xCA, 0x9A, 0xBC, 0xB0, 0x08, 0x2E, 0x4F,
49 | 0x8D, 0x56, 0x51, 0xE4, 0x6D, 0x3C, 0xDB, 0x76,
50 | 0x2D, 0x02, 0xD0, 0xBF, 0x37, 0xC9, 0xE5, 0x92}
51 | },
52 | //3: random string
53 | {
54 | "dThNFRWWhyG7pINI",
55 | {0x64, 0x13, 0x46, 0x80, 0xDC, 0x26, 0x6E, 0x5D,
56 | 0xFF, 0xE3, 0x83, 0xBD, 0xC4, 0xD1, 0x98, 0xC3,
57 | 0xA3, 0x59, 0x2C, 0x36, 0xB4, 0x78, 0xCE, 0xBE,
58 | 0xD6, 0x6C, 0x15, 0x8F, 0x78, 0x82, 0x5A, 0x28}
59 | },
60 | //4: longer string
61 | {
62 | "laSQWLJtfvdfSvH9MaJC32tk59jpm3ZOkfQX2E308aUqgyqY"
63 | "Tq2hOyoLJaujn4ULaFDEb65ISERxjSqovIiccU1q8TxsBwm6"
64 | "qodWbY3mUdPL0YuRrN9RggDzkvHQz91XbpoItjPB7mxtzILt"
65 | "lypZtfJY3A3xh0B4ZrsRM2FTtcircLWRfDOpGIGbQcJoXeZq"
66 | "vKdvzrGbs6oG8wKAYKn51j3aQDNmENXGlYR06eRXFyctEU3g"
67 | "HDaXB6shHCa621wAIPn3ZjtaPzkYjFIQv2NwAnmLCSxOlhqs"
68 | "pCoaNVwHfHc6bc3c0Ani6f8Gto3lfrEMwLaPkxOEXuh4SK5w"
69 | "0qWQdahu4LNqoqT7KI7uuwXiMMzw6Y7ySK3u37VJ8msDNI6f"
70 | "0nRHEfROfhK2Yf3FVGItOcNBQDUa4BeuAJgt",
71 | {0xCD, 0x6F, 0x3B, 0x5E, 0x08, 0xC3, 0x41, 0x62,
72 | 0xCB, 0xD5, 0x19, 0x0D, 0xA8, 0xCD, 0x45, 0xF7,
73 | 0x63, 0x7E, 0x15, 0x13, 0x8A, 0x39, 0x62, 0x90,
74 | 0x03, 0x68, 0x97, 0xB3, 0x18, 0x84, 0x26, 0xFE}
75 | },
76 | //5: 56 spaces
77 | {
78 | " ",
79 | {0xB6, 0x0C, 0x4C, 0x2D, 0x56, 0x5C, 0xD1, 0xF1,
80 | 0x0E, 0xEB, 0x0D, 0xEF, 0xFD, 0xD7, 0xB6, 0x5F,
81 | 0xDF, 0x9D, 0x4F, 0xD3, 0x96, 0x08, 0x68, 0xDA,
82 | 0x68, 0xE3, 0x53, 0x31, 0x59, 0xB7, 0x0B, 0xD8}
83 | }
84 | };
85 |
86 | //main function
87 | int main () {
88 | //runs through all the hard-coded pairs, then returns
89 | for (int i = 0; i < sizeof(pairs)/sizeof(pairs[0]); i++) {
90 | unsigned char out[32];
91 | if (lonesha256(out, pairs[i].in, strlen(pairs[i].in)))
92 | printf("TEST %d: ERROR\n", i);
93 | else if (memcmp(out, pairs[i].out, sizeof(out)))
94 | printf("TEST %d: FAILED\n", i);
95 | else
96 | printf("TEST %d: PASSED\n", i);
97 | }
98 | //return
99 | return 0;
100 | }
--------------------------------------------------------------------------------
/lonesha256.h:
--------------------------------------------------------------------------------
1 | /*
2 | lonesha256.h - Portable, endian-proof, single-file, single-function sha256 implementation, originally based on LibTomCrypt
3 |
4 | To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring
5 | rights to this software to the public domain worldwide. This software is distributed without any warranty.
6 | You should have received a copy of the CC0 Public Domain Dedication along with this software.
7 | If not, see .
8 | */
9 |
10 | /*
11 | lonesha256 supports the following three configurations:
12 | #define LONESHA256_EXTERN
13 | Default, should be used when using lonesha256 in multiple compilation units within the same project.
14 | #define LONESHA256_IMPLEMENTATION
15 | Must be defined in exactly one source file within a project for lonesha256 to be found by the linker.
16 | #define LONESHA256_STATIC
17 | Defines the lonesha256() function as static, useful if lonesha256 is only used in a single compilation unit.
18 |
19 | lonesha256 function:
20 | (static|extern) int lonesha256 (unsigned char out[32], const unsigned char* in, size_t len)
21 | writes the sha256 hash of the first "len" bytes in buffer "in" to buffer "out"
22 | returns 0 on success, may return non-zero in future versions to indicate error
23 | */
24 |
25 | //header section
26 | #ifndef LONESHA256_H
27 | #define LONESHA256_H
28 |
29 | //process configuration
30 | #ifdef LONESHA256_STATIC
31 | #define LONESHA256_IMPLEMENTATION
32 | #define LSHA256DEF static
33 | #else //LONESHA256_EXTERN
34 | #define LSHA256DEF extern
35 | #endif
36 |
37 | //includes
38 | #include //size_t
39 |
40 | //lonesha256 declaration
41 | LSHA256DEF int lonesha256(unsigned char[32], const unsigned char*, size_t);
42 |
43 | #endif //LONESHA256_H
44 |
45 | //implementation section
46 | #ifdef LONESHA256_IMPLEMENTATION
47 | #undef LONESHA256_IMPLEMENTATION
48 |
49 | //macros
50 | #define S(x, n) (((((uint32_t)(x)&0xFFFFFFFFUL)>>(uint32_t)((n)&31))|((uint32_t)(x)<<(uint32_t)((32-((n)&31))&31)))&0xFFFFFFFFUL)
51 | #define R(x, n) (((x)&0xFFFFFFFFUL)>>(n))
52 | #define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3))
53 | #define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10))
54 | #define RND(a,b,c,d,e,f,g,h,i) \
55 | t0 = h + (S(e, 6) ^ S(e, 11) ^ S(e, 25)) + (g ^ (e & (f ^ g))) + K[i] + W[i]; \
56 | t1 = (S(a, 2) ^ S(a, 13) ^ S(a, 22)) + (((a | b) & c) | (a & b)); \
57 | d += t0; \
58 | h = t0 + t1;
59 | #define STORE32H(x, y) \
60 | (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \
61 | (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255);
62 | #define LOAD32H(x, y) \
63 | x = ((uint32_t)((y)[0]&255)<<24)|((uint32_t)((y)[1]&255)<<16)|((uint32_t)((y)[2]&255)<<8)|((uint32_t)((y)[3]&255));
64 | #define STORE64H(x, y) \
65 | (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \
66 | (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \
67 | (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \
68 | (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255);
69 | #define SHA256_COMPRESS(buff) \
70 | for (int i = 0; i < 8; i++) S[i] = sha256_state[i]; \
71 | for (int i = 0; i < 16; i++) LOAD32H(W[i], buff + (4*i)); \
72 | for (int i = 16; i < 64; i++) W[i] = Gamma1(W[i-2]) + W[i-7] + Gamma0(W[i-15]) + W[i-16]; \
73 | for (int i = 0; i < 64; i++) { \
74 | RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i); \
75 | t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4]; \
76 | S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t; \
77 | } \
78 | for (int i = 0; i < 8; i++) sha256_state[i] = sha256_state[i] + S[i];
79 |
80 | //includes
81 | #include //uint32_t, uint64_t
82 | #include //memcpy
83 |
84 | //lonesha256 function
85 | LSHA256DEF int lonesha256 (unsigned char out[32], const unsigned char* in, size_t len) {
86 | //writes the sha256 hash of the first "len" bytes in buffer "in" to buffer "out"
87 | //returns 0 on success, may return non-zero in future versions to indicate error
88 | const uint32_t K[64] = {
89 | 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
90 | 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
91 | 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
92 | 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
93 | 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
94 | 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
95 | 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
96 | 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
97 | 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
98 | 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
99 | 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
100 | 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
101 | 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
102 | 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
103 | 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
104 | 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
105 | };
106 | uint64_t sha256_length = 0;
107 | uint32_t sha256_state[8] = {
108 | 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL,
109 | 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL
110 | }, S[8], W[64], t0, t1, t;
111 | unsigned char sha256_buf[64];
112 | //process input in 64 byte chunks
113 | while (len >= 64) {
114 | SHA256_COMPRESS(in);
115 | sha256_length += 64 * 8;
116 | in += 64;
117 | len -= 64;
118 | }
119 | //copy remaining bytes into sha256_buf
120 | memcpy(sha256_buf, in, len);
121 | //finish up (len now number of bytes in sha256_buf)
122 | sha256_length += len * 8;
123 | sha256_buf[len++] = 0x80;
124 | //pad then compress if length is above 56 bytes
125 | if (len > 56) {
126 | while (len < 64) sha256_buf[len++] = 0;
127 | SHA256_COMPRESS(sha256_buf);
128 | len = 0;
129 | }
130 | //pad up to 56 bytes
131 | while (len < 56) sha256_buf[len++] = 0;
132 | //store length and compress
133 | STORE64H(sha256_length, sha256_buf + 56);
134 | SHA256_COMPRESS(sha256_buf);
135 | //copy output
136 | for (int i = 0; i < 8; i++) {
137 | STORE32H(sha256_state[i], out + 4*i);
138 | }
139 | //return
140 | return 0;
141 | }
142 |
143 | #endif //LONESHA256_IMPLEMENTATION
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | CC0 1.0 Universal
2 |
3 | Statement of Purpose
4 |
5 | The laws of most jurisdictions throughout the world automatically confer
6 | exclusive Copyright and Related Rights (defined below) upon the creator and
7 | subsequent owner(s) (each and all, an "owner") of an original work of
8 | authorship and/or a database (each, a "Work").
9 |
10 | Certain owners wish to permanently relinquish those rights to a Work for the
11 | purpose of contributing to a commons of creative, cultural and scientific
12 | works ("Commons") that the public can reliably and without fear of later
13 | claims of infringement build upon, modify, incorporate in other works, reuse
14 | and redistribute as freely as possible in any form whatsoever and for any
15 | purposes, including without limitation commercial purposes. These owners may
16 | contribute to the Commons to promote the ideal of a free culture and the
17 | further production of creative, cultural and scientific works, or to gain
18 | reputation or greater distribution for their Work in part through the use and
19 | efforts of others.
20 |
21 | For these and/or other purposes and motivations, and without any expectation
22 | of additional consideration or compensation, the person associating CC0 with a
23 | Work (the "Affirmer"), to the extent that he or she is an owner of Copyright
24 | and Related Rights in the Work, voluntarily elects to apply CC0 to the Work
25 | and publicly distribute the Work under its terms, with knowledge of his or her
26 | Copyright and Related Rights in the Work and the meaning and intended legal
27 | effect of CC0 on those rights.
28 |
29 | 1. Copyright and Related Rights. A Work made available under CC0 may be
30 | protected by copyright and related or neighboring rights ("Copyright and
31 | Related Rights"). Copyright and Related Rights include, but are not limited
32 | to, the following:
33 |
34 | i. the right to reproduce, adapt, distribute, perform, display, communicate,
35 | and translate a Work;
36 |
37 | ii. moral rights retained by the original author(s) and/or performer(s);
38 |
39 | iii. publicity and privacy rights pertaining to a person's image or likeness
40 | depicted in a Work;
41 |
42 | iv. rights protecting against unfair competition in regards to a Work,
43 | subject to the limitations in paragraph 4(a), below;
44 |
45 | v. rights protecting the extraction, dissemination, use and reuse of data in
46 | a Work;
47 |
48 | vi. database rights (such as those arising under Directive 96/9/EC of the
49 | European Parliament and of the Council of 11 March 1996 on the legal
50 | protection of databases, and under any national implementation thereof,
51 | including any amended or successor version of such directive); and
52 |
53 | vii. other similar, equivalent or corresponding rights throughout the world
54 | based on applicable law or treaty, and any national implementations thereof.
55 |
56 | 2. Waiver. To the greatest extent permitted by, but not in contravention of,
57 | applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and
58 | unconditionally waives, abandons, and surrenders all of Affirmer's Copyright
59 | and Related Rights and associated claims and causes of action, whether now
60 | known or unknown (including existing as well as future claims and causes of
61 | action), in the Work (i) in all territories worldwide, (ii) for the maximum
62 | duration provided by applicable law or treaty (including future time
63 | extensions), (iii) in any current or future medium and for any number of
64 | copies, and (iv) for any purpose whatsoever, including without limitation
65 | commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes
66 | the Waiver for the benefit of each member of the public at large and to the
67 | detriment of Affirmer's heirs and successors, fully intending that such Waiver
68 | shall not be subject to revocation, rescission, cancellation, termination, or
69 | any other legal or equitable action to disrupt the quiet enjoyment of the Work
70 | by the public as contemplated by Affirmer's express Statement of Purpose.
71 |
72 | 3. Public License Fallback. Should any part of the Waiver for any reason be
73 | judged legally invalid or ineffective under applicable law, then the Waiver
74 | shall be preserved to the maximum extent permitted taking into account
75 | Affirmer's express Statement of Purpose. In addition, to the extent the Waiver
76 | is so judged Affirmer hereby grants to each affected person a royalty-free,
77 | non transferable, non sublicensable, non exclusive, irrevocable and
78 | unconditional license to exercise Affirmer's Copyright and Related Rights in
79 | the Work (i) in all territories worldwide, (ii) for the maximum duration
80 | provided by applicable law or treaty (including future time extensions), (iii)
81 | in any current or future medium and for any number of copies, and (iv) for any
82 | purpose whatsoever, including without limitation commercial, advertising or
83 | promotional purposes (the "License"). The License shall be deemed effective as
84 | of the date CC0 was applied by Affirmer to the Work. Should any part of the
85 | License for any reason be judged legally invalid or ineffective under
86 | applicable law, such partial invalidity or ineffectiveness shall not
87 | invalidate the remainder of the License, and in such case Affirmer hereby
88 | affirms that he or she will not (i) exercise any of his or her remaining
89 | Copyright and Related Rights in the Work or (ii) assert any associated claims
90 | and causes of action with respect to the Work, in either case contrary to
91 | Affirmer's express Statement of Purpose.
92 |
93 | 4. Limitations and Disclaimers.
94 |
95 | a. No trademark or patent rights held by Affirmer are waived, abandoned,
96 | surrendered, licensed or otherwise affected by this document.
97 |
98 | b. Affirmer offers the Work as-is and makes no representations or warranties
99 | of any kind concerning the Work, express, implied, statutory or otherwise,
100 | including without limitation warranties of title, merchantability, fitness
101 | for a particular purpose, non infringement, or the absence of latent or
102 | other defects, accuracy, or the present or absence of errors, whether or not
103 | discoverable, all to the greatest extent permissible under applicable law.
104 |
105 | c. Affirmer disclaims responsibility for clearing rights of other persons
106 | that may apply to the Work or any use thereof, including without limitation
107 | any person's Copyright and Related Rights in the Work. Further, Affirmer
108 | disclaims responsibility for obtaining any necessary consents, permissions
109 | or other rights required for any use of the Work.
110 |
111 | d. Affirmer understands and acknowledges that Creative Commons is not a
112 | party to this document and has no duty or obligation with respect to this
113 | CC0 or use of the Work.
114 |
115 | For more information, please see
116 |
--------------------------------------------------------------------------------