python-sha-256 icon indicating copy to clipboard operation
python-sha-256 copied to clipboard

Left-shift operation in Python is different from the one defined in NIST.FIPS.180-4.pdf

Open yuttai opened this issue 2 years ago • 0 comments

Left-shift operation is discribed in NIST.FIPS.180-4.pdf as follow:

2.2.2 Symbols and Operations The following symbols are used in the secure hash algorithm specifications; each operates on w- bit words. << Left-shift operation, where x << n is obtained by discarding the left-most n bits of the word x and then padding the result with n zeroes on the right.

In contrast, Python integers are unbounded and the left-shift operator never discards bits. For example, (2 ** 63) << 63 == 2 ** 126 in Python. As the result, the following code def _rotate_right(num: int, shift: int, size: int = 32): """Rotate an integer right.""" return (num >> shift) | (num << size - shift) doesn't really rotate num. Instead, it might result an integer equal or larger than 2 ** 32...

Although the code doesn't literally match the computation specified in NIST.FIPS.180-4.pdf, generate_hash still computes the SHA-256 hash because ^ (num >> 3) in _sigma0, ^ (num >> 10) in _sigma1, and two % 2**32 in t loop in generate_hash trim extra bits, and we might think the code is optimized to reduced the number of % operator. I still think it might be better to explicitly state this in the document string of _rotate_right, and update it to something like """Rotate an integer right for lower 32-bits.""" . Another approach is adding an % 2**32 in _rotate_right to explicitly trim extra bits...

yuttai avatar Aug 21 '23 13:08 yuttai