diff --git a/tests/test_ciphers.py b/tests/test_ciphers.py index 2cbd483..22ac14a 100644 --- a/tests/test_ciphers.py +++ b/tests/test_ciphers.py @@ -25,6 +25,7 @@ import pytest from wolfcrypt._ffi import lib as _lib from wolfcrypt.ciphers import MODE_CTR, MODE_ECB, MODE_CBC, WolfCryptError +from wolfcrypt.random import Random from wolfcrypt.utils import t2b, h2b import os @@ -613,11 +614,12 @@ def test_ecc_sign_verify_raw(ecc_private, ecc_public): def test_ecc_make_shared_secret(): - a = EccPrivate.make_key(32) + rng = Random() + a = EccPrivate.make_key(32, rng=rng) a_pub = EccPublic() a_pub.import_x963(a.export_x963()) - b = EccPrivate.make_key(32) + b = EccPrivate.make_key(32, rng=rng) b_pub = EccPublic() b_pub.import_x963(b.export_x963()) @@ -626,6 +628,13 @@ def test_ecc_make_shared_secret(): == a.shared_secret(b_pub) \ == b.shared_secret(a_pub) + def test_ecc_make_key_no_rng(): + key = EccPrivate.make_key(32) + pub_key = EccPublic() + pub_key.import_x963(key.export_x963()) + + assert key.shared_secret(pub_key) + if _lib.ED25519_ENABLED: @pytest.fixture def ed25519_private(vectors): diff --git a/wolfcrypt/ciphers.py b/wolfcrypt/ciphers.py index 8fa304b..b256e33 100644 --- a/wolfcrypt/ciphers.py +++ b/wolfcrypt/ciphers.py @@ -824,10 +824,12 @@ def verify_pss(self, plaintext, signature): class RsaPrivate(RsaPublic): if _lib.KEYGEN_ENABLED: @classmethod - def make_key(cls, size, rng=Random(), hash_type=None): + def make_key(cls, size, rng=None, hash_type=None): """ Generates a new key pair of desired length **size**. """ + if rng is None: + rng = Random() rsa = cls(hash_type=hash_type) ret = _lib.wc_MakeRsaKey(rsa.native_object, size, 65537, @@ -1182,21 +1184,27 @@ def verify_raw(self, R, S, data): class EccPrivate(EccPublic): + + def __init__(self, key=None, rng=None): + super().__init__(key) + if rng is None: + rng = Random() + self._rng = rng + @classmethod - def make_key(cls, size, rng=Random()): + def make_key(cls, size, rng=None): """ Generates a new key pair of desired length **size**. """ - ecc = cls() - - ret = _lib.wc_ecc_make_key(rng.native_object, size, + ecc = cls(rng=rng) + ret = _lib.wc_ecc_make_key(ecc._rng.native_object, size, ecc.native_object) if ret < 0: raise WolfCryptError("Key generation error (%d)" % ret) if _lib.ECC_TIMING_RESISTANCE_ENABLED and (not _lib.FIPS_ENABLED or _lib.FIPS_VERSION > 2): - ret = _lib.wc_ecc_set_rng(ecc.native_object, rng.native_object) + ret = _lib.wc_ecc_set_rng(ecc.native_object, ecc._rng.native_object) if ret < 0: raise WolfCryptError("Error setting ECC RNG (%d)" % ret) @@ -1289,12 +1297,14 @@ def shared_secret(self, peer): return _ffi.buffer(shared_secret, secret_size[0])[:] - def sign(self, plaintext, rng=Random()): + def sign(self, plaintext, rng=None): """ Signs **plaintext**, using the private key data in the object. Returns the signature. """ + if rng is None: + rng = Random() plaintext = t2b(plaintext) signature = _ffi.new("byte[%d]" % self.max_signature_size) @@ -1312,12 +1322,14 @@ def sign(self, plaintext, rng=Random()): return _ffi.buffer(signature, signature_size[0])[:] if _lib.MPAPI_ENABLED: - def sign_raw(self, plaintext, rng=Random()): + def sign_raw(self, plaintext, rng=None): """ Signs **plaintext**, using the private key data in the object. Returns the signature in its two raw components r, s """ + if rng is None: + rng = Random() plaintext = t2b(plaintext) R = _ffi.new("mp_int[1]") S = _ffi.new("mp_int[1]") @@ -1449,10 +1461,12 @@ def __init__(self, key=None, pub=None): self.decode_key(key,pub) @classmethod - def make_key(cls, size, rng=Random()): + def make_key(cls, size, rng=None): """ Generates a new key pair of desired length **size**. """ + if rng is None: + rng = Random() ed25519 = cls() ret = _lib.wc_ed25519_make_key(rng.native_object, size, @@ -1645,10 +1659,12 @@ def __init__(self, key=None, pub=None): self.decode_key(key,pub) @classmethod - def make_key(cls, size, rng=Random()): + def make_key(cls, size, rng=None): """ Generates a new key pair of desired length **size**. """ + if rng is None: + rng = Random() ed448 = cls() ret = _lib.wc_ed448_make_key(rng.native_object, size, @@ -1862,13 +1878,15 @@ def decode_key(self, pub_key): if ret < 0: # pragma: no cover raise WolfCryptError("wc_KyberKey_DecodePublicKey() error (%d)" % ret) - def encapsulate(self, rng=Random()): + def encapsulate(self, rng=None): """ :param rng: random number generator for an encupsulation :type rng: Random :return: tuple of a shared secret (first element) and the cipher text (second element) :rtype: tuple[bytes, bytes] """ + if rng is None: + rng = Random() ct_size = self.ct_size ss_size = self.ss_size ct = _ffi.new(f"unsigned char[{ct_size}]") @@ -1906,7 +1924,7 @@ def encapsulate_with_random(self, rand): class MlKemPrivate(_MlKemBase): @classmethod - def make_key(cls, mlkem_type, rng=Random()): + def make_key(cls, mlkem_type, rng=None): """ :param mlkem_type: ML-KEM type :type mlkem_type: MlKemType @@ -1915,6 +1933,8 @@ def make_key(cls, mlkem_type, rng=Random()): :return: `MlKemPrivate` object :rtype: MlKemPrivate """ + if rng is None: + rng = Random() mlkem_priv = cls(mlkem_type) ret = _lib.wc_KyberKey_MakeKey(mlkem_priv.native_object, rng.native_object) @@ -2150,7 +2170,7 @@ def verify(self, signature, message): class MlDsaPrivate(_MlDsaBase): @classmethod - def make_key(cls, mldsa_type, rng=Random()): + def make_key(cls, mldsa_type, rng=None): """ :param mldsa_type: ML-DSA type :type mldsa_type: MlDsaType @@ -2159,6 +2179,8 @@ def make_key(cls, mldsa_type, rng=Random()): :return: `MlDsaPrivate` object :rtype: MlDsaPrivate """ + if rng is None: + rng = Random() mldsa_priv = cls(mldsa_type) ret = _lib.wc_dilithium_make_key( mldsa_priv.native_object, rng.native_object @@ -2243,7 +2265,7 @@ def decode_key(self, priv_key, pub_key=None): if pub_key is not None: self._decode_pub_key(pub_key) - def sign(self, message, rng=Random()): + def sign(self, message, rng=None): """ :param message: message to be signed :type message: bytes or str @@ -2252,6 +2274,8 @@ def sign(self, message, rng=Random()): :return: signature :rtype: bytes """ + if rng is None: + rng = Random() msg_bytestype = t2b(message) in_size = self.sig_size signature = _ffi.new(f"byte[{in_size}]")