]>
git.ipfire.org Git - thirdparty/bird.git/blob - lib/sha512.c
2 * BIRD Library -- SHA-512 and SHA-384 Hash Functions
4 * (c) 2015 CZ.NIC z.s.p.o.
6 * Based on the code from libgcrypt-1.6.0, which is
7 * (c) 2003, 2006, 2008, 2009 Free Software Foundation, Inc.
9 * Can be freely distributed and used under the terms of the GNU GPL.
12 #include "lib/sha512.h"
13 #include "lib/unaligned.h"
16 // #define SHA512_UNROLLED
19 sha512_init(struct hash_context
*CTX
)
21 struct sha512_context
*ctx
= (void *) CTX
;
23 ctx
->h0
= U64(0x6a09e667f3bcc908);
24 ctx
->h1
= U64(0xbb67ae8584caa73b);
25 ctx
->h2
= U64(0x3c6ef372fe94f82b);
26 ctx
->h3
= U64(0xa54ff53a5f1d36f1);
27 ctx
->h4
= U64(0x510e527fade682d1);
28 ctx
->h5
= U64(0x9b05688c2b3e6c1f);
29 ctx
->h6
= U64(0x1f83d9abfb41bd6b);
30 ctx
->h7
= U64(0x5be0cd19137e2179);
37 sha384_init(struct hash_context
*CTX
)
39 struct sha384_context
*ctx
= (void *) CTX
;
41 ctx
->h0
= U64(0xcbbb9d5dc1059ed8);
42 ctx
->h1
= U64(0x629a292a367cd507);
43 ctx
->h2
= U64(0x9159015a3070dd17);
44 ctx
->h3
= U64(0x152fecd8f70e5939);
45 ctx
->h4
= U64(0x67332667ffc00b31);
46 ctx
->h5
= U64(0x8eb44a8768581511);
47 ctx
->h6
= U64(0xdb0c2e0d64f98fa7);
48 ctx
->h7
= U64(0x47b5481dbefa4fa4);
57 return ((x
>> n
) | (x
<< (64 - n
)));
61 Ch(u64 x
, u64 y
, u64 z
)
63 return ((x
& y
) ^ ( ~x
& z
));
67 Maj(u64 x
, u64 y
, u64 z
)
69 return ((x
& y
) ^ (x
& z
) ^ (y
& z
));
75 return (ROTR(x
, 28) ^ ROTR(x
, 34) ^ ROTR(x
, 39));
81 return (ROTR(x
, 14) ^ ROTR(x
, 18) ^ ROTR(x
, 41));
84 static const u64 k
[] =
86 U64(0x428a2f98d728ae22), U64(0x7137449123ef65cd),
87 U64(0xb5c0fbcfec4d3b2f), U64(0xe9b5dba58189dbbc),
88 U64(0x3956c25bf348b538), U64(0x59f111f1b605d019),
89 U64(0x923f82a4af194f9b), U64(0xab1c5ed5da6d8118),
90 U64(0xd807aa98a3030242), U64(0x12835b0145706fbe),
91 U64(0x243185be4ee4b28c), U64(0x550c7dc3d5ffb4e2),
92 U64(0x72be5d74f27b896f), U64(0x80deb1fe3b1696b1),
93 U64(0x9bdc06a725c71235), U64(0xc19bf174cf692694),
94 U64(0xe49b69c19ef14ad2), U64(0xefbe4786384f25e3),
95 U64(0x0fc19dc68b8cd5b5), U64(0x240ca1cc77ac9c65),
96 U64(0x2de92c6f592b0275), U64(0x4a7484aa6ea6e483),
97 U64(0x5cb0a9dcbd41fbd4), U64(0x76f988da831153b5),
98 U64(0x983e5152ee66dfab), U64(0xa831c66d2db43210),
99 U64(0xb00327c898fb213f), U64(0xbf597fc7beef0ee4),
100 U64(0xc6e00bf33da88fc2), U64(0xd5a79147930aa725),
101 U64(0x06ca6351e003826f), U64(0x142929670a0e6e70),
102 U64(0x27b70a8546d22ffc), U64(0x2e1b21385c26c926),
103 U64(0x4d2c6dfc5ac42aed), U64(0x53380d139d95b3df),
104 U64(0x650a73548baf63de), U64(0x766a0abb3c77b2a8),
105 U64(0x81c2c92e47edaee6), U64(0x92722c851482353b),
106 U64(0xa2bfe8a14cf10364), U64(0xa81a664bbc423001),
107 U64(0xc24b8b70d0f89791), U64(0xc76c51a30654be30),
108 U64(0xd192e819d6ef5218), U64(0xd69906245565a910),
109 U64(0xf40e35855771202a), U64(0x106aa07032bbd1b8),
110 U64(0x19a4c116b8d2d0c8), U64(0x1e376c085141ab53),
111 U64(0x2748774cdf8eeb99), U64(0x34b0bcb5e19b48a8),
112 U64(0x391c0cb3c5c95a63), U64(0x4ed8aa4ae3418acb),
113 U64(0x5b9cca4f7763e373), U64(0x682e6ff3d6b2b8a3),
114 U64(0x748f82ee5defb2fc), U64(0x78a5636f43172f60),
115 U64(0x84c87814a1f0ab72), U64(0x8cc702081a6439ec),
116 U64(0x90befffa23631e28), U64(0xa4506cebde82bde9),
117 U64(0xbef9a3f7b2c67915), U64(0xc67178f2e372532b),
118 U64(0xca273eceea26619c), U64(0xd186b8c721c0c207),
119 U64(0xeada7dd6cde0eb1e), U64(0xf57d4f7fee6ed178),
120 U64(0x06f067aa72176fba), U64(0x0a637dc5a2c898a6),
121 U64(0x113f9804bef90dae), U64(0x1b710b35131c471b),
122 U64(0x28db77f523047d84), U64(0x32caab7b40c72493),
123 U64(0x3c9ebe0a15c9bebc), U64(0x431d67c49c100d4c),
124 U64(0x4cc5d4becb3e42b6), U64(0x597f299cfc657e2a),
125 U64(0x5fcb6fab3ad6faec), U64(0x6c44198c4a475817)
129 * Transform the message W which consists of 16 64-bit-words
132 sha512_transform(struct sha512_context
*ctx
, const byte
*data
)
134 u64 a
, b
, c
, d
, e
, f
, g
, h
;
138 /* get values from the chaining vars */
148 for (t
= 0; t
< 16; t
++)
149 w
[t
] = get_u64(data
+ t
* 8);
151 #define S0(x) (ROTR((x),1) ^ ROTR((x),8) ^ ((x)>>7))
152 #define S1(x) (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6))
154 for (t
= 0; t
< 80 - 16; )
158 /* Performance on a AMD Athlon(tm) Dual Core Processor 4050e
159 with gcc 4.3.3 using gcry_md_hash_buffer of each 10000 bytes
160 initialized to 0,1,2,3...255,0,... and 1000 iterations:
162 Not unrolled with macros: 440ms
163 Unrolled with macros: 350ms
164 Unrolled with inline: 330ms
166 #ifndef SHA512_UNROLLED
167 t1
= h
+ sum1(e
) + Ch(e
, f
, g
) + k
[t
] + w
[t
%16];
168 w
[t
%16] += S1(w
[(t
- 2)%16]) + w
[(t
- 7)%16] + S0(w
[(t
- 15)%16]);
169 t2
= sum0(a
) + Maj(a
, b
, c
);
180 t1
= h
+ sum1(e
) + Ch(e
, f
, g
) + k
[t
] + w
[0];
181 w
[0] += S1(w
[14]) + w
[9] + S0(w
[1]);
182 t2
= sum0(a
) + Maj(a
, b
, c
);
186 t1
= g
+ sum1(d
) + Ch(d
, e
, f
) + k
[t
+1] + w
[1];
187 w
[1] += S1(w
[15]) + w
[10] + S0(w
[2]);
188 t2
= sum0(h
) + Maj(h
, a
, b
);
192 t1
= f
+ sum1(c
) + Ch(c
, d
, e
) + k
[t
+2] + w
[2];
193 w
[2] += S1(w
[0]) + w
[11] + S0(w
[3]);
194 t2
= sum0(g
) + Maj(g
, h
, a
);
198 t1
= e
+ sum1(b
) + Ch(b
, c
, d
) + k
[t
+3] + w
[3];
199 w
[3] += S1(w
[1]) + w
[12] + S0(w
[4]);
200 t2
= sum0(f
) + Maj(f
, g
, h
);
204 t1
= d
+ sum1(a
) + Ch(a
, b
, c
) + k
[t
+4] + w
[4];
205 w
[4] += S1(w
[2]) + w
[13] + S0(w
[5]);
206 t2
= sum0(e
) + Maj(e
, f
, g
);
210 t1
= c
+ sum1(h
) + Ch(h
, a
, b
) + k
[t
+5] + w
[5];
211 w
[5] += S1(w
[3]) + w
[14] + S0(w
[6]);
212 t2
= sum0(d
) + Maj(d
, e
, f
);
216 t1
= b
+ sum1(g
) + Ch(g
, h
, a
) + k
[t
+6] + w
[6];
217 w
[6] += S1(w
[4]) + w
[15] + S0(w
[7]);
218 t2
= sum0(c
) + Maj(c
, d
, e
);
222 t1
= a
+ sum1(f
) + Ch(f
, g
, h
) + k
[t
+7] + w
[7];
223 w
[7] += S1(w
[5]) + w
[0] + S0(w
[8]);
224 t2
= sum0(b
) + Maj(b
, c
, d
);
228 t1
= h
+ sum1(e
) + Ch(e
, f
, g
) + k
[t
+8] + w
[8];
229 w
[8] += S1(w
[6]) + w
[1] + S0(w
[9]);
230 t2
= sum0(a
) + Maj(a
, b
, c
);
234 t1
= g
+ sum1(d
) + Ch(d
, e
, f
) + k
[t
+9] + w
[9];
235 w
[9] += S1(w
[7]) + w
[2] + S0(w
[10]);
236 t2
= sum0(h
) + Maj(h
, a
, b
);
240 t1
= f
+ sum1(c
) + Ch(c
, d
, e
) + k
[t
+10] + w
[10];
241 w
[10] += S1(w
[8]) + w
[3] + S0(w
[11]);
242 t2
= sum0(g
) + Maj(g
, h
, a
);
246 t1
= e
+ sum1(b
) + Ch(b
, c
, d
) + k
[t
+11] + w
[11];
247 w
[11] += S1(w
[9]) + w
[4] + S0(w
[12]);
248 t2
= sum0(f
) + Maj(f
, g
, h
);
252 t1
= d
+ sum1(a
) + Ch(a
, b
, c
) + k
[t
+12] + w
[12];
253 w
[12] += S1(w
[10]) + w
[5] + S0(w
[13]);
254 t2
= sum0(e
) + Maj(e
, f
, g
);
258 t1
= c
+ sum1(h
) + Ch(h
, a
, b
) + k
[t
+13] + w
[13];
259 w
[13] += S1(w
[11]) + w
[6] + S0(w
[14]);
260 t2
= sum0(d
) + Maj(d
, e
, f
);
264 t1
= b
+ sum1(g
) + Ch(g
, h
, a
) + k
[t
+14] + w
[14];
265 w
[14] += S1(w
[12]) + w
[7] + S0(w
[15]);
266 t2
= sum0(c
) + Maj(c
, d
, e
);
270 t1
= a
+ sum1(f
) + Ch(f
, g
, h
) + k
[t
+15] + w
[15];
271 w
[15] += S1(w
[13]) + w
[8] + S0(w
[0]);
272 t2
= sum0(b
) + Maj(b
, c
, d
);
284 #ifndef SHA512_UNROLLED
285 t1
= h
+ sum1(e
) + Ch(e
, f
, g
) + k
[t
] + w
[t
%16];
286 t2
= sum0(a
) + Maj(a
, b
, c
);
297 t1
= h
+ sum1(e
) + Ch(e
, f
, g
) + k
[t
] + w
[0];
298 t2
= sum0(a
) + Maj(a
, b
, c
);
302 t1
= g
+ sum1(d
) + Ch(d
, e
, f
) + k
[t
+1] + w
[1];
303 t2
= sum0(h
) + Maj(h
, a
, b
);
307 t1
= f
+ sum1(c
) + Ch(c
, d
, e
) + k
[t
+2] + w
[2];
308 t2
= sum0(g
) + Maj(g
, h
, a
);
312 t1
= e
+ sum1(b
) + Ch(b
, c
, d
) + k
[t
+3] + w
[3];
313 t2
= sum0(f
) + Maj(f
, g
, h
);
317 t1
= d
+ sum1(a
) + Ch(a
, b
, c
) + k
[t
+4] + w
[4];
318 t2
= sum0(e
) + Maj(e
, f
, g
);
322 t1
= c
+ sum1(h
) + Ch(h
, a
, b
) + k
[t
+5] + w
[5];
323 t2
= sum0(d
) + Maj(d
, e
, f
);
327 t1
= b
+ sum1(g
) + Ch(g
, h
, a
) + k
[t
+6] + w
[6];
328 t2
= sum0(c
) + Maj(c
, d
, e
);
332 t1
= a
+ sum1(f
) + Ch(f
, g
, h
) + k
[t
+7] + w
[7];
333 t2
= sum0(b
) + Maj(b
, c
, d
);
337 t1
= h
+ sum1(e
) + Ch(e
, f
, g
) + k
[t
+8] + w
[8];
338 t2
= sum0(a
) + Maj(a
, b
, c
);
342 t1
= g
+ sum1(d
) + Ch(d
, e
, f
) + k
[t
+9] + w
[9];
343 t2
= sum0(h
) + Maj(h
, a
, b
);
347 t1
= f
+ sum1(c
) + Ch(c
, d
, e
) + k
[t
+10] + w
[10];
348 t2
= sum0(g
) + Maj(g
, h
, a
);
352 t1
= e
+ sum1(b
) + Ch(b
, c
, d
) + k
[t
+11] + w
[11];
353 t2
= sum0(f
) + Maj(f
, g
, h
);
357 t1
= d
+ sum1(a
) + Ch(a
, b
, c
) + k
[t
+12] + w
[12];
358 t2
= sum0(e
) + Maj(e
, f
, g
);
362 t1
= c
+ sum1(h
) + Ch(h
, a
, b
) + k
[t
+13] + w
[13];
363 t2
= sum0(d
) + Maj(d
, e
, f
);
367 t1
= b
+ sum1(g
) + Ch(g
, h
, a
) + k
[t
+14] + w
[14];
368 t2
= sum0(c
) + Maj(c
, d
, e
);
372 t1
= a
+ sum1(f
) + Ch(f
, g
, h
) + k
[t
+15] + w
[15];
373 t2
= sum0(b
) + Maj(b
, c
, d
);
381 /* Update chaining vars. */
391 return /* burn_stack */ (8 + 16) * sizeof(u64
) + sizeof(u32
) + 3 * sizeof(void*);
395 sha512_update(struct hash_context
*CTX
, const byte
*buf
, uint len
)
397 struct sha512_context
*ctx
= (void *) CTX
;
401 /* Fill rest of internal buffer */
402 for (; len
&& ctx
->count
< SHA512_BLOCK_SIZE
; len
--)
403 ctx
->buf
[ctx
->count
++] = *buf
++;
405 if (ctx
->count
< SHA512_BLOCK_SIZE
)
408 /* Process data from internal buffer */
409 sha512_transform(ctx
, ctx
->buf
);
417 /* Process data from input buffer */
418 while (len
>= SHA512_BLOCK_SIZE
)
420 sha512_transform(ctx
, buf
);
422 buf
+= SHA512_BLOCK_SIZE
;
423 len
-= SHA512_BLOCK_SIZE
;
426 /* Copy remaining data to internal buffer */
427 memcpy(ctx
->buf
, buf
, len
);
432 * The routine final terminates the computation and returns the digest. The
433 * handle is prepared for a new cycle, but adding bytes to the handle will the
434 * destroy the returned buffer.
436 * Returns: 64 bytes representing the digest. When used for sha384, we take the
437 * first 48 of those bytes.
440 sha512_final(struct hash_context
*CTX
)
442 struct sha512_context
*ctx
= (void *) CTX
;
445 sha512_update(CTX
, NULL
, 0); /* flush */
450 /* multiply by 128 to make a byte count */
452 msb
= (th
<< 7) | (t
>> 57);
455 if ((lsb
+= ctx
->count
) < t
)
457 /* multiply by 8 to make a bit count */
463 if (ctx
->count
< 112)
466 ctx
->buf
[ctx
->count
++] = 0x80; /* pad */
467 while(ctx
->count
< 112)
468 ctx
->buf
[ctx
->count
++] = 0; /* pad */
472 /* need one extra block */
473 ctx
->buf
[ctx
->count
++] = 0x80; /* pad character */
474 while(ctx
->count
< 128)
475 ctx
->buf
[ctx
->count
++] = 0;
476 sha512_update(CTX
, NULL
, 0); /* flush */
477 memset(ctx
->buf
, 0, 112); /* fill next block with zeroes */
480 /* append the 128 bit count */
481 put_u64(ctx
->buf
+ 112, msb
);
482 put_u64(ctx
->buf
+ 120, lsb
);
483 sha512_transform(ctx
, ctx
->buf
);
486 #define X(a) do { put_u64(p, ctx->h##a); p += 8; } while(0)