From a49aa2ba531207d183dac27303470fa72e4d0031 Mon Sep 17 00:00:00 2001 From: The MMGen Project Date: Tue, 12 Dec 2023 10:19:51 +0000 Subject: [PATCH] keygen.py: forbid use of non-safe public key generation backends While the default generation backends for all public key types are timing safe, a non-safe implementation could be selected manually by the user or automatically as a fallback in the case of a broken installation (e.g. missing libsecp256k1). This patch prevents the use of non-timing-safe backends altogether except when testing. --- mmgen/keygen.py | 7 +++++++ mmgen/proto/secp256k1/keygen.py | 6 ++++++ mmgen/proto/xmr/keygen.py | 7 +++++-- mmgen/proto/zec/keygen.py | 3 +++ 4 files changed, 21 insertions(+), 2 deletions(-) diff --git a/mmgen/keygen.py b/mmgen/keygen.py index 48d8337c..e9b40ccb 100755 --- a/mmgen/keygen.py +++ b/mmgen/keygen.py @@ -32,6 +32,13 @@ keygen_public_data = namedtuple( class keygen_base: + def __init__(self,cfg): + if not (self.production_safe or cfg.test_suite): + from .util import die + die(2, + f'Public key generator {type(self).__name__!r} is not safe from timing attacks ' + 'and may only be used in a testing environment') + def gen_data(self,privkey): assert isinstance(privkey,PrivKey) return keygen_public_data( diff --git a/mmgen/proto/secp256k1/keygen.py b/mmgen/proto/secp256k1/keygen.py index c48bb034..5e305661 100755 --- a/mmgen/proto/secp256k1/keygen.py +++ b/mmgen/proto/secp256k1/keygen.py @@ -19,7 +19,10 @@ class backend: class libsecp256k1(keygen_base): + production_safe = True + def __init__(self,cfg): + super().__init__(cfg) # catch ImportError to satisfy pylint when testing repo with unbuilt secp256k1 extension mod: try: from .secp256k1 import priv2pub @@ -51,7 +54,10 @@ class backend: class python_ecdsa(keygen_base): + production_safe = False + def __init__(self,cfg): + super().__init__(cfg) import ecdsa self.ecdsa = ecdsa diff --git a/mmgen/proto/xmr/keygen.py b/mmgen/proto/xmr/keygen.py index ef5c227c..c7d74dcc 100755 --- a/mmgen/proto/xmr/keygen.py +++ b/mmgen/proto/xmr/keygen.py @@ -20,10 +20,9 @@ class backend: class base(keygen_base): def __init__(self,cfg): - + super().__init__(cfg) from ...proto.xmr.params import mainnet self.proto_cls = mainnet - from ...util2 import get_keccak self.keccak_256 = get_keccak(cfg) @@ -35,6 +34,8 @@ class backend: class nacl(base): + production_safe = True + def __init__(self,cfg): super().__init__(cfg) from nacl.bindings import crypto_scalarmult_ed25519_base_noclamp @@ -49,6 +50,8 @@ class backend: class ed25519(base): + production_safe = False + def __init__(self,cfg): super().__init__(cfg) from ...contrib.ed25519 import edwards,encodepoint,B,scalarmult diff --git a/mmgen/proto/zec/keygen.py b/mmgen/proto/zec/keygen.py index 69798aef..61cf42b9 100755 --- a/mmgen/proto/zec/keygen.py +++ b/mmgen/proto/zec/keygen.py @@ -19,7 +19,10 @@ class backend: class nacl(keygen_base): + production_safe = True + def __init__(self,cfg): + super().__init__(cfg) from nacl.bindings import crypto_scalarmult_base self.crypto_scalarmult_base = crypto_scalarmult_base from ...sha2 import Sha256