Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

32 and 64-bit fletcher checksums are incorrect #2

Open
nolanhergert opened this issue Jul 5, 2022 · 1 comment
Open

32 and 64-bit fletcher checksums are incorrect #2

nolanhergert opened this issue Jul 5, 2022 · 1 comment

Comments

@nolanhergert
Copy link

nolanhergert commented Jul 5, 2022

It seems you aren't alone on the internet either: https://gchq.github.io/CyberChef/#recipe=Fletcher-64_Checksum()&input=YWJjZGVmZ2g (I'll submit an issue for them too)

The easiest way to demonstrate this is with your examples, where the upper 2 bytes (4 nibbles) are all 0's, when they should be filled with data like Wikipedia: https://en.wikipedia.org/wiki/Fletcher%27s_checksum#Test_vectors

The problem is that you are only using byte-sized chunks for the sums instead of uint16 or uint32 chunks, respectively.

Here is an example of a proper implementation:

import array

def get_fletcher64(data_bytes: bytes) -> dict:
    """
    Accepts bytes as input.
    Returns the Fletcher64 checksum value in decimal and hexadecimal format.
    32-bit implementation (64-bit checksum)
    """
    sum1, sum2 = int(), int()
    data = array.array('I', str.encode(data_bytes))
    print(len(data))
    for index in range(len(data)):
        sum1 = (sum1 + data[index]) % 4294967295
        sum2 = (sum2 + sum1) % 4294967295
    result = (sum2 << 32) | sum1
    return {"Fletcher64_dec": result, "Fletcher64_hex": hex(result)}

Which returns the proper value when using the wikipedia test string.

test_string_input = 'abcdefgh'
checksum_result = FletcherChecksumStr.get_fletcher64(test_string_input)
print(checksum_result)
2
{'Fletcher64_dec': 3543817411021686982, 'Fletcher64_hex': '0x312e2b28cccac8c6'}
  • This doesn't work for strings/bytes where the length isn't a multiple of the checksum size,
  • The above is using signed int, and not unsigned int, which will run into overflow issues.

I'll leave the above as an exercise for the reader 😉

@nolanhergert nolanhergert changed the title Your code does not compute correct values for 32 and 64-bit checksums 32 and 64-bit checksums are incorrect Jul 5, 2022
@nolanhergert nolanhergert changed the title 32 and 64-bit checksums are incorrect 32 and 64-bit fletcher checksums are incorrect Jul 5, 2022
@mrx23dot
Copy link

Test vectors from https://en.wikipedia.org/wiki/Fletcher%27s_checksum#Fletcher-64

Fletcher-64

"abcde" -> 14467467625952928454 (0xC8C6C527646362C6)
"abcdef" -> 14467579776138987718 (0xC8C72B276463C8C6)
"abcdefgh" -> 3543817411021686982 (0x312E2B28CCCAC8C6)

Fletcher-32

"abcde" -> 4031760169 (0xF04FC729)
"abcdef" -> 1448095018 (0x56502D2A)
"abcdefgh" -> 3957429649 (0xEBE19591)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants