SHA256Digest.java revision e6bf3e8dfa2804891a82075cb469b736321b4827
1package org.bouncycastle.crypto.digests;
2
3
4import org.bouncycastle.crypto.digests.GeneralDigest;
5import 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 */
19public 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     */
32    public SHA256Digest()
33    {
34        reset();
35    }
36
37    /**
38     * Copy constructor.  This will copy the state of the provided
39     * message digest.
40     */
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
58    public String getAlgorithmName()
59    {
60        return "SHA-256";
61    }
62
63    public int getDigestSize()
64    {
65        return DIGEST_LENGTH;
66    }
67
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
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
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     */
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
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 */
240    private int Ch(
241        int    x,
242        int    y,
243        int    z)
244    {
245        return (x & y) ^ ((~x) & z);
246    }
247
248    private int Maj(
249        int    x,
250        int    y,
251        int    z)
252    {
253        return (x & y) ^ (x & z) ^ (y & z);
254    }
255
256    private int Sum0(
257        int    x)
258    {
259        return ((x >>> 2) | (x << 30)) ^ ((x >>> 13) | (x << 19)) ^ ((x >>> 22) | (x << 10));
260    }
261
262    private int Sum1(
263        int    x)
264    {
265        return ((x >>> 6) | (x << 26)) ^ ((x >>> 11) | (x << 21)) ^ ((x >>> 25) | (x << 7));
266    }
267
268    private int Theta0(
269        int    x)
270    {
271        return ((x >>> 7) | (x << 25)) ^ ((x >>> 18) | (x << 14)) ^ (x >>> 3);
272    }
273
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