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