1 package org.bouncycastle.crypto.digests; 2 3 import org.bouncycastle.crypto.ExtendedDigest; 4 import org.bouncycastle.crypto.util.Pack; 5 6 /** 7 * Base class for SHA-384 and SHA-512. 8 */ 9 public abstract class LongDigest 10 implements ExtendedDigest 11 { 12 private static final int BYTE_LENGTH = 128; 13 14 private byte[] xBuf; 15 private int xBufOff; 16 17 private long byteCount1; 18 private long byteCount2; 19 20 protected long H1, H2, H3, H4, H5, H6, H7, H8; 21 22 private long[] W = new long[80]; 23 private int wOff; 24 25 /** 26 * Constructor for variable length word 27 */ 28 protected LongDigest() 29 { 30 xBuf = new byte[8]; 31 xBufOff = 0; 32 33 reset(); 34 } 35 36 /** 37 * Copy constructor. We are using copy constructors in place 38 * of the Object.clone() interface as this interface is not 39 * supported by J2ME. 40 */ 41 protected LongDigest(LongDigest t) 42 { 43 xBuf = new byte[t.xBuf.length]; 44 System.arraycopy(t.xBuf, 0, xBuf, 0, t.xBuf.length); 45 46 xBufOff = t.xBufOff; 47 byteCount1 = t.byteCount1; 48 byteCount2 = t.byteCount2; 49 50 H1 = t.H1; 51 H2 = t.H2; 52 H3 = t.H3; 53 H4 = t.H4; 54 H5 = t.H5; 55 H6 = t.H6; 56 H7 = t.H7; 57 H8 = t.H8; 58 59 System.arraycopy(t.W, 0, W, 0, t.W.length); 60 wOff = t.wOff; 61 } 62 63 public void update( 64 byte in) 65 { 66 xBuf[xBufOff++] = in; 67 68 if (xBufOff == xBuf.length) 69 { 70 processWord(xBuf, 0); 71 xBufOff = 0; 72 } 73 74 byteCount1++; 75 } 76 77 public void update( 78 byte[] in, 79 int inOff, 80 int len) 81 { 82 // 83 // fill the current word 84 // 85 while ((xBufOff != 0) && (len > 0)) 86 { 87 update(in[inOff]); 88 89 inOff++; 90 len--; 91 } 92 93 // 94 // process whole words. 95 // 96 while (len > xBuf.length) 97 { 98 processWord(in, inOff); 99 100 inOff += xBuf.length; 101 len -= xBuf.length; 102 byteCount1 += xBuf.length; 103 } 104 105 // 106 // load in the remainder. 107 // 108 while (len > 0) 109 { 110 update(in[inOff]); 111 112 inOff++; 113 len--; 114 } 115 } 116 117 public void finish() 118 { 119 adjustByteCounts(); 120 121 long lowBitLength = byteCount1 << 3; 122 long hiBitLength = byteCount2; 123 124 // 125 // add the pad bytes. 126 // 127 update((byte)128); 128 129 while (xBufOff != 0) 130 { 131 update((byte)0); 132 } 133 134 processLength(lowBitLength, hiBitLength); 135 136 processBlock(); 137 } 138 139 public void reset() 140 { 141 byteCount1 = 0; 142 byteCount2 = 0; 143 144 xBufOff = 0; 145 for (int i = 0; i < xBuf.length; i++) 146 { 147 xBuf[i] = 0; 148 } 149 150 wOff = 0; 151 for (int i = 0; i != W.length; i++) 152 { 153 W[i] = 0; 154 } 155 } 156 157 public int getByteLength() 158 { 159 return BYTE_LENGTH; 160 } 161 162 protected void processWord( 163 byte[] in, 164 int inOff) 165 { 166 W[wOff] = Pack.bigEndianToLong(in, inOff); 167 168 if (++wOff == 16) 169 { 170 processBlock(); 171 } 172 } 173 174 /** 175 * adjust the byte counts so that byteCount2 represents the 176 * upper long (less 3 bits) word of the byte count. 177 */ 178 private void adjustByteCounts() 179 { 180 if (byteCount1 > 0x1fffffffffffffffL) 181 { 182 byteCount2 += (byteCount1 >>> 61); 183 byteCount1 &= 0x1fffffffffffffffL; 184 } 185 } 186 187 protected void processLength( 188 long lowW, 189 long hiW) 190 { 191 if (wOff > 14) 192 { 193 processBlock(); 194 } 195 196 W[14] = hiW; 197 W[15] = lowW; 198 } 199 200 protected void processBlock() 201 { 202 adjustByteCounts(); 203 204 // 205 // expand 16 word block into 80 word blocks. 206 // 207 for (int t = 16; t <= 79; t++) 208 { 209 W[t] = Sigma1(W[t - 2]) + W[t - 7] + Sigma0(W[t - 15]) + W[t - 16]; 210 } 211 212 // 213 // set up working variables. 214 // 215 long a = H1; 216 long b = H2; 217 long c = H3; 218 long d = H4; 219 long e = H5; 220 long f = H6; 221 long g = H7; 222 long h = H8; 223 224 int t = 0; 225 for(int i = 0; i < 10; i ++) 226 { 227 // t = 8 * i 228 h += Sum1(e) + Ch(e, f, g) + K[t] + W[t++]; 229 d += h; 230 h += Sum0(a) + Maj(a, b, c); 231 232 // t = 8 * i + 1 233 g += Sum1(d) + Ch(d, e, f) + K[t] + W[t++]; 234 c += g; 235 g += Sum0(h) + Maj(h, a, b); 236 237 // t = 8 * i + 2 238 f += Sum1(c) + Ch(c, d, e) + K[t] + W[t++]; 239 b += f; 240 f += Sum0(g) + Maj(g, h, a); 241 242 // t = 8 * i + 3 243 e += Sum1(b) + Ch(b, c, d) + K[t] + W[t++]; 244 a += e; 245 e += Sum0(f) + Maj(f, g, h); 246 247 // t = 8 * i + 4 248 d += Sum1(a) + Ch(a, b, c) + K[t] + W[t++]; 249 h += d; 250 d += Sum0(e) + Maj(e, f, g); 251 252 // t = 8 * i + 5 253 c += Sum1(h) + Ch(h, a, b) + K[t] + W[t++]; 254 g += c; 255 c += Sum0(d) + Maj(d, e, f); 256 257 // t = 8 * i + 6 258 b += Sum1(g) + Ch(g, h, a) + K[t] + W[t++]; 259 f += b; 260 b += Sum0(c) + Maj(c, d, e); 261 262 // t = 8 * i + 7 263 a += Sum1(f) + Ch(f, g, h) + K[t] + W[t++]; 264 e += a; 265 a += Sum0(b) + Maj(b, c, d); 266 } 267 268 H1 += a; 269 H2 += b; 270 H3 += c; 271 H4 += d; 272 H5 += e; 273 H6 += f; 274 H7 += g; 275 H8 += h; 276 277 // 278 // reset the offset and clean out the word buffer. 279 // 280 wOff = 0; 281 for (int i = 0; i < 16; i++) 282 { 283 W[i] = 0; 284 } 285 } 286 287 /* SHA-384 and SHA-512 functions (as for SHA-256 but for longs) */ 288 private long Ch( 289 long x, 290 long y, 291 long z) 292 { 293 return ((x & y) ^ ((~x) & z)); 294 } 295 296 private long Maj( 297 long x, 298 long y, 299 long z) 300 { 301 return ((x & y) ^ (x & z) ^ (y & z)); 302 } 303 304 private long Sum0( 305 long x) 306 { 307 return ((x << 36)|(x >>> 28)) ^ ((x << 30)|(x >>> 34)) ^ ((x << 25)|(x >>> 39)); 308 } 309 310 private long Sum1( 311 long x) 312 { 313 return ((x << 50)|(x >>> 14)) ^ ((x << 46)|(x >>> 18)) ^ ((x << 23)|(x >>> 41)); 314 } 315 316 private long Sigma0( 317 long x) 318 { 319 return ((x << 63)|(x >>> 1)) ^ ((x << 56)|(x >>> 8)) ^ (x >>> 7); 320 } 321 322 private long Sigma1( 323 long x) 324 { 325 return ((x << 45)|(x >>> 19)) ^ ((x << 3)|(x >>> 61)) ^ (x >>> 6); 326 } 327 328 /* SHA-384 and SHA-512 Constants 329 * (represent the first 64 bits of the fractional parts of the 330 * cube roots of the first sixty-four prime numbers) 331 */ 332 static final long K[] = { 333 0x428a2f98d728ae22L, 0x7137449123ef65cdL, 0xb5c0fbcfec4d3b2fL, 0xe9b5dba58189dbbcL, 334 0x3956c25bf348b538L, 0x59f111f1b605d019L, 0x923f82a4af194f9bL, 0xab1c5ed5da6d8118L, 335 0xd807aa98a3030242L, 0x12835b0145706fbeL, 0x243185be4ee4b28cL, 0x550c7dc3d5ffb4e2L, 336 0x72be5d74f27b896fL, 0x80deb1fe3b1696b1L, 0x9bdc06a725c71235L, 0xc19bf174cf692694L, 337 0xe49b69c19ef14ad2L, 0xefbe4786384f25e3L, 0x0fc19dc68b8cd5b5L, 0x240ca1cc77ac9c65L, 338 0x2de92c6f592b0275L, 0x4a7484aa6ea6e483L, 0x5cb0a9dcbd41fbd4L, 0x76f988da831153b5L, 339 0x983e5152ee66dfabL, 0xa831c66d2db43210L, 0xb00327c898fb213fL, 0xbf597fc7beef0ee4L, 340 0xc6e00bf33da88fc2L, 0xd5a79147930aa725L, 0x06ca6351e003826fL, 0x142929670a0e6e70L, 341 0x27b70a8546d22ffcL, 0x2e1b21385c26c926L, 0x4d2c6dfc5ac42aedL, 0x53380d139d95b3dfL, 342 0x650a73548baf63deL, 0x766a0abb3c77b2a8L, 0x81c2c92e47edaee6L, 0x92722c851482353bL, 343 0xa2bfe8a14cf10364L, 0xa81a664bbc423001L, 0xc24b8b70d0f89791L, 0xc76c51a30654be30L, 344 0xd192e819d6ef5218L, 0xd69906245565a910L, 0xf40e35855771202aL, 0x106aa07032bbd1b8L, 345 0x19a4c116b8d2d0c8L, 0x1e376c085141ab53L, 0x2748774cdf8eeb99L, 0x34b0bcb5e19b48a8L, 346 0x391c0cb3c5c95a63L, 0x4ed8aa4ae3418acbL, 0x5b9cca4f7763e373L, 0x682e6ff3d6b2b8a3L, 347 0x748f82ee5defb2fcL, 0x78a5636f43172f60L, 0x84c87814a1f0ab72L, 0x8cc702081a6439ecL, 348 0x90befffa23631e28L, 0xa4506cebde82bde9L, 0xbef9a3f7b2c67915L, 0xc67178f2e372532bL, 349 0xca273eceea26619cL, 0xd186b8c721c0c207L, 0xeada7dd6cde0eb1eL, 0xf57d4f7fee6ed178L, 350 0x06f067aa72176fbaL, 0x0a637dc5a2c898a6L, 0x113f9804bef90daeL, 0x1b710b35131c471bL, 351 0x28db77f523047d84L, 0x32caab7b40c72493L, 0x3c9ebe0a15c9bebcL, 0x431d67c49c100d4cL, 352 0x4cc5d4becb3e42b6L, 0x597f299cfc657e2aL, 0x5fcb6fab3ad6faecL, 0x6c44198c4a475817L 353 }; 354 } 355