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