5 const struct _hash_descriptor sha512_desc =
18 static const ulong64 K[80] = {
19 CONST64(0x428a2f98d728ae22), CONST64(0x7137449123ef65cd),
20 CONST64(0xb5c0fbcfec4d3b2f), CONST64(0xe9b5dba58189dbbc),
21 CONST64(0x3956c25bf348b538), CONST64(0x59f111f1b605d019),
22 CONST64(0x923f82a4af194f9b), CONST64(0xab1c5ed5da6d8118),
23 CONST64(0xd807aa98a3030242), CONST64(0x12835b0145706fbe),
24 CONST64(0x243185be4ee4b28c), CONST64(0x550c7dc3d5ffb4e2),
25 CONST64(0x72be5d74f27b896f), CONST64(0x80deb1fe3b1696b1),
26 CONST64(0x9bdc06a725c71235), CONST64(0xc19bf174cf692694),
27 CONST64(0xe49b69c19ef14ad2), CONST64(0xefbe4786384f25e3),
28 CONST64(0x0fc19dc68b8cd5b5), CONST64(0x240ca1cc77ac9c65),
29 CONST64(0x2de92c6f592b0275), CONST64(0x4a7484aa6ea6e483),
30 CONST64(0x5cb0a9dcbd41fbd4), CONST64(0x76f988da831153b5),
31 CONST64(0x983e5152ee66dfab), CONST64(0xa831c66d2db43210),
32 CONST64(0xb00327c898fb213f), CONST64(0xbf597fc7beef0ee4),
33 CONST64(0xc6e00bf33da88fc2), CONST64(0xd5a79147930aa725),
34 CONST64(0x06ca6351e003826f), CONST64(0x142929670a0e6e70),
35 CONST64(0x27b70a8546d22ffc), CONST64(0x2e1b21385c26c926),
36 CONST64(0x4d2c6dfc5ac42aed), CONST64(0x53380d139d95b3df),
37 CONST64(0x650a73548baf63de), CONST64(0x766a0abb3c77b2a8),
38 CONST64(0x81c2c92e47edaee6), CONST64(0x92722c851482353b),
39 CONST64(0xa2bfe8a14cf10364), CONST64(0xa81a664bbc423001),
40 CONST64(0xc24b8b70d0f89791), CONST64(0xc76c51a30654be30),
41 CONST64(0xd192e819d6ef5218), CONST64(0xd69906245565a910),
42 CONST64(0xf40e35855771202a), CONST64(0x106aa07032bbd1b8),
43 CONST64(0x19a4c116b8d2d0c8), CONST64(0x1e376c085141ab53),
44 CONST64(0x2748774cdf8eeb99), CONST64(0x34b0bcb5e19b48a8),
45 CONST64(0x391c0cb3c5c95a63), CONST64(0x4ed8aa4ae3418acb),
46 CONST64(0x5b9cca4f7763e373), CONST64(0x682e6ff3d6b2b8a3),
47 CONST64(0x748f82ee5defb2fc), CONST64(0x78a5636f43172f60),
48 CONST64(0x84c87814a1f0ab72), CONST64(0x8cc702081a6439ec),
49 CONST64(0x90befffa23631e28), CONST64(0xa4506cebde82bde9),
50 CONST64(0xbef9a3f7b2c67915), CONST64(0xc67178f2e372532b),
51 CONST64(0xca273eceea26619c), CONST64(0xd186b8c721c0c207),
52 CONST64(0xeada7dd6cde0eb1e), CONST64(0xf57d4f7fee6ed178),
53 CONST64(0x06f067aa72176fba), CONST64(0x0a637dc5a2c898a6),
54 CONST64(0x113f9804bef90dae), CONST64(0x1b710b35131c471b),
55 CONST64(0x28db77f523047d84), CONST64(0x32caab7b40c72493),
56 CONST64(0x3c9ebe0a15c9bebc), CONST64(0x431d67c49c100d4c),
57 CONST64(0x4cc5d4becb3e42b6), CONST64(0x597f299cfc657e2a),
58 CONST64(0x5fcb6fab3ad6faec), CONST64(0x6c44198c4a475817)
61 /* Various logical functions */
62 #define Ch(x,y,z) (z ^ (x & (y ^ z)))
63 #define Maj(x,y,z) (((x | y) & z) | (x & y))
64 #define S(x, n) ROR64((x),(n))
65 #define R(x, n) (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)n))
66 #define Sigma0(x) (S(x, 28) ^ S(x, 34) ^ S(x, 39))
67 #define Sigma1(x) (S(x, 14) ^ S(x, 18) ^ S(x, 41))
68 #define Gamma0(x) (S(x, 1) ^ S(x, 8) ^ R(x, 7))
69 #define Gamma1(x) (S(x, 19) ^ S(x, 61) ^ R(x, 6))
71 /* compress 1024-bits */
73 static void _sha512_compress(hash_state * md)
75 static void sha512_compress(hash_state * md)
78 ulong64 S[8], W[80], t0, t1;
83 /* copy state into S */
84 for (i = 0; i < 8; i++)
85 S[i] = md->sha512.state[i];
87 /* copy the state into 1024-bits into W[0..15] */
88 for (i = 0; i < 16; i++) {
89 LOAD64H(W[i], md->sha512.buf + (8*i));
93 for (i = 16; i < 80; i++) {
94 W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
98 for (i = 0; i < 80; i++) {
99 t0 = S[7] + Sigma1(S[4]) + Ch(S[4], S[5], S[6]) + K[i] + W[i];
100 t1 = Sigma0(S[0]) + Maj(S[0], S[1], S[2]);
112 for (i = 0; i < 8; i++) {
113 md->sha512.state[i] = md->sha512.state[i] + S[i];
117 /* compress 1024-bits */
119 static void sha512_compress(hash_state * md)
121 _sha512_compress(md);
122 burn_stack(sizeof(ulong64) * 90 + sizeof(int));
126 /* init the sha512 state */
127 void sha512_init(hash_state * md)
131 md->sha512.curlen = 0;
132 md->sha512.length = 0;
133 md->sha512.state[0] = CONST64(0x6a09e667f3bcc908);
134 md->sha512.state[1] = CONST64(0xbb67ae8584caa73b);
135 md->sha512.state[2] = CONST64(0x3c6ef372fe94f82b);
136 md->sha512.state[3] = CONST64(0xa54ff53a5f1d36f1);
137 md->sha512.state[4] = CONST64(0x510e527fade682d1);
138 md->sha512.state[5] = CONST64(0x9b05688c2b3e6c1f);
139 md->sha512.state[6] = CONST64(0x1f83d9abfb41bd6b);
140 md->sha512.state[7] = CONST64(0x5be0cd19137e2179);
143 void sha512_process(hash_state * md, const unsigned char *buf, unsigned long len)
147 _ARGCHK(buf != NULL);
149 n = MIN(len, (128 - md->sha512.curlen));
150 memcpy(md->sha512.buf + md->sha512.curlen, buf, (size_t)n);
151 md->sha512.curlen += n;
155 /* is 128 bytes full? */
156 if (md->sha512.curlen == 128) {
158 md->sha512.length += 1024;
159 md->sha512.curlen = 0;
164 void sha512_done(hash_state * md, unsigned char *hash)
169 _ARGCHK(hash != NULL);
171 /* increase the length of the message */
172 md->sha512.length += md->sha512.curlen * CONST64(8);
174 /* append the '1' bit */
175 md->sha512.buf[md->sha512.curlen++] = (unsigned char)0x80;
177 /* if the length is currently above 112 bytes we append zeros
178 * then compress. Then we can fall back to padding zeros and length
179 * encoding like normal.
181 if (md->sha512.curlen > 112) {
182 while (md->sha512.curlen < 128) {
183 md->sha512.buf[md->sha512.curlen++] = (unsigned char)0;
186 md->sha512.curlen = 0;
189 /* pad upto 120 bytes of zeroes
190 * note: that from 112 to 120 is the 64 MSB of the length. We assume that you won't hash
191 * > 2^64 bits of data... :-)
193 while (md->sha512.curlen < 120) {
194 md->sha512.buf[md->sha512.curlen++] = (unsigned char)0;
198 STORE64H(md->sha512.length, md->sha512.buf+120);
202 for (i = 0; i < 8; i++) {
203 STORE64H(md->sha512.state[i], hash+(8*i));
206 zeromem(md, sizeof(hash_state));
210 int sha512_test(void)
215 static const struct {
217 unsigned char hash[64];
220 { 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba,
221 0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31,
222 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
223 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a,
224 0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8,
225 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
226 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e,
227 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f }
229 { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
230 { 0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda,
231 0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f,
232 0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1,
233 0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18,
234 0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4,
235 0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a,
236 0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54,
237 0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09 }
242 unsigned char tmp[64];
245 for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
247 sha512_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
248 sha512_done(&md, tmp);
249 if (memcmp(tmp, tests[i].hash, 64) != 0) {
250 return CRYPT_FAIL_TESTVECTOR;