comparison sha512.c @ 0:d7da3b1e1540 libtomcrypt

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