From f2df61585b6a16e57545546a3d01077d33ca38ba Mon Sep 17 00:00:00 2001 From: /dev/null Date: Wed, 24 Nov 2021 00:02:40 +0000 Subject: [PATCH] Replace old pysha3 with cryptodomex, test on Python 3.10 pysha3 is pretty old and doesn't seem to have any modern Python wheels, so it requires being compiled on Python 3.7 or newer. Cryptodome is more modern and maintained, though larger. --- .travis.yml | 1 + monero/address.py | 2 +- monero/keccak.py | 10 ++++++++++ monero/seed.py | 14 ++++---------- monero/transaction/__init__.py | 6 +++--- monero/wallet.py | 2 +- requirements.txt | 2 +- 7 files changed, 21 insertions(+), 16 deletions(-) create mode 100644 monero/keccak.py diff --git a/.travis.yml b/.travis.yml index d0f42e4..8db2237 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,7 @@ python: - "3.7" - "3.8" - "3.9" + - "3.10" matrix: allow_failures: python: "nightly" diff --git a/monero/address.py b/monero/address.py index 2def4b0..69e193d 100644 --- a/monero/address.py +++ b/monero/address.py @@ -1,6 +1,5 @@ from binascii import hexlify, unhexlify import re -from sha3 import keccak_256 import six import struct import warnings @@ -9,6 +8,7 @@ from . import base58 from . import const from . import ed25519 from . import numbers +from .keccak import keccak_256 _ADDR_REGEX = re.compile(r'^[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{95}$') _IADDR_REGEX = re.compile(r'^[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{106}$') diff --git a/monero/keccak.py b/monero/keccak.py new file mode 100644 index 0000000..5b6e88f --- /dev/null +++ b/monero/keccak.py @@ -0,0 +1,10 @@ +from Cryptodome.Hash import keccak + + +def keccak_256(data): + """ + Return a hashlib-compatible Keccak 256 object for the given data. + """ + hash = keccak.new(digest_bits=256) + hash.update(data) + return hash diff --git a/monero/seed.py b/monero/seed.py index 5601c02..a98ca89 100644 --- a/monero/seed.py +++ b/monero/seed.py @@ -37,10 +37,10 @@ from binascii import hexlify, unhexlify from os import urandom -from sha3 import keccak_256 import warnings from . import base58, const, ed25519, wordlists from .address import address +from .keccak import keccak_256 class Seed(object): """Creates a seed object either from local system randomness or an imported phrase. @@ -124,9 +124,7 @@ class Seed(object): return self.hex def _hex_seed_keccak(self): - h = keccak_256() - h.update(unhexlify(self.hex)) - return h.digest() + return keccak_256(unhexlify(self.hex)).digest() def secret_spend_key(self): a = self._hex_seed_keccak() if self.is_mymonero() else unhexlify(self.hex) @@ -134,9 +132,7 @@ class Seed(object): def secret_view_key(self): b = self._hex_seed_keccak() if self.is_mymonero() else unhexlify(self.secret_spend_key()) - h = keccak_256() - h.update(b) - return self.sc_reduce(h.digest()) + return self.sc_reduce(keccak_256(b).digest()) def public_spend_key(self): if self._ed_pub_spend_key: @@ -164,9 +160,7 @@ class Seed(object): "Invalid net argument '{:s}'. Must be one of monero.const.NET_*".format(net)) netbyte = (18, 53, 24)[const.NETS.index(net)] data = "{:x}{:s}{:s}".format(netbyte, self.public_spend_key(), self.public_view_key()) - h = keccak_256() - h.update(unhexlify(data)) - checksum = h.hexdigest() + checksum = keccak_256(unhexlify(data)).hexdigest() return address(base58.encode(data + checksum[0:8])) diff --git a/monero/transaction/__init__.py b/monero/transaction/__init__.py index 8fc9f54..b323754 100644 --- a/monero/transaction/__init__.py +++ b/monero/transaction/__init__.py @@ -2,7 +2,6 @@ import binascii import itertools import operator import re -import sha3 import six import struct import varint @@ -12,6 +11,7 @@ from ..numbers import from_atomic, PaymentID from .. import ed25519 from .. import exceptions from .extra import ExtraParser +from ..keccak import keccak_256 class Payment(object): """ @@ -138,7 +138,7 @@ class Transaction(object): varint.encode(idx), ] ) - Hs_ur = sha3.keccak_256(hsdata).digest() + Hs_ur = keccak_256(hsdata).digest() # sc_reduce32: Hsint_ur = ed25519.decodeint(Hs_ur) @@ -159,7 +159,7 @@ class Transaction(object): timestamp=self.timestamp, transaction=self, local_address=addr) - amount_hs = sha3.keccak_256(b"amount" + Hs).digest() + amount_hs = keccak_256(b"amount" + Hs).digest() xormask = amount_hs[:len(encamount)] dec_amount = bytearray(a ^ b for a, b in zip(*map(bytearray, (encamount, xormask)))) int_amount = struct.unpack("=1.12.0 ipaddress