admins.html: include current irc contact information
[girocco.git] / src / lt256.c
blob79039e997436f9b6a6e134b319cbfa406f0e64ae
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
3 * LibTomCrypt is a library that provides various cryptographic
4 * algorithms in a highly modular and flexible manner.
6 * The library is free for all purposes without any express
7 * guarantee it works.
9 * License: public domain -or- http://www.wtfpl.net/txt/copying/
12 /**
13 @file sha256.c
14 LTC_SHA256 by Tom St Denis
17 #include "lt256.h"
18 #include <stdlib.h>
19 #include <string.h>
21 #ifndef MIN
22 #define MIN(x, y) ( ((x)<(y))?(x):(y) )
23 #endif
25 #define CRYPT_OK 1
26 #define hash_state SHA256_CTX
27 #define sha256_init SHA256_Init
28 #define sha256_process SHA256_Update
29 #define sha256_done SHA256_Final
31 #define STORE32H(x, y) \
32 do { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \
33 (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); } while(0)
35 #define LOAD32H(x, y) \
36 do { x = ((uint32_t)((y)[0] & 255)<<24) | \
37 ((uint32_t)((y)[1] & 255)<<16) | \
38 ((uint32_t)((y)[2] & 255)<<8) | \
39 ((uint32_t)((y)[3] & 255)); } while(0)
41 #define STORE64H(x, y) \
42 do { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \
43 (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \
44 (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \
45 (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } while(0)
47 /* 32-bit Rotates */
48 #if defined(_MSC_VER)
49 #define LTC_ROx_BUILTIN
51 /* instrinsic rotate */
52 #include <stdlib.h>
53 #pragma intrinsic(_rotr,_rotl)
54 #define ROR(x,n) _rotr(x,n)
55 #define RORc(x,n) ROR(x,n)
57 #elif defined(LTC_HAVE_ROTATE_BUILTIN)
58 #define LTC_ROx_BUILTIN
60 #define ROR(x,n) __builtin_rotateright32(x,n)
61 #define RORc(x,n) ROR(x,n)
63 #elif !defined(__STRICT_ANSI__) && defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && !defined(INTEL_CC) && !defined(LTC_NO_ASM)
64 #define LTC_ROx_ASM
66 static inline uint32_t ROR(uint32_t word, int i)
68 asm ("rorl %%cl,%0"
69 :"=r" (word)
70 :"0" (word),"c" (i));
71 return word;
74 #ifndef LTC_NO_ROLC
76 #define RORc(word,i) ({ \
77 uint32_t __RORc_tmp = (word); \
78 __asm__ ("rorl %2, %0" : \
79 "=r" (__RORc_tmp) : \
80 "0" (__RORc_tmp), \
81 "I" (i)); \
82 __RORc_tmp; \
85 #else
87 #define RORc ROR
89 #endif
91 #elif !defined(__STRICT_ANSI__) && defined(LTC_PPC32)
92 #define LTC_ROx_ASM
94 static inline uint32_t ROR(uint32_t word, int i)
96 asm ("rotlw %0,%0,%2"
97 :"=r" (word)
98 :"0" (word),"r" (32-i));
99 return word;
102 #ifndef LTC_NO_ROLC
104 static inline uint32_t RORc(uint32_t word, const int i)
106 asm ("rotrwi %0,%0,%2"
107 :"=r" (word)
108 :"0" (word),"I" (i));
109 return word;
112 #else
114 #define RORc ROR
116 #endif
118 #else
120 /* rotates the hard way */
121 #define ROR(x, y) ( ((((uint32_t)(x)&0xFFFFFFFFUL)>>(uint32_t)((y)&31)) | ((uint32_t)(x)<<(uint32_t)((32-((y)&31))&31))) & 0xFFFFFFFFUL)
122 #define RORc(x, y) ( ((((uint32_t)(x)&0xFFFFFFFFUL)>>(uint32_t)((y)&31)) | ((uint32_t)(x)<<(uint32_t)((32-((y)&31))&31))) & 0xFFFFFFFFUL)
124 #endif
126 /* a simple macro for making hash "process" functions */
127 #define HASH_PROCESS(func_name, compress_name, block_size) \
128 int func_name(hash_state *md, const void *_in, size_t inlen) \
130 const unsigned char *in = (const unsigned char *)_in; \
131 size_t n; \
132 int err; \
133 if (!md || !in) return 0; \
134 if (md->curlen > sizeof(md->buf)) { \
135 return 0; \
137 if ((md->length + inlen) < md->length) { \
138 return 0; \
140 while (inlen > 0) { \
141 if (md->curlen == 0 && inlen >= block_size) { \
142 if ((err = compress_name(md, in)) != CRYPT_OK) { \
143 return err; \
145 md->length += block_size * 8; \
146 in += block_size; \
147 inlen -= block_size; \
148 } else { \
149 n = MIN(inlen, (block_size - md->curlen)); \
150 memcpy(md->buf + md->curlen, in, (size_t)n); \
151 md->curlen += n; \
152 in += n; \
153 inlen -= n; \
154 if (md->curlen == block_size) { \
155 if ((err = compress_name(md, md->buf)) != CRYPT_OK) { \
156 return err; \
158 md->length += 8*block_size; \
159 md->curlen = 0; \
163 return CRYPT_OK; \
166 #ifdef LTC_SMALL_CODE
167 /* the K array */
168 static const uint32_t K[64] = {
169 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
170 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
171 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
172 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
173 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
174 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
175 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
176 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
177 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
178 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
179 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
180 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
181 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
183 #endif
185 /* Various logical functions */
186 #define Ch(x,y,z) (z ^ (x & (y ^ z)))
187 #define Maj(x,y,z) (((x | y) & z) | (x & y))
188 #define S(x, n) RORc((x),(n))
189 #define R(x, n) (((x)&0xFFFFFFFFUL)>>(n))
190 #define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22))
191 #define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25))
192 #define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3))
193 #define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10))
195 /* compress 512-bits */
196 static int sha256_compress(hash_state *md, const unsigned char *buf)
198 uint32_t S[8], W[64], t0, t1;
199 #ifdef LTC_SMALL_CODE
200 uint32_t t;
201 #endif
202 int i;
204 /* copy state into S */
205 for (i = 0; i < 8; i++) {
206 S[i] = md->state[i];
209 /* copy the state into 512-bits into W[0..15] */
210 for (i = 0; i < 16; i++) {
211 LOAD32H(W[i], buf + (4*i));
214 /* fill W[16..63] */
215 for (i = 16; i < 64; i++) {
216 W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
219 /* Compress */
220 #ifdef LTC_SMALL_CODE
221 #define RND(a,b,c,d,e,f,g,h,i) \
222 t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
223 t1 = Sigma0(a) + Maj(a, b, c); \
224 d += t0; \
225 h = t0 + t1;
227 for (i = 0; i < 64; ++i) {
228 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i);
229 t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4];
230 S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t;
232 #else
233 #define RND(a,b,c,d,e,f,g,h,i,ki) \
234 t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \
235 t1 = Sigma0(a) + Maj(a, b, c); \
236 d += t0; \
237 h = t0 + t1;
239 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98);
240 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x71374491);
241 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcf);
242 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba5);
243 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25b);
244 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1);
245 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4);
246 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5);
247 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98);
248 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b01);
249 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be);
250 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3);
251 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74);
252 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe);
253 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a7);
254 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174);
255 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c1);
256 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786);
257 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc6);
258 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc);
259 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f);
260 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa);
261 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dc);
262 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da);
263 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152);
264 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d);
265 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c8);
266 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7);
267 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf3);
268 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147);
269 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351);
270 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x14292967);
271 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a85);
272 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b2138);
273 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc);
274 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d13);
275 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a7354);
276 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb);
277 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e);
278 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c85);
279 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a1);
280 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664b);
281 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70);
282 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a3);
283 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819);
284 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd6990624);
285 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e3585);
286 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa070);
287 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116);
288 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c08);
289 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774c);
290 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5);
291 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3);
292 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4a);
293 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f);
294 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3);
295 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee);
296 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f);
297 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814);
298 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc70208);
299 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa);
300 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506ceb);
301 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7);
302 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2);
304 #undef RND
306 #endif
308 /* feedback */
309 for (i = 0; i < 8; i++) {
310 md->state[i] = md->state[i] + S[i];
312 return CRYPT_OK;
316 Initialize the hash state
317 @param md The hash state you wish to initialize
318 @return CRYPT_OK if successful
320 int sha256_init(hash_state *md)
322 if (!md) return 0;
324 md->curlen = 0;
325 md->length = 0;
326 md->state[0] = 0x6A09E667UL;
327 md->state[1] = 0xBB67AE85UL;
328 md->state[2] = 0x3C6EF372UL;
329 md->state[3] = 0xA54FF53AUL;
330 md->state[4] = 0x510E527FUL;
331 md->state[5] = 0x9B05688CUL;
332 md->state[6] = 0x1F83D9ABUL;
333 md->state[7] = 0x5BE0CD19UL;
334 return CRYPT_OK;
338 Process a block of memory though the hash
339 @param md The hash state
340 @param in The data to hash
341 @param inlen The length of the data (octets)
342 @return CRYPT_OK if successful
344 HASH_PROCESS(sha256_process, sha256_compress, 64)
347 Terminate the hash to get the digest
348 @param md The hash state
349 @param out [out] The destination of the hash (32 bytes)
350 @return CRYPT_OK if successful
352 int sha256_done(unsigned char *out, hash_state *md)
354 int i;
356 if (!md || !out) return 0;
358 if (md->curlen >= sizeof(md->buf)) {
359 return 0;
363 /* increase the length of the message */
364 md->length += md->curlen * 8;
366 /* append the '1' bit */
367 md->buf[md->curlen++] = (unsigned char)0x80;
369 /* if the length is currently above 56 bytes we append zeros
370 * then compress. Then we can fall back to padding zeros and length
371 * encoding like normal.
373 if (md->curlen > 56) {
374 while (md->curlen < 64) {
375 md->buf[md->curlen++] = (unsigned char)0;
377 sha256_compress(md, md->buf);
378 md->curlen = 0;
381 /* pad upto 56 bytes of zeroes */
382 while (md->curlen < 56) {
383 md->buf[md->curlen++] = (unsigned char)0;
386 /* store length */
387 STORE64H(md->length, md->buf+56);
388 sha256_compress(md, md->buf);
390 /* copy output */
391 for (i = 0; i < 8; i++) {
392 STORE32H(md->state[i], out+(4*i));
394 return CRYPT_OK;
397 unsigned char *SHA256(const void *data, size_t len, unsigned char *md)
399 SHA256_CTX c;
401 if (!SHA256_Init(&c)) return NULL;
402 if (!SHA256_Update(&c, data, len)) return NULL;
403 if (!SHA256_Final(md, &c)) return NULL;
404 return md;