• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.bouncycastle.crypto.digests;
2 
3 
4 import org.bouncycastle.crypto.digests.GeneralDigest;
5 import org.bouncycastle.crypto.util.Pack;
6 
7 
8 /**
9  * FIPS 180-2 implementation of SHA-256.
10  *
11  * <pre>
12  *         block  word  digest
13  * SHA-1   512    32    160
14  * SHA-256 512    32    256
15  * SHA-384 1024   64    384
16  * SHA-512 1024   64    512
17  * </pre>
18  */
19 public class SHA256Digest
20     extends GeneralDigest
21 {
22     private static final int    DIGEST_LENGTH = 32;
23 
24     private int     H1, H2, H3, H4, H5, H6, H7, H8;
25 
26     private int[]   X = new int[64];
27     private int     xOff;
28 
29     /**
30      * Standard constructor
31      */
SHA256Digest()32     public SHA256Digest()
33     {
34         reset();
35     }
36 
37     /**
38      * Copy constructor.  This will copy the state of the provided
39      * message digest.
40      */
SHA256Digest(SHA256Digest t)41     public SHA256Digest(SHA256Digest t)
42     {
43         super(t);
44 
45         H1 = t.H1;
46         H2 = t.H2;
47         H3 = t.H3;
48         H4 = t.H4;
49         H5 = t.H5;
50         H6 = t.H6;
51         H7 = t.H7;
52         H8 = t.H8;
53 
54         System.arraycopy(t.X, 0, X, 0, t.X.length);
55         xOff = t.xOff;
56     }
57 
getAlgorithmName()58     public String getAlgorithmName()
59     {
60         return "SHA-256";
61     }
62 
getDigestSize()63     public int getDigestSize()
64     {
65         return DIGEST_LENGTH;
66     }
67 
processWord( byte[] in, int inOff)68     protected void processWord(
69         byte[]  in,
70         int     inOff)
71     {
72         // Note: Inlined for performance
73 //        X[xOff] = Pack.bigEndianToInt(in, inOff);
74         int n = in[inOff] << 24;
75         n |= (in[++inOff] & 0xff) << 16;
76         n |= (in[++inOff] & 0xff) << 8;
77         n |= (in[++inOff] & 0xff);
78         X[xOff] = n;
79 
80         if (++xOff == 16)
81         {
82             processBlock();
83         }
84     }
85 
processLength( long bitLength)86     protected void processLength(
87         long    bitLength)
88     {
89         if (xOff > 14)
90         {
91             processBlock();
92         }
93 
94         X[14] = (int)(bitLength >>> 32);
95         X[15] = (int)(bitLength & 0xffffffff);
96     }
97 
doFinal( byte[] out, int outOff)98     public int doFinal(
99         byte[]  out,
100         int     outOff)
101     {
102         finish();
103 
104         Pack.intToBigEndian(H1, out, outOff);
105         Pack.intToBigEndian(H2, out, outOff + 4);
106         Pack.intToBigEndian(H3, out, outOff + 8);
107         Pack.intToBigEndian(H4, out, outOff + 12);
108         Pack.intToBigEndian(H5, out, outOff + 16);
109         Pack.intToBigEndian(H6, out, outOff + 20);
110         Pack.intToBigEndian(H7, out, outOff + 24);
111         Pack.intToBigEndian(H8, out, outOff + 28);
112 
113         reset();
114 
115         return DIGEST_LENGTH;
116     }
117 
118     /**
119      * reset the chaining variables
120      */
reset()121     public void reset()
122     {
123         super.reset();
124 
125         /* SHA-256 initial hash value
126          * The first 32 bits of the fractional parts of the square roots
127          * of the first eight prime numbers
128          */
129 
130         H1 = 0x6a09e667;
131         H2 = 0xbb67ae85;
132         H3 = 0x3c6ef372;
133         H4 = 0xa54ff53a;
134         H5 = 0x510e527f;
135         H6 = 0x9b05688c;
136         H7 = 0x1f83d9ab;
137         H8 = 0x5be0cd19;
138 
139         xOff = 0;
140         for (int i = 0; i != X.length; i++)
141         {
142             X[i] = 0;
143         }
144     }
145 
processBlock()146     protected void processBlock()
147     {
148         //
149         // expand 16 word block into 64 word blocks.
150         //
151         for (int t = 16; t <= 63; t++)
152         {
153             X[t] = Theta1(X[t - 2]) + X[t - 7] + Theta0(X[t - 15]) + X[t - 16];
154         }
155 
156         //
157         // set up working variables.
158         //
159         int     a = H1;
160         int     b = H2;
161         int     c = H3;
162         int     d = H4;
163         int     e = H5;
164         int     f = H6;
165         int     g = H7;
166         int     h = H8;
167 
168         int t = 0;
169         for(int i = 0; i < 8; i ++)
170         {
171             // t = 8 * i
172             h += Sum1(e) + Ch(e, f, g) + K[t] + X[t];
173             d += h;
174             h += Sum0(a) + Maj(a, b, c);
175             ++t;
176 
177             // t = 8 * i + 1
178             g += Sum1(d) + Ch(d, e, f) + K[t] + X[t];
179             c += g;
180             g += Sum0(h) + Maj(h, a, b);
181             ++t;
182 
183             // t = 8 * i + 2
184             f += Sum1(c) + Ch(c, d, e) + K[t] + X[t];
185             b += f;
186             f += Sum0(g) + Maj(g, h, a);
187             ++t;
188 
189             // t = 8 * i + 3
190             e += Sum1(b) + Ch(b, c, d) + K[t] + X[t];
191             a += e;
192             e += Sum0(f) + Maj(f, g, h);
193             ++t;
194 
195             // t = 8 * i + 4
196             d += Sum1(a) + Ch(a, b, c) + K[t] + X[t];
197             h += d;
198             d += Sum0(e) + Maj(e, f, g);
199             ++t;
200 
201             // t = 8 * i + 5
202             c += Sum1(h) + Ch(h, a, b) + K[t] + X[t];
203             g += c;
204             c += Sum0(d) + Maj(d, e, f);
205             ++t;
206 
207             // t = 8 * i + 6
208             b += Sum1(g) + Ch(g, h, a) + K[t] + X[t];
209             f += b;
210             b += Sum0(c) + Maj(c, d, e);
211             ++t;
212 
213             // t = 8 * i + 7
214             a += Sum1(f) + Ch(f, g, h) + K[t] + X[t];
215             e += a;
216             a += Sum0(b) + Maj(b, c, d);
217             ++t;
218         }
219 
220         H1 += a;
221         H2 += b;
222         H3 += c;
223         H4 += d;
224         H5 += e;
225         H6 += f;
226         H7 += g;
227         H8 += h;
228 
229         //
230         // reset the offset and clean out the word buffer.
231         //
232         xOff = 0;
233         for (int i = 0; i < 16; i++)
234         {
235             X[i] = 0;
236         }
237     }
238 
239     /* SHA-256 functions */
Ch( int x, int y, int z)240     private int Ch(
241         int    x,
242         int    y,
243         int    z)
244     {
245         return (x & y) ^ ((~x) & z);
246     }
247 
Maj( int x, int y, int z)248     private int Maj(
249         int    x,
250         int    y,
251         int    z)
252     {
253         return (x & y) ^ (x & z) ^ (y & z);
254     }
255 
Sum0( int x)256     private int Sum0(
257         int    x)
258     {
259         return ((x >>> 2) | (x << 30)) ^ ((x >>> 13) | (x << 19)) ^ ((x >>> 22) | (x << 10));
260     }
261 
Sum1( int x)262     private int Sum1(
263         int    x)
264     {
265         return ((x >>> 6) | (x << 26)) ^ ((x >>> 11) | (x << 21)) ^ ((x >>> 25) | (x << 7));
266     }
267 
Theta0( int x)268     private int Theta0(
269         int    x)
270     {
271         return ((x >>> 7) | (x << 25)) ^ ((x >>> 18) | (x << 14)) ^ (x >>> 3);
272     }
273 
Theta1( int x)274     private int Theta1(
275         int    x)
276     {
277         return ((x >>> 17) | (x << 15)) ^ ((x >>> 19) | (x << 13)) ^ (x >>> 10);
278     }
279 
280     /* SHA-256 Constants
281      * (represent the first 32 bits of the fractional parts of the
282      * cube roots of the first sixty-four prime numbers)
283      */
284     static final int K[] = {
285         0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
286         0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
287         0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
288         0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
289         0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
290         0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
291         0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
292         0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
293     };
294 }
295 
296