comparison src/hashes/sha2/sha512.c @ 191:1c15b283127b libtomcrypt-orig

Import of libtomcrypt 1.02 with manual path rename rearrangement etc
author Matt Johnston <matt@ucc.asn.au>
date Fri, 06 May 2005 13:23:02 +0000
parents
children 39d5d58461d6
comparison
equal deleted inserted replaced
143:5d99163f7e32 191:1c15b283127b
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
2 *
3 * LibTomCrypt is a library that provides various cryptographic
4 * algorithms in a highly modular and flexible manner.
5 *
6 * The library is free for all purposes without any express
7 * guarantee it works.
8 *
9 * Tom St Denis, [email protected], http://libtomcrypt.org
10 */
11 #include "tomcrypt.h"
12
13 /**
14 @param sha512.c
15 SHA512 by Tom St Denis
16 */
17
18 #ifdef SHA512
19
20 const struct ltc_hash_descriptor sha512_desc =
21 {
22 "sha512",
23 5,
24 64,
25 128,
26
27 /* DER identifier */
28 { 0x30, 0x51, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86,
29 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
30 0x00, 0x04, 0x40 },
31 19,
32
33 &sha512_init,
34 &sha512_process,
35 &sha512_done,
36 &sha512_test
37 };
38
39 /* the K array */
40 static const ulong64 K[80] = {
41 CONST64(0x428a2f98d728ae22), CONST64(0x7137449123ef65cd),
42 CONST64(0xb5c0fbcfec4d3b2f), CONST64(0xe9b5dba58189dbbc),
43 CONST64(0x3956c25bf348b538), CONST64(0x59f111f1b605d019),
44 CONST64(0x923f82a4af194f9b), CONST64(0xab1c5ed5da6d8118),
45 CONST64(0xd807aa98a3030242), CONST64(0x12835b0145706fbe),
46 CONST64(0x243185be4ee4b28c), CONST64(0x550c7dc3d5ffb4e2),
47 CONST64(0x72be5d74f27b896f), CONST64(0x80deb1fe3b1696b1),
48 CONST64(0x9bdc06a725c71235), CONST64(0xc19bf174cf692694),
49 CONST64(0xe49b69c19ef14ad2), CONST64(0xefbe4786384f25e3),
50 CONST64(0x0fc19dc68b8cd5b5), CONST64(0x240ca1cc77ac9c65),
51 CONST64(0x2de92c6f592b0275), CONST64(0x4a7484aa6ea6e483),
52 CONST64(0x5cb0a9dcbd41fbd4), CONST64(0x76f988da831153b5),
53 CONST64(0x983e5152ee66dfab), CONST64(0xa831c66d2db43210),
54 CONST64(0xb00327c898fb213f), CONST64(0xbf597fc7beef0ee4),
55 CONST64(0xc6e00bf33da88fc2), CONST64(0xd5a79147930aa725),
56 CONST64(0x06ca6351e003826f), CONST64(0x142929670a0e6e70),
57 CONST64(0x27b70a8546d22ffc), CONST64(0x2e1b21385c26c926),
58 CONST64(0x4d2c6dfc5ac42aed), CONST64(0x53380d139d95b3df),
59 CONST64(0x650a73548baf63de), CONST64(0x766a0abb3c77b2a8),
60 CONST64(0x81c2c92e47edaee6), CONST64(0x92722c851482353b),
61 CONST64(0xa2bfe8a14cf10364), CONST64(0xa81a664bbc423001),
62 CONST64(0xc24b8b70d0f89791), CONST64(0xc76c51a30654be30),
63 CONST64(0xd192e819d6ef5218), CONST64(0xd69906245565a910),
64 CONST64(0xf40e35855771202a), CONST64(0x106aa07032bbd1b8),
65 CONST64(0x19a4c116b8d2d0c8), CONST64(0x1e376c085141ab53),
66 CONST64(0x2748774cdf8eeb99), CONST64(0x34b0bcb5e19b48a8),
67 CONST64(0x391c0cb3c5c95a63), CONST64(0x4ed8aa4ae3418acb),
68 CONST64(0x5b9cca4f7763e373), CONST64(0x682e6ff3d6b2b8a3),
69 CONST64(0x748f82ee5defb2fc), CONST64(0x78a5636f43172f60),
70 CONST64(0x84c87814a1f0ab72), CONST64(0x8cc702081a6439ec),
71 CONST64(0x90befffa23631e28), CONST64(0xa4506cebde82bde9),
72 CONST64(0xbef9a3f7b2c67915), CONST64(0xc67178f2e372532b),
73 CONST64(0xca273eceea26619c), CONST64(0xd186b8c721c0c207),
74 CONST64(0xeada7dd6cde0eb1e), CONST64(0xf57d4f7fee6ed178),
75 CONST64(0x06f067aa72176fba), CONST64(0x0a637dc5a2c898a6),
76 CONST64(0x113f9804bef90dae), CONST64(0x1b710b35131c471b),
77 CONST64(0x28db77f523047d84), CONST64(0x32caab7b40c72493),
78 CONST64(0x3c9ebe0a15c9bebc), CONST64(0x431d67c49c100d4c),
79 CONST64(0x4cc5d4becb3e42b6), CONST64(0x597f299cfc657e2a),
80 CONST64(0x5fcb6fab3ad6faec), CONST64(0x6c44198c4a475817)
81 };
82
83 /* Various logical functions */
84 #define Ch(x,y,z) (z ^ (x & (y ^ z)))
85 #define Maj(x,y,z) (((x | y) & z) | (x & y))
86 #define S(x, n) ROR64c(x, n)
87 #define R(x, n) (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)n))
88 #define Sigma0(x) (S(x, 28) ^ S(x, 34) ^ S(x, 39))
89 #define Sigma1(x) (S(x, 14) ^ S(x, 18) ^ S(x, 41))
90 #define Gamma0(x) (S(x, 1) ^ S(x, 8) ^ R(x, 7))
91 #define Gamma1(x) (S(x, 19) ^ S(x, 61) ^ R(x, 6))
92
93 /* compress 1024-bits */
94 #ifdef LTC_CLEAN_STACK
95 static int _sha512_compress(hash_state * md, unsigned char *buf)
96 #else
97 static int sha512_compress(hash_state * md, unsigned char *buf)
98 #endif
99 {
100 ulong64 S[8], W[80], t0, t1;
101 int i;
102
103 /* copy state into S */
104 for (i = 0; i < 8; i++) {
105 S[i] = md->sha512.state[i];
106 }
107
108 /* copy the state into 1024-bits into W[0..15] */
109 for (i = 0; i < 16; i++) {
110 LOAD64H(W[i], buf + (8*i));
111 }
112
113 /* fill W[16..79] */
114 for (i = 16; i < 80; i++) {
115 W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
116 }
117
118 /* Compress */
119 #ifdef LTC_SMALL_CODE
120 for (i = 0; i < 80; i++) {
121 t0 = S[7] + Sigma1(S[4]) + Ch(S[4], S[5], S[6]) + K[i] + W[i];
122 t1 = Sigma0(S[0]) + Maj(S[0], S[1], S[2]);
123 S[7] = S[6];
124 S[6] = S[5];
125 S[5] = S[4];
126 S[4] = S[3] + t0;
127 S[3] = S[2];
128 S[2] = S[1];
129 S[1] = S[0];
130 S[0] = t0 + t1;
131 }
132 #else
133 #define RND(a,b,c,d,e,f,g,h,i) \
134 t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
135 t1 = Sigma0(a) + Maj(a, b, c); \
136 d += t0; \
137 h = t0 + t1;
138
139 for (i = 0; i < 80; i += 8) {
140 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0);
141 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1);
142 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2);
143 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3);
144 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4);
145 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5);
146 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6);
147 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7);
148 }
149 #endif
150
151
152 /* feedback */
153 for (i = 0; i < 8; i++) {
154 md->sha512.state[i] = md->sha512.state[i] + S[i];
155 }
156
157 return CRYPT_OK;
158 }
159
160 /* compress 1024-bits */
161 #ifdef LTC_CLEAN_STACK
162 static int sha512_compress(hash_state * md, unsigned char *buf)
163 {
164 int err;
165 err = _sha512_compress(md, buf);
166 burn_stack(sizeof(ulong64) * 90 + sizeof(int));
167 return err;
168 }
169 #endif
170
171 /**
172 Initialize the hash state
173 @param md The hash state you wish to initialize
174 @return CRYPT_OK if successful
175 */
176 int sha512_init(hash_state * md)
177 {
178 LTC_ARGCHK(md != NULL);
179 md->sha512.curlen = 0;
180 md->sha512.length = 0;
181 md->sha512.state[0] = CONST64(0x6a09e667f3bcc908);
182 md->sha512.state[1] = CONST64(0xbb67ae8584caa73b);
183 md->sha512.state[2] = CONST64(0x3c6ef372fe94f82b);
184 md->sha512.state[3] = CONST64(0xa54ff53a5f1d36f1);
185 md->sha512.state[4] = CONST64(0x510e527fade682d1);
186 md->sha512.state[5] = CONST64(0x9b05688c2b3e6c1f);
187 md->sha512.state[6] = CONST64(0x1f83d9abfb41bd6b);
188 md->sha512.state[7] = CONST64(0x5be0cd19137e2179);
189 return CRYPT_OK;
190 }
191
192 /**
193 Process a block of memory though the hash
194 @param md The hash state
195 @param in The data to hash
196 @param inlen The length of the data (octets)
197 @return CRYPT_OK if successful
198 */
199 HASH_PROCESS(sha512_process, sha512_compress, sha512, 128)
200
201 /**
202 Terminate the hash to get the digest
203 @param md The hash state
204 @param out [out] The destination of the hash (64 bytes)
205 @return CRYPT_OK if successful
206 */
207 int sha512_done(hash_state * md, unsigned char *out)
208 {
209 int i;
210
211 LTC_ARGCHK(md != NULL);
212 LTC_ARGCHK(out != NULL);
213
214 if (md->sha512.curlen >= sizeof(md->sha512.buf)) {
215 return CRYPT_INVALID_ARG;
216 }
217
218 /* increase the length of the message */
219 md->sha512.length += md->sha512.curlen * CONST64(8);
220
221 /* append the '1' bit */
222 md->sha512.buf[md->sha512.curlen++] = (unsigned char)0x80;
223
224 /* if the length is currently above 112 bytes we append zeros
225 * then compress. Then we can fall back to padding zeros and length
226 * encoding like normal.
227 */
228 if (md->sha512.curlen > 112) {
229 while (md->sha512.curlen < 128) {
230 md->sha512.buf[md->sha512.curlen++] = (unsigned char)0;
231 }
232 sha512_compress(md, md->sha512.buf);
233 md->sha512.curlen = 0;
234 }
235
236 /* pad upto 120 bytes of zeroes
237 * note: that from 112 to 120 is the 64 MSB of the length. We assume that you won't hash
238 * > 2^64 bits of data... :-)
239 */
240 while (md->sha512.curlen < 120) {
241 md->sha512.buf[md->sha512.curlen++] = (unsigned char)0;
242 }
243
244 /* store length */
245 STORE64H(md->sha512.length, md->sha512.buf+120);
246 sha512_compress(md, md->sha512.buf);
247
248 /* copy output */
249 for (i = 0; i < 8; i++) {
250 STORE64H(md->sha512.state[i], out+(8*i));
251 }
252 #ifdef LTC_CLEAN_STACK
253 zeromem(md, sizeof(hash_state));
254 #endif
255 return CRYPT_OK;
256 }
257
258 /**
259 Self-test the hash
260 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
261 */
262 int sha512_test(void)
263 {
264 #ifndef LTC_TEST
265 return CRYPT_NOP;
266 #else
267 static const struct {
268 char *msg;
269 unsigned char hash[64];
270 } tests[] = {
271 { "abc",
272 { 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba,
273 0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31,
274 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
275 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a,
276 0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8,
277 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
278 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e,
279 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f }
280 },
281 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
282 { 0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda,
283 0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f,
284 0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1,
285 0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18,
286 0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4,
287 0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a,
288 0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54,
289 0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09 }
290 },
291 };
292
293 int i;
294 unsigned char tmp[64];
295 hash_state md;
296
297 for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
298 sha512_init(&md);
299 sha512_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
300 sha512_done(&md, tmp);
301 if (memcmp(tmp, tests[i].hash, 64) != 0) {
302 return CRYPT_FAIL_TESTVECTOR;
303 }
304 }
305 return CRYPT_OK;
306 #endif
307 }
308
309 #ifdef SHA384
310 #include "sha384.c"
311 #endif
312
313 #endif
314
315
316