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