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.
This commit is contained in:
The MMGen Project 2023-12-12 10:19:51 +00:00
commit a49aa2ba53
Signed by: mmgen
GPG key ID: 3F8B1861E32B7DA2
4 changed files with 21 additions and 2 deletions

View file

@ -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(

View file

@ -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

View file

@ -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

View file

@ -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