Legrandin / pycryptodome

A self-contained cryptographic library for Python
https://www.pycryptodome.org
Other
2.74k stars 492 forks source link

TupleHash.update() raises TypeError when passed a tuple of byte strings #767

Closed jelaiw closed 9 months ago

jelaiw commented 9 months ago

When trying the new TupleHash.update() feature (described in the Changelog for version 3.19.0), specifically the code example at https://www.pycryptodome.org/src/hash/tuplehash128 where a tuple of byte strings is passed, a TypeError is raised.

$ python
Python 3.10.8 (main, Sep 13 2023, 16:52:46) [GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from Crypto.Hash import TupleHash128
>>> hd = TupleHash128.new(digest_bytes=16)
>>> hd.update((b'deposit', b'100', b'joe'))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/python/3.10.8/lib/python3.10/site-packages/Crypto/Hash/TupleHash128.py", line 66, in update
    raise TypeError("You can only call 'update' on bytes" )
TypeError: You can only call 'update' on bytes
>>> 

Based on the code examples in the docs, a hex digest of 4c095be894c21cfe7076a7d0fe3f70ed is expected.

jelaiw commented 9 months ago

Ok, after poking around a bit and playing with the unit test, I think I understand what is going on. Before I submit a patch for consideration, is the intent for update() to take a variable length data argument, like so:

$ python
Python 3.10.8 (main, Sep 13 2023, 16:52:46) [GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from Crypto.Hash import TupleHash128
>>> hd = TupleHash128.new(digest_bytes=16)
>>> hd.update(b'deposit', b'100', b'joe')
<Crypto.Hash.TupleHash128.TupleHash object at 0x7f2a74ebbc10>
>>> print(hd.hexdigest())
4c095be894c21cfe7076a7d0fe3f70ed
>>> 

Or do you actually want to support passing an actual list/tuple of byte strings to update() (as is shown in the code example)?

Legrandin commented 9 months ago

Indeed the docs were outdated: they are ok now. Thanks for flagging. The intention is that something can do:

hd.update(b'deposit', b'100', b'joe')

or:

 t = b'deposit', b'100', b'joe'
 hd.update(*t)