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