Last active
May 9, 2024 08:09
-
-
Save 8051Enthusiast/80c044b3a6f6ad145617eebe11eb9fb1 to your computer and use it in GitHub Desktop.
This file contains 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
# matrix from the `a^i` generator basis to the `a^(-2^i)` normal basis | |
to_normal = [0x7f50f7fd, 0x95ecaead, 0x495ffebe, 0x90618596, 0x6e0d0395, 0x527b6ec5, 0x563d1cac, 0x1ee02779, | |
0x287efd13, 0x5a66f53c, 0xdf3df773, 0xa0d25f82, 0x79357a5b, 0xe5c59050, 0x15508e51, 0x498da844, | |
0xcaf65756, 0x4830c2cb, 0xa93db762, 0x8f7013bc, 0x2d337a9e, 0x50692fc1, 0x72e2c828, 0x24c6d422, | |
0xa4186165, 0x47b809de, 0xa83497e0, 0x12636a11, 0x23dc04ef, 0x8931b508, 0x4498da84, 0xffffffff] | |
# inverse of to_normal | |
from_normal = [0xdb710641, 0x6d930ac3, 0x6d3d2d4d, 0x6567cb95, 0xd7125358, 0x5b358fd3, 0x2e9bb40b, 0x12a59a49, | |
0x8df9403d, 0x5139de12, 0xba340226, 0x29c45641, 0x12fbc105, 0xecd30c55, 0x3755ebd8, 0x24ee460c, | |
0x23783fcf, 0x479933fc, 0xa39442a5, 0x9ea0056d, 0xf42608f6, 0x20cacf04, 0x2a0cf83d, 0xeffd8645, | |
0x2a39a67d, 0x640ebd82, 0x9dfd8792, 0x277402ab, 0xad31bc4f, 0x31536354, 0x5ea35fca, 0x52b55e39] | |
# multiplication by a in the normal basis | |
shift = [0xffffffff, 0x00000001, 0x94397e07, 0xa61f509a, 0xa5e6fdbb, 0xcebff8ed, 0x8c596f2f, 0x22e9c80d, | |
0xbbab17bd, 0xef34b18b, 0x3fb74ec0, 0x33fa9bbf, 0xf4770a92, 0x6ecfe923, 0x9506c497, 0x0b497ad5, | |
0xa68938da, 0x9a9596e9, 0xa144fe2c, 0x75e642f6, 0xdbf0bde6, 0xb4206bbb, 0x8976cdf0, 0x9aab05a2, | |
0x90c19016, 0xb8cfff29, 0x755d666f, 0xebfa87bf, 0x6caf6575, 0xb4830c2c, 0xc8f7013b, 0x224c6d42] | |
# applies matrix bitwise to n | |
def apply(matrix, n): | |
ret = 0 | |
for i in range(32): | |
if n & (1 << i): | |
ret ^= matrix[i] | |
return ret | |
def shift_bytes(sum, count): | |
# crc32 has a blocksize of 2^32 - 1, and we multiply by 8 to get the bit count | |
count = (count * 8) % 0xFFFFFFFF | |
ret = apply(to_normal, sum) | |
# basically exponentiation by squaring | |
for i in range(32): | |
if count & (1 << i): | |
ret = apply(shift, ret) | |
ret = (ret >> 1) | (ret << 31) | |
return apply(from_normal, ret) | |
# takes a zlib checksum and a count of bytes, and returns the checksum | |
# of the data with the given number of `0xff` bytes appended. | |
# example usage: `append_crc32_ff(zlib.crc32(b'hello'), 3)` will return the | |
# checksum of `b'hello\xff\xff\xff'` | |
def append_crc32_ff(sum, count): | |
# corresponds to 1 / (a + 1) | |
offset = 0x492f023f | |
return shift_bytes(sum ^ offset, count) ^ offset | |
This file contains 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
# matrix from the `a^i` generator basis to the `a^(-2^i)` normal basis | |
from_normal = [0x82608edb, 0xc350c9b6, 0xb2b4bcb6, 0xa9d3e6a6, 0x1aca48eb, 0xcbf1acda, 0xd02dd974, 0x9259a548, | |
0xbc029fb1, 0x487b9c8a, 0x64402c5d, 0x826a2394, 0xa083df48, 0xaa30cb37, 0x1bd7aaec, 0x30627724, | |
0xf3fc1ec4, 0x3fcc99e2, 0xa54229c5, 0xb6a00579, 0x6f10642f, 0x20f35304, 0xbc1f3054, 0xa261bff7, | |
0xbe659c54, 0x41bd7026, 0x49e1bfb9, 0xd5402ee4, 0xf23d8cb5, 0x2ac6ca8c, 0x53fac57a, 0x9c7aad4a] | |
# inverse of from_normal | |
to_normal = [0xffffffff, 0x4498da84, 0x8931b508, 0x23dc04ef, 0x12636a11, 0xa83497e0, 0x47b809de, 0xa4186165, | |
0x24c6d422, 0x72e2c828, 0x50692fc1, 0x2d337a9e, 0x8f7013bc, 0xa93db762, 0x4830c2cb, 0xcaf65756, | |
0x498da844, 0x15508e51, 0xe5c59050, 0x79357a5b, 0xa0d25f82, 0xdf3df773, 0x5a66f53c, 0x287efd13, | |
0x1ee02779, 0x563d1cac, 0x527b6ec5, 0x6e0d0395, 0x90618596, 0x495ffebe, 0x95ecaead, 0x7f50f7fd] | |
# multiplication by a in the normal basis | |
shift = [0xffffffff, 0x00000001, 0x94397e07, 0xa61f509a, 0xa5e6fdbb, 0xcebff8ed, 0x8c596f2f, 0x22e9c80d, | |
0xbbab17bd, 0xef34b18b, 0x3fb74ec0, 0x33fa9bbf, 0xf4770a92, 0x6ecfe923, 0x9506c497, 0x0b497ad5, | |
0xa68938da, 0x9a9596e9, 0xa144fe2c, 0x75e642f6, 0xdbf0bde6, 0xb4206bbb, 0x8976cdf0, 0x9aab05a2, | |
0x90c19016, 0xb8cfff29, 0x755d666f, 0xebfa87bf, 0x6caf6575, 0xb4830c2c, 0xc8f7013b, 0x224c6d42] | |
# applies matrix bitwise to n | |
def apply(matrix, n): | |
ret = 0 | |
for i in range(32): | |
if n & (1 << i): | |
ret ^= matrix[i] | |
return ret | |
def shift_bytes(sum, count): | |
# crc32 has a blocksize of 2^32 - 1, and we multiply by 8 to get the bit count | |
count = (count * 8) % 0xFFFFFFFF | |
ret = apply(to_normal, sum) | |
# basically exponentiation by squaring | |
for i in range(32): | |
if count & (1 << i): | |
ret = apply(shift, ret) | |
ret = (ret >> 1) | (ret << 31) | |
return apply(from_normal, ret) | |
# takes a reflected crc32 and a count of bytes, and returns the checksum | |
# of the data with the given number of `0xff` bytes appended | |
def append_crc32_ff(sum, count): | |
# corresponds to crc([0xff]) / (a^8 + 1) | |
offset = 0xfc40f492 | |
return shift_bytes(sum ^ offset, count) ^ offset |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment