Skip to content

Instantly share code, notes, and snippets.

@natmchugh
Last active October 9, 2015 16:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save natmchugh/12c8a4798784cff696f4 to your computer and use it in GitHub Desktop.
Save natmchugh/12c8a4798784cff696f4 to your computer and use it in GitHub Desktop.
Python version of a quick check of the Freestart collision published here https://sites.google.com/site/itstheshappening/
import struct, binascii
def _left_rotate(n, b):
return ((n << b) | (n >> (32 - b))) & 0xffffffff
def sha1(IV, message):
# Initialize variables:
(h0, h1, h2, h3, h4) = IV
# Pre-processing:
original_byte_len = len(message)
original_bit_len = original_byte_len * 8
# append the bit '1' to the message
message += b'\x80'
# append 0 <= k < 512 bits '0', so that the resulting message length (in bits)
# is congruent to 448 (mod 512)
message += b'\x00' * ((56 - (original_byte_len + 1) % 64) % 64)
# append length of message (before pre-processing), in bits, as 64-bit big-endian integer
message += struct.pack(b'>Q', original_bit_len)
# Process the message in successive 512-bit chunks:
# break message into 512-bit chunks
for i in range(0, len(message), 64):
w = [0] * 80
# break chunk into sixteen 32-bit big-endian words w[i]
for j in range(16):
w[j] = struct.unpack(b'>I', message[i + j*4:i + j*4 + 4])[0]
# Extend the sixteen 32-bit words into eighty 32-bit words:
for j in range(16, 80):
w[j] = _left_rotate(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1)
# Initialize hash value for this chunk:
a = h0
b = h1
c = h2
d = h3
e = h4
for i in range(80):
if 0 <= i <= 19:
# Use alternative 1 for f from FIPS PB 180-1 to avoid ~
f = d ^ (b & (c ^ d))
k = 0x5A827999
elif 20 <= i <= 39:
f = b ^ c ^ d
k = 0x6ED9EBA1
elif 40 <= i <= 59:
f = (b & c) | (b & d) | (c & d)
k = 0x8F1BBCDC
elif 60 <= i <= 79:
f = b ^ c ^ d
k = 0xCA62C1D6
a, b, c, d, e = ((_left_rotate(a, 5) + f + e + k + w[i]) & 0xffffffff,
a, _left_rotate(b, 30), c, d)
# sAdd this chunk's hash to result so far:
h0 = (h0 + a) & 0xffffffff
h1 = (h1 + b) & 0xffffffff
h2 = (h2 + c) & 0xffffffff
h3 = (h3 + d) & 0xffffffff
h4 = (h4 + e) & 0xffffffff
# Produce the final hash value (big-endian):
return '%08x%08x%08x%08x%08x' % (h0, h1, h2, h3, h4)
IV1 = [0x506b0178, 0xff6d1890, 0x202291fd, 0x3ade3871, 0xb2c665ea]
M1 = '9d443828a5ea3df086eaa0fa7783a7363324484daf702aaaa3dab679d8a69e2d543820eda7fffb52d3ff493fc3ff551efbffd97f55feeef2085af312088688a9'
hash1 = sha1(IV1, binascii.unhexlify(M1))
IV2 = [0x506b0178, 0xff6d1891, 0xa02291fd, 0x3ade3871, 0xb2c665ea];
M2 = '3f44383881ea3deca0eaa0ee5183a72c3324485dab702ab66fdab66dd4a69e2f943820fd13fffb4eefff493b7fff5504dbffd96f71feeeeee45af306048688ab'
hash2 = sha1(IV2, binascii.unhexlify(M2))
print hash1
print hash2
print hash1 == hash2
@natmchugh
Copy link
Author

Output should be:

54813675e9900e893a481f290c1310a72806f86a
54813675e9900e893a481f290c1310a72806f86a
True

@natmchugh
Copy link
Author

If you want it without padding which will give the hash same hash values as in the paper comment out line 14 to 21

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment