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