Skip to content

Conversation

@sipa
Copy link
Member

@sipa sipa commented Dec 8, 2021

Closes #23710.

@sipa sipa force-pushed the 202112_ripemd160 branch from cdfaa53 to 5b559dc Compare December 8, 2021 19:30
@laanwj laanwj added the Tests label Dec 8, 2021
@jamesob
Copy link
Contributor

jamesob commented Dec 8, 2021

ACK 5b559dc, pending CI

Verified test vectors match my system's ripemd160 installation. Did not review the actual crypto.

# Copyright (c) 2021 Pieter Wuille
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test-only pure Python RIPEMD160 implementation."""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What makes this inherently test-only?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not constant time.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO should be mentioned in the comment.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's indeed a good warning to add in a followup.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not constant time.

Given that its only use in Bitcoin is ripemd160(sha256(data)), does this not make a timing attack effectively useless?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mmgen Yes, but it's open-source code, and open-source code gets copied and can end up being adopted for other purposes.

@maflcko
Copy link
Member

maflcko commented Dec 9, 2021

After merge there will be one other remaining use of new(). (git grep 'hashlib.new'). Since it is discouraged in the python docs, we should replace that with the named constructor.

Going to merge this for our CI, but I plan to review after merge.

Copy link
Member

@maflcko maflcko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good and given that there are tests, this is probably correct. Left a nit to show that I read the code.

for b in range(len(data) >> 6):
state = compress(*state, data[64*b:64*(b+1)])
# Construct final blocks (with padding and size).
pad = b"\x80" + b"\x00" * ((119 - len(data)) & 63)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: using the & operator is a slightly odd way to change the sign of an integer, no?

Might be better written as (119 - len&63) & 63 ?

See also https://docs.python.org/3/library/stdtypes.html#bitwise-operations-on-integer-types

Performing these calculations with at least one extra sign extension bit in a finite two’s complement representation (a working bit-width of 1 + max(x.bit_length(), y.bit_length()) or more) is sufficient to get the same result as if there were an infinite number of sign bits.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm happy to change it, but "& 63" is exactly the same as "% 64" but faster, and that should be sufficient here.

Copy link
Member

@maflcko maflcko Dec 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh it is fine. I was just commenting that &63 also changes the sign from negative to positive.

For example if the size is 172, then 119-172 will be negative and &63 will make it positive.

Edit: I checked that the two do the same:

>>> all([  (119-i)&63==(119-i&63)&63  for i in range(1000000) ])
True

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the result of & is only negative if both inputs are negative.

@richardkiss
Copy link
Contributor

Thanks for this! I've ported to python 2 and integrated into pycoin here richardkiss/pycoin@6b3e4bb

@fanquake
Copy link
Member

fanquake commented Jul 6, 2022

Backported to 0.21 in #25538. 22.0 in #25250.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

test: Openssl removed ripemd160

9 participants