Created
January 5, 2018 14:22
-
-
Save rhizoome/ef5d38415ee6cecd666455e07d78e8bb to your computer and use it in GitHub Desktop.
Check if crc32 and md5 are affine
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""Affinity test.""" | |
from hashlib import md5 | |
from binascii import crc32 | |
from hypothesis import given | |
from hypothesis.strategies import integers, lists, tuples | |
# In practice, CRC operations are often started with a nonzero state. Because | |
# of this, the actual equation is usually of the form: | |
# crc(a)⊕crc(b)=crc(a⊕b)⊕c | |
# for some constant c (which depends on the length of a, b). | |
# An alternative way of expressing this is, for three any equal-length | |
# bitstrings a,b,ca,b,c, we have: | |
# crc(a)⊕crc(b)⊕crc(c)=crc(a⊕b⊕c) | |
# The technical term for this relationship is affine; in cryptography, we treat | |
# it as linear because, for attacks that assume linearity, affine works just as | |
# well. | |
_bin32 = integers(min_value=0, max_value=2**32 - 1) | |
def crc32i(a): | |
"""crc32 an integer.""" | |
return crc32(a.to_bytes(4, "big")) | |
def md532i(a): | |
"""md5 corresponding to the crc32i, to prove it is not affine.""" | |
d = md5(a.to_bytes(4, "big")).digest() | |
return int.from_bytes(d[:4], "big", signed=True) | |
@given(lists(tuples(_bin32, _bin32), min_size=10)) | |
def test_crc_not_affine(data): | |
"""If crc32 is affine as described above this should fail.""" | |
cl = map(lambda v: crc32i(v[0]) ^ crc32i(v[1]) ^ crc32i(v[0] ^ v[1]), data) | |
# Check if c is constant | |
x = next(cl) | |
assert all(c == x for c in cl) | |
@given(lists(tuples(_bin32, _bin32), min_size=10)) | |
def test_md5_not_affine(data): | |
"""If crc32 is affine as described above this should fail.""" | |
cl = map(lambda v: md532i(v[0]) ^ md532i(v[1]) ^ md532i(v[0] ^ v[1]), data) | |
# Check if c is constant | |
x = next(cl) | |
assert all(c == x for c in cl) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment