comparison sha512.c @ 20:b939f2d4431e libtomcrypt

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