Team TDB Members: Anthony Knopp Zach Langley SHA-1 Team TDB Members: Anthony Knopp Zach Langley
Overview SHA-1 is a cryptographic hash function designed by the NSA and published by the NIST as a U.S Federal standard. It is a Merkle-Damgard construction, 160 bit digest size hash that performs 80 rounds. The spec was first published in 1995, two years after SHA-0. In 2005 SHA-1 was proven to be “broken” and various weaknesses were found in the hash function. No collisions were found but the running time to find one was proven to be much smaller than brute force.
Padding SHA-1 pads data in the following way: 1) Append the bitstring 10000…000 to the message (the amount of 0’s depends on the original message length) 2) The last two words in the message are set to be the amount of bits in the original message E.g., “hello” after padding becomes: 68656c6c 6f800000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000028
Round Function Constants: A0 = 67452301 B0 = EFCDAB89 C0 = 98BADCFE E0 = C3D2E1F0 K0..19 = 5A827999 K20..39 = 6ED9EBA1 K40..59 = 8F1BBCDC K60..79 = CA62C1D6
Original Design Original Algorithm: We originally stored the words to hash as a circular queue of sixteen 32- bit words, and used bitwise operations to compute hash Took advantage of Merkle-Damgård construction by using an append(byte) method, which would hash the data as it filled up
Original Runtime Measurements time java –Xint SHATest test.txt time java –Xint SHATestBulk 500000 Trial(#) 20mb File Results(s) 1 82.284 2 82.228 3 82.227 Average 82.246 Trial(#) bulk encrypt Results(s) 1 106.096 2 106.272 3 106.105 Average 106.157
Original Profile(File) Rank Self Accum Method Location 1 12.03% java.io .BufferedInputStream .read SHATest.java:11 2 9.66% 21.68% SHA1.compress SHA1.java:113 3 7.71% 29.40% SHA1.java:97 4 7.21% 36.61% SHA1.f SHA1.java:11 5 7.14% 43.75% SHA1.append SHA1.java:45
Original Profile(Bulk Encryptions) Rank Self Accum Method Location 1 10.23% SHA1.compress SHA1.java:113 2 8.46% 18.69% SHA1.java:97 3 7.50% 26.19% SHA1.f SHA1.java:11 4 6.83% 33.02% SHA1.java:88 5 6.09% 39.11% SHA1.java:101 6 4.88% 43.99% SHA1.java:94 7 4.05% 48.13% SHA1.java:22
Original Analysis Offending lines: data = new int[16]; int temp = circularShift(a, 5) + f(t, b, c, d) + e + data[s] + k[t/20]; if (t < 20) for (int t = 0; t <= 79; t++) { c = circularShift(b, 30); data[s] = circularShift(data[s], 1); return (x << n) | (x >>> (32 - n)); if (bytes >= 4 * data.length)
Revised Design Unrolled loop Operated on an array of 80 words, instead of masking with 16 In-lined all functions and constants Used 5 chaining values instead of an array
Revised Design Runtime time java –Xint SHATestOptimized test.txt time java –Xint SHATestBulkOptimized 1000000 Trial(#) 20mb File Results(s) 1 49.010 2 48.973 3 49.261 Average 49.081 Trial(#) 20mb File Results(s) 1 65.342 2 65.412 3 65.400 Average 65.384
Revised Design Profile (file) Rank Self Accum Method Location 1 30.40% java.io .BufferedInputStream .read SHATest.java:11 2 14.41% 44.82% OptimizedSHA1.append OptimizedSHA1.java:26 3 8.06% 52.87% 4 2.06% 54.94% 5 1.94% 56.88%
Revised Design Profile(Bulk Encryptions) Rank Self Accum Method Location 1 24.84% java.lang .AbstractStringBuilder .<init> OptimizedSHA1.java:316 2 5.79% 30.63% java.util.Arrays .copyOfRange 3 5.56% 36.19% 4 5.52% 41.70% 5 5.41% 47.11% 6 5.06% 52.18% 7 1.71% 53.89%
Revised Analysis Offending lines: String ret = Hex.toString(chain0) + Hex.toString(chain1) + Hex.toString(chain2) + Hex.toString(chain3) + Hex.toString(chain4); data[bytes >> 2] = (data[bytes >> 2] << 8) | (b & 0xff);
What We Learned We learned that the government spec for SHA-1 is very thorough in its description and implementation of SHA-1. The implementation didn’t pose much trouble. We learned that really trying to trim down run time can be a pain and requires a lot of trial and error. You can have an idea of what will reduce runtime but it turns out it doesn’t really help at all and sometimes makes it worse.
Possible Future Work There’s not much future work when it comes to implementing the algorithm. It would be interesting to implement the algorithm in another language and compare the running times between Java and the other language. Future work could also include attempting to implement some of the attacks against SHA-1 and see if we can find some collisions on smaller amounts of rounds.