Home | History | Annotate | Download | only in digests
      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      */
     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