Improve.
[libgcrypt.git] / cipher / sha256.c
1 /* sha256.c - SHA256 hash function
2  *      Copyright (C) 2003 Free Software Foundation, Inc.
3  *
4  * This file is part of Libgcrypt.
5  *
6  * Libgcrypt is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as
8  * published by the Free Software Foundation; either version 2.1 of
9  * the License, or (at your option) any later version.
10  *
11  * Libgcrypt is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21
22 /*  Test vectors:
23     
24     "abc"
25     ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad
26
27     "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
28     248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1
29  
30     "a" one million times
31     cdc76e5c 9914fb92 81a1c7e2 84d73e67 f1809a48 a497200e 046d39cc c7112cd0
32
33  */
34
35
36 #include <config.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <assert.h>
41 #include "g10lib.h"
42 #include "memory.h"
43 #include "bithelp.h"
44 #include "cipher.h"
45
46 typedef struct {
47   u32  h0,h1,h2,h3,h4,h5,h6,h7;
48   u32  nblocks;
49   byte buf[64];
50   int  count;
51 } SHA256_CONTEXT;
52
53
54 static void
55 sha256_init (void *context)
56 {
57   SHA256_CONTEXT *hd = (SHA256_CONTEXT *) context;
58
59   hd->h0 = 0x6a09e667;
60   hd->h1 = 0xbb67ae85;
61   hd->h2 = 0x3c6ef372;
62   hd->h3 = 0xa54ff53a;
63   hd->h4 = 0x510e527f;
64   hd->h5 = 0x9b05688c;
65   hd->h6 = 0x1f83d9ab;
66   hd->h7 = 0x5be0cd19;
67
68   hd->nblocks = 0;
69   hd->count = 0;
70 }
71
72
73 /*
74   Transform the message X which consists of 16 32-bit-words. See FIPS
75   180-2 for details.  */
76 #define Cho(x,y,z) (z ^ (x & (y ^ z)))      /* (4.2) same as SHA-1's F1 */
77 #define Maj(x,y,z) ((x & y) | (z & (x|y)))  /* (4.3) same as SHA-1's F3 */
78 #define Sum0(x) (ror ((x), 2) ^ ror ((x), 13) ^ ror ((x), 22))  /* (4.4) */
79 #define Sum1(x) (ror ((x), 6) ^ ror ((x), 11) ^ ror ((x), 25))  /* (4.5) */
80 #define S0(x) (ror ((x), 7) ^ ror ((x), 18) ^ ((x) >> 3))       /* (4.6) */
81 #define S1(x) (ror ((x), 17) ^ ror ((x), 19) ^ ((x) >> 10))     /* (4.7) */
82 #define R(a,b,c,d,e,f,g,h,k,w) do                                 \
83           {                                                       \
84             t1 = (h) + Sum1((e)) + Cho((e),(f),(g)) + (k) + (w);  \
85             t2 = Sum0((a)) + Maj((a),(b),(c));                    \
86             h = g;                                                \
87             g = f;                                                \
88             f = e;                                                \
89             e = d + t1;                                           \
90             d = c;                                                \
91             c = b;                                                \
92             b = a;                                                \
93             a = t1 + t2;                                          \
94           } while (0)
95  
96 static void
97 transform (SHA256_CONTEXT *hd, byte *data)
98 {
99   static const u32 K[64] = {
100     0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
101     0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
102     0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
103     0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 
104     0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
105     0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
106     0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
107     0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
108     0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
109     0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
110     0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
111     0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
112     0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
113     0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
114     0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
115     0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
116   };
117
118   u32 a,b,c,d,e,f,g,h,t1,t2;
119   u32 x[16];
120   u32 w[64];
121   int i;
122   
123   a = hd->h0;
124   b = hd->h1;
125   c = hd->h2;
126   d = hd->h3;
127   e = hd->h4;
128   f = hd->h5;
129   g = hd->h6;
130   h = hd->h7;
131   
132 #ifdef WORDS_BIGENDIAN
133   memcpy (x, data, 64);
134 #else
135   { 
136     byte *p2;
137   
138     for (i=0, p2=(byte*)x; i < 16; i++, p2 += 4 ) 
139       {
140         p2[3] = *data++;
141         p2[2] = *data++;
142         p2[1] = *data++;
143         p2[0] = *data++;
144       }
145   }
146 #endif
147
148   for (i=0; i < 16; i++)
149     w[i] = x[i];
150   for (; i < 64; i++)
151     w[i] = S1(w[i-2]) + w[i-7] + S0(w[i-15]) + w[i-16];
152
153   for (i=0; i < 64; i++)
154     R(a,b,c,d,e,f,g,h,K[i],w[i]);
155
156   hd->h0 += a;
157   hd->h1 += b;
158   hd->h2 += c;
159   hd->h3 += d;
160   hd->h4 += e;
161   hd->h5 += f;
162   hd->h6 += g;
163   hd->h7 += h;
164 }
165 #undef Cho
166 #undef Maj
167 #undef Sum0
168 #undef Sum1
169 #undef S0
170 #undef S1
171 #undef R
172
173
174 /* Update the message digest with the contents of INBUF with length
175   INLEN.  */
176 static void
177 sha256_write (void *context, byte *inbuf, size_t inlen)
178 {
179   SHA256_CONTEXT *hd = (SHA256_CONTEXT *) context;
180   if (hd->count == 64)
181     { /* flush the buffer */
182       transform (hd, hd->buf);
183       _gcry_burn_stack (74*4+32);
184       hd->count = 0;
185       hd->nblocks++;
186     }
187   if (!inbuf)
188     return;
189   if (hd->count)
190     {
191       for (; inlen && hd->count < 64; inlen--)
192         hd->buf[hd->count++] = *inbuf++;
193       sha256_write (hd, NULL, 0);
194       if (!inlen)
195         return;
196     }
197
198   while (inlen >= 64)
199     {
200       transform (hd, inbuf);
201       hd->count = 0;
202       hd->nblocks++;
203       inlen -= 64;
204       inbuf += 64;
205     }
206   _gcry_burn_stack (74*4+32);
207   for (; inlen && hd->count < 64; inlen--)
208     hd->buf[hd->count++] = *inbuf++;
209 }
210
211
212 /*
213    The routine finally terminates the computation and returns the
214    digest.  The handle is prepared for a new cycle, but adding bytes
215    to the handle will the destroy the returned buffer.  Returns: 32
216    bytes with the message the digest.  */
217 static void
218 sha256_final(void *context)
219 {
220   SHA256_CONTEXT *hd = (SHA256_CONTEXT *) context;
221   u32 t, msb, lsb;
222   byte *p;
223   
224   sha256_write (hd, NULL, 0); /* flush */;
225
226   t = hd->nblocks;
227   /* multiply by 64 to make a byte count */
228   lsb = t << 6;
229   msb = t >> 26;
230   /* add the count */
231   t = lsb;
232   if ((lsb += hd->count) < t)
233     msb++;
234   /* multiply by 8 to make a bit count */
235   t = lsb;
236   lsb <<= 3;
237   msb <<= 3;
238   msb |= t >> 29;
239
240   if (hd->count < 56)
241     { /* enough room */
242       hd->buf[hd->count++] = 0x80; /* pad */
243       while (hd->count < 56)
244         hd->buf[hd->count++] = 0;  /* pad */
245     }
246   else
247     { /* need one extra block */
248       hd->buf[hd->count++] = 0x80; /* pad character */
249       while (hd->count < 64)
250         hd->buf[hd->count++] = 0;
251       sha256_write (hd, NULL, 0);  /* flush */;
252       memset (hd->buf, 0, 56 ); /* fill next block with zeroes */
253     }
254   /* append the 64 bit count */
255   hd->buf[56] = msb >> 24;
256   hd->buf[57] = msb >> 16;
257   hd->buf[58] = msb >>  8;
258   hd->buf[59] = msb;
259   hd->buf[60] = lsb >> 24;
260   hd->buf[61] = lsb >> 16;
261   hd->buf[62] = lsb >>  8;
262   hd->buf[63] = lsb;
263   transform (hd, hd->buf);
264   _gcry_burn_stack (74*4+32);
265
266   p = hd->buf;
267 #ifdef WORDS_BIGENDIAN
268 #define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
269 #else /* little endian */
270 #define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16;  \
271                   *p++ = hd->h##a >> 8; *p++ = hd->h##a; } while(0)
272 #endif
273   X(0);
274   X(1);
275   X(2);
276   X(3);
277   X(4);
278   X(5);
279   X(6);
280   X(7);
281 #undef X
282 }
283
284 static byte *
285 sha256_read (void *context)
286 {
287   SHA256_CONTEXT *hd = (SHA256_CONTEXT *) context;
288   return hd->buf;
289 }
290
291 static byte asn[19] = /* Object ID is  2.16.840.1.101.3.4.2.1 */
292   { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
293     0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
294     0x00, 0x04, 0x20 };
295
296 gcry_md_spec_t digest_spec_sha256 =
297   {
298     "SHA256", asn, DIM (asn), 32,
299     sha256_init, sha256_write, sha256_final, sha256_read,
300     sizeof (SHA256_CONTEXT)
301   };