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