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