Merge branch 'master' into ml-dsa-generate-from-seed
commit
90f21e1d13
|
|
@ -26,7 +26,6 @@ from contextlib import contextmanager
|
|||
from distutils.util import get_platform
|
||||
from cffi import FFI
|
||||
import shutil
|
||||
import glob
|
||||
from wolfcrypt._version import __wolfssl_version__ as version
|
||||
|
||||
def local_path(path):
|
||||
|
|
@ -332,7 +331,7 @@ def get_features(local_wolfssl, features):
|
|||
|
||||
for d in include_dirs:
|
||||
if not os.path.exists(d):
|
||||
e = "Invalid wolfSSL include dir: .".format(d)
|
||||
e = f"Invalid wolfSSL include dir: {d}"
|
||||
raise FileNotFoundError(e)
|
||||
|
||||
options = os.path.join(d, "wolfssl", "options.h")
|
||||
|
|
@ -543,6 +542,8 @@ def build_ffi(local_wolfssl, features):
|
|||
typedef struct { ...; } OS_Seed;
|
||||
|
||||
int wc_InitRng(WC_RNG*);
|
||||
int wc_InitRngNonce(WC_RNG*, byte*, word32);
|
||||
int wc_InitRngNonce_ex(WC_RNG*, byte*, word32, void*, int);
|
||||
int wc_RNG_GenerateBlock(WC_RNG*, byte*, word32);
|
||||
int wc_RNG_GenerateByte(WC_RNG*, byte*);
|
||||
int wc_FreeRng(WC_RNG*);
|
||||
|
|
@ -1032,6 +1033,8 @@ def build_ffi(local_wolfssl, features):
|
|||
int wc_dilithium_export_public(dilithium_key* key, byte* out, word32* outLen);
|
||||
int wc_dilithium_import_public(const byte* in, word32 inLen, dilithium_key* key);
|
||||
int wc_dilithium_sign_msg(const byte* msg, word32 msgLen, byte* sig, word32* sigLen, dilithium_key* key, WC_RNG* rng);
|
||||
int wc_dilithium_sign_msg_with_seed(const byte* msg, word32 msgLen, byte* sig, word32* sigLen, dilithium_key* key, const byte* seed);
|
||||
int wc_dilithium_sign_ctx_msg_with_seed(const byte* ctx, byte ctxLen, const byte* msg, word32 msgLen, byte* sig, word32* sigLen, dilithium_key* key, const byte* seed);
|
||||
int wc_dilithium_verify_msg(const byte* sig, word32 sigLen, const byte* msg, word32 msgLen, int* res, dilithium_key* key);
|
||||
typedef dilithium_key MlDsaKey;
|
||||
int wc_MlDsaKey_GetPrivLen(MlDsaKey* key, int* len);
|
||||
|
|
|
|||
2
setup.py
2
setup.py
|
|
@ -22,12 +22,12 @@
|
|||
# pylint: disable=wrong-import-position
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
os.chdir(os.path.dirname(sys.argv[0]) or ".")
|
||||
|
||||
import re
|
||||
VERSIONFILE = "wolfcrypt/_version.py"
|
||||
verstrline = open(VERSIONFILE, "rt").read()
|
||||
VSRE = r"^__version__ = ['\"]([^'\"]*)['\"]"
|
||||
|
|
|
|||
|
|
@ -23,11 +23,10 @@
|
|||
from wolfcrypt._ffi import lib as _lib
|
||||
|
||||
if _lib.AESGCM_STREAM_ENABLED:
|
||||
from collections import namedtuple
|
||||
import pytest
|
||||
from wolfcrypt.utils import t2b
|
||||
from wolfcrypt.exceptions import WolfCryptError
|
||||
from binascii import hexlify as b2h, unhexlify as h2b
|
||||
from binascii import hexlify as b2h
|
||||
from wolfcrypt.ciphers import AesGcmStream
|
||||
|
||||
def test_encrypt():
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ if _lib.CHACHA20_POLY1305_ENABLED:
|
|||
import pytest
|
||||
from wolfcrypt.utils import t2b
|
||||
from wolfcrypt.exceptions import WolfCryptError
|
||||
from binascii import hexlify as b2h, unhexlify as h2b
|
||||
from binascii import unhexlify as h2b
|
||||
from wolfcrypt.ciphers import ChaCha20Poly1305
|
||||
|
||||
def test_encrypt_decrypt():
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@
|
|||
from collections import namedtuple
|
||||
import random
|
||||
import pytest
|
||||
from wolfcrypt._ffi import ffi as _ffi
|
||||
from wolfcrypt._ffi import lib as _lib
|
||||
from wolfcrypt.ciphers import MODE_CTR, MODE_ECB, MODE_CBC, WolfCryptError
|
||||
from wolfcrypt.utils import t2b, h2b
|
||||
import os
|
||||
|
||||
|
|
@ -43,20 +43,16 @@ if _lib.CHACHA_ENABLED:
|
|||
from wolfcrypt.ciphers import ChaCha
|
||||
|
||||
if _lib.RSA_ENABLED:
|
||||
from wolfcrypt.ciphers import (RsaPrivate, RsaPublic, HASH_TYPE_SHA256, MGF1SHA256, HASH_TYPE_SHA, MGF1SHA1)
|
||||
from wolfcrypt.ciphers import RsaPrivate, RsaPublic, HASH_TYPE_SHA256, HASH_TYPE_SHA
|
||||
|
||||
if _lib.ECC_ENABLED:
|
||||
from wolfcrypt.ciphers import (EccPrivate, EccPublic)
|
||||
from wolfcrypt.ciphers import EccPrivate, EccPublic
|
||||
|
||||
if _lib.ED25519_ENABLED:
|
||||
from wolfcrypt.ciphers import (Ed25519Private, Ed25519Public)
|
||||
from wolfcrypt.ciphers import Ed25519Private, Ed25519Public
|
||||
|
||||
if _lib.ED448_ENABLED:
|
||||
from wolfcrypt.ciphers import (Ed448Private, Ed448Public)
|
||||
|
||||
from wolfcrypt.ciphers import (
|
||||
MODE_CTR, MODE_ECB, MODE_CBC, WolfCryptError
|
||||
)
|
||||
from wolfcrypt.ciphers import Ed448Private, Ed448Public
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@
|
|||
|
||||
from collections import namedtuple
|
||||
import pytest
|
||||
from wolfcrypt._ffi import ffi as _ffi
|
||||
from wolfcrypt._ffi import lib as _lib
|
||||
from wolfcrypt.utils import t2b
|
||||
|
||||
|
|
|
|||
|
|
@ -24,8 +24,7 @@ from wolfcrypt._ffi import lib as _lib
|
|||
|
||||
if _lib.ML_DSA_ENABLED:
|
||||
import pytest
|
||||
|
||||
from wolfcrypt.ciphers import MlDsaPrivate, MlDsaPublic, MlDsaType, ML_DSA_KEYGEN_SEED_LENGTH
|
||||
from wolfcrypt.ciphers import MlDsaPrivate, MlDsaPublic, MlDsaType, ML_DSA_KEYGEN_SEED_LENGTH, ML_DSA_SIGNATURE_SEED_LENGTH
|
||||
from wolfcrypt.random import Random
|
||||
|
||||
@pytest.fixture
|
||||
|
|
@ -135,9 +134,9 @@ if _lib.ML_DSA_ENABLED:
|
|||
wrong_message = b"This is a wrong message for ML-DSA signature"
|
||||
assert not mldsa_pub.verify(signature, wrong_message)
|
||||
|
||||
def test_generate_from_seed(mldsa_type, rng):
|
||||
private_key_seed = rng.bytes(ML_DSA_KEYGEN_SEED_LENGTH)
|
||||
mldsa_priv = MlDsaPrivate.make_key_from_seed(mldsa_type, private_key_seed)
|
||||
def test_sign_with_seed(mldsa_type, rng):
|
||||
signature_seed = rng.bytes(ML_DSA_SIGNATURE_SEED_LENGTH)
|
||||
mldsa_priv = MlDsaPrivate.make_key(mldsa_type, rng)
|
||||
pub_key = mldsa_priv.encode_pub_key()
|
||||
|
||||
# Import public key
|
||||
|
|
@ -146,22 +145,38 @@ if _lib.ML_DSA_ENABLED:
|
|||
|
||||
# Sign a message
|
||||
message = b"This is a test message for ML-DSA signature"
|
||||
signature = mldsa_priv.sign(message, rng)
|
||||
signature = mldsa_priv.sign_with_seed(message, signature_seed)
|
||||
assert len(signature) == mldsa_priv.sig_size
|
||||
|
||||
# Verify the signature using public key
|
||||
assert mldsa_pub.verify(signature, message)
|
||||
|
||||
# re-generate from the same seed:
|
||||
mldsa_priv_regenerated = MlDsaPrivate.make_key_from_seed(mldsa_type, private_key_seed)
|
||||
assert mldsa_priv_regenerated.encode_priv_key() == mldsa_priv.encode_priv_key()
|
||||
assert mldsa_priv_regenerated.encode_pub_key() == mldsa_priv.encode_pub_key()
|
||||
signature_from_same_seed = mldsa_priv.sign_with_seed(message, signature_seed)
|
||||
assert signature == signature_from_same_seed
|
||||
|
||||
# test that the seed length is checked:
|
||||
# test that the seed size is checked:
|
||||
with pytest.raises(ValueError):
|
||||
mldsa_priv = MlDsaPrivate.make_key_from_seed(mldsa_type, bytes(ML_DSA_KEYGEN_SEED_LENGTH - 1))
|
||||
with pytest.raises(ValueError):
|
||||
mldsa_priv = MlDsaPrivate.make_key_from_seed(mldsa_type, bytes(ML_DSA_KEYGEN_SEED_LENGTH + 1))
|
||||
# test that the seed type is checked (should be bytes-like, not a string)
|
||||
_ = mldsa_priv.sign_with_seed(message, signature_seed[:-1])
|
||||
|
||||
# test that the seed type is checked (should be bytes-like, not string)
|
||||
with pytest.raises(TypeError):
|
||||
mldsa_priv = MlDsaPrivate.make_key_from_seed(mldsa_type, 'a' * ML_DSA_KEYGEN_SEED_LENGTH)
|
||||
_ = mldsa_priv.sign_with_seed(message, "")
|
||||
|
||||
def test_sign_with_seed_and_context(mldsa_type, rng):
|
||||
signature_seed = rng.bytes(ML_DSA_SIGNATURE_SEED_LENGTH)
|
||||
mldsa_priv = MlDsaPrivate.make_key(mldsa_type, rng)
|
||||
pub_key = mldsa_priv.encode_pub_key()
|
||||
|
||||
# Import public key
|
||||
mldsa_pub = MlDsaPublic(mldsa_type)
|
||||
mldsa_pub.decode_key(pub_key)
|
||||
|
||||
# Sign a message
|
||||
message = b"This is a test message for ML-DSA signature"
|
||||
context = b"Some context for the signature"
|
||||
signature = mldsa_priv.sign_with_seed(message, signature_seed, ctx=context)
|
||||
assert len(signature) == mldsa_priv.sig_size
|
||||
# test that the context length is checked (more than 255 bytes is invalid):
|
||||
with pytest.raises(ValueError):
|
||||
_ = mldsa_priv.sign_with_seed(message, signature_seed[:-1], ctx=bytes(1000))
|
||||
|
|
|
|||
|
|
@ -37,3 +37,14 @@ def test_bytes(rng):
|
|||
assert len(rng.bytes(1)) == 1
|
||||
assert len(rng.bytes(8)) == 8
|
||||
assert len(rng.bytes(128)) == 128
|
||||
|
||||
@pytest.fixture
|
||||
def rng_nonce():
|
||||
return Random(b"abcdefghijklmnopqrstuv")
|
||||
|
||||
def test_nonce_byte(rng_nonce):
|
||||
assert len(rng_nonce.byte()) == 1
|
||||
|
||||
@pytest.mark.parametrize("length", (1, 8, 128))
|
||||
def test_nonce_bytes(rng_nonce, length):
|
||||
assert len(rng_nonce.bytes(length)) == length
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ top_level_py = os.path.basename(sys.argv[0])
|
|||
if top_level_py not in ["setup.py", "build_ffi.py"]:
|
||||
from wolfcrypt._ffi import ffi as _ffi
|
||||
from wolfcrypt._ffi import lib as _lib
|
||||
from wolfcrypt.exceptions import WolfCryptError
|
||||
|
||||
if hasattr(_lib, 'WC_RNG_SEED_CB_ENABLED'):
|
||||
if _lib.WC_RNG_SEED_CB_ENABLED:
|
||||
|
|
@ -53,8 +54,7 @@ if top_level_py not in ["setup.py", "build_ffi.py"]:
|
|||
if ret < 0:
|
||||
raise WolfCryptError("wc_SetSeed_Cb failed (%d)" % ret)
|
||||
if _lib.FIPS_ENABLED and _lib.FIPS_VERSION >= 5:
|
||||
ret = _lib.wolfCrypt_SetPrivateKeyReadEnable_fips(1,
|
||||
_lib.WC_KEYTYPE_ALL);
|
||||
ret = _lib.wolfCrypt_SetPrivateKeyReadEnable_fips(1, _lib.WC_KEYTYPE_ALL)
|
||||
if ret < 0:
|
||||
raise WolfCryptError("wolfCrypt_SetPrivateKeyReadEnable_fips failed"
|
||||
" (%d)" % ret)
|
||||
|
|
|
|||
|
|
@ -213,10 +213,9 @@ class _Cipher(object):
|
|||
string = t2b(string)
|
||||
|
||||
if not string:
|
||||
raise ValueError(
|
||||
"empty string not allowed")
|
||||
raise ValueError("empty string not allowed")
|
||||
|
||||
if len(string) % self.block_size and not self.mode == MODE_CTR and not "ChaCha" in self._native_type:
|
||||
if len(string) % self.block_size and self.mode != MODE_CTR and "ChaCha" not in self._native_type:
|
||||
raise ValueError(
|
||||
"string must be a multiple of %d in length" % self.block_size)
|
||||
|
||||
|
|
@ -498,7 +497,7 @@ if _lib.CHACHA_ENABLED:
|
|||
self._dec = None
|
||||
self._key = None
|
||||
if len(key) > 0:
|
||||
if not size in self._key_sizes:
|
||||
if size not in self._key_sizes:
|
||||
raise ValueError("Invalid key size %d" % size)
|
||||
self._key = t2b(key)
|
||||
self.key_size = size
|
||||
|
|
@ -506,7 +505,7 @@ if _lib.CHACHA_ENABLED:
|
|||
self._IV_counter = 0
|
||||
|
||||
def _set_key(self, direction):
|
||||
if self._key == None:
|
||||
if self._key is None:
|
||||
return -1
|
||||
if self._enc:
|
||||
ret = _lib.wc_Chacha_SetKey(self._enc, self._key, len(self._key))
|
||||
|
|
@ -692,7 +691,7 @@ if _lib.RSA_ENABLED:
|
|||
|
||||
class RsaPublic(_Rsa):
|
||||
def __init__(self, key=None, hash_type=None):
|
||||
if key != None:
|
||||
if key is not None:
|
||||
key = t2b(key)
|
||||
self._hash_type = hash_type
|
||||
|
||||
|
|
@ -830,8 +829,6 @@ if _lib.RSA_ENABLED:
|
|||
Generates a new key pair of desired length **size**.
|
||||
"""
|
||||
rsa = cls(hash_type=hash_type)
|
||||
if rsa == None: # pragma: no cover
|
||||
raise WolfCryptError("Invalid key error (%d)" % ret)
|
||||
|
||||
ret = _lib.wc_MakeRsaKey(rsa.native_object, size, 65537,
|
||||
rng.native_object)
|
||||
|
|
@ -852,7 +849,7 @@ if _lib.RSA_ENABLED:
|
|||
idx = _ffi.new("word32*")
|
||||
idx[0] = 0
|
||||
|
||||
if key != None:
|
||||
if key is not None:
|
||||
key = t2b(key)
|
||||
ret = _lib.wc_RsaPrivateKeyDecode(key, idx,
|
||||
self.native_object, len(key))
|
||||
|
|
@ -1096,7 +1093,7 @@ if _lib.ECC_ENABLED:
|
|||
qy_size[0] = self.size
|
||||
|
||||
ret = _lib.wc_ecc_export_public_raw(self.native_object, Qx,
|
||||
qx_size, Qy, qy_size);
|
||||
qx_size, Qy, qy_size)
|
||||
if ret != 0: # pragma: no cover
|
||||
raise WolfCryptError("Key encode error (%d)" % ret)
|
||||
|
||||
|
|
@ -1265,7 +1262,7 @@ if _lib.ECC_ENABLED:
|
|||
d_size[0] = self.size
|
||||
|
||||
ret = _lib.wc_ecc_export_private_raw(self.native_object, Qx,
|
||||
qx_size, Qy, qy_size, d, d_size);
|
||||
qx_size, Qy, qy_size, d, d_size)
|
||||
if ret != 0: # pragma: no cover
|
||||
raise WolfCryptError("Key encode error (%d)" % ret)
|
||||
|
||||
|
|
@ -1322,8 +1319,8 @@ if _lib.ECC_ENABLED:
|
|||
Returns the signature in its two raw components r, s
|
||||
"""
|
||||
plaintext = t2b(plaintext)
|
||||
R = _ffi.new("mp_int[1]");
|
||||
S = _ffi.new("mp_int[1]");
|
||||
R = _ffi.new("mp_int[1]")
|
||||
S = _ffi.new("mp_int[1]")
|
||||
|
||||
R_bin = _ffi.new("unsigned char[%d]" % self.size )
|
||||
S_bin = _ffi.new("unsigned char[%d]" % self.size )
|
||||
|
|
@ -1478,12 +1475,12 @@ if _lib.ED25519_ENABLED:
|
|||
idx[0] = 0
|
||||
if pub:
|
||||
ret = _lib.wc_ed25519_import_private_key(key, len(key), pub,
|
||||
len(pub), self.native_object);
|
||||
len(pub), self.native_object)
|
||||
if ret < 0:
|
||||
raise WolfCryptError("Key decode error (%d)" % ret)
|
||||
else:
|
||||
ret = _lib.wc_ed25519_import_private_only(key, len(key),
|
||||
self.native_object);
|
||||
self.native_object)
|
||||
if ret < 0:
|
||||
raise WolfCryptError("Key decode error (%d)" % ret)
|
||||
pubkey = _ffi.new("byte[%d]" % (self.size * 4))
|
||||
|
|
@ -1492,7 +1489,7 @@ if _lib.ED25519_ENABLED:
|
|||
if ret < 0:
|
||||
raise WolfCryptError("Public key generate error (%d)" % ret)
|
||||
ret = _lib.wc_ed25519_import_public(pubkey, self.size,
|
||||
self.native_object);
|
||||
self.native_object)
|
||||
|
||||
if self.size <= 0: # pragma: no cover
|
||||
raise WolfCryptError("Key decode error (%d)" % self.size)
|
||||
|
|
@ -1622,7 +1619,7 @@ if _lib.ED448_ENABLED:
|
|||
status = _ffi.new("int[1]")
|
||||
ctx_buf = _ffi.NULL
|
||||
ctx_buf_len = 0
|
||||
if ctx != None:
|
||||
if ctx is not None:
|
||||
ctx_buf = t2b(ctx)
|
||||
ctx_buf_len = len(ctx_buf)
|
||||
|
||||
|
|
@ -1674,12 +1671,12 @@ if _lib.ED448_ENABLED:
|
|||
idx[0] = 0
|
||||
if pub:
|
||||
ret = _lib.wc_ed448_import_private_key(key, len(key), pub,
|
||||
len(pub), self.native_object);
|
||||
len(pub), self.native_object)
|
||||
if ret < 0:
|
||||
raise WolfCryptError("Key decode error (%d)" % ret)
|
||||
else:
|
||||
ret = _lib.wc_ed448_import_private_only(key, len(key),
|
||||
self.native_object);
|
||||
self.native_object)
|
||||
if ret < 0:
|
||||
raise WolfCryptError("Key decode error (%d)" % ret)
|
||||
pubkey = _ffi.new("byte[%d]" % (self.size * 4))
|
||||
|
|
@ -1688,7 +1685,7 @@ if _lib.ED448_ENABLED:
|
|||
if ret < 0:
|
||||
raise WolfCryptError("Public key generate error (%d)" % ret)
|
||||
ret = _lib.wc_ed448_import_public(pubkey, self.size,
|
||||
self.native_object);
|
||||
self.native_object)
|
||||
|
||||
if self.size <= 0: # pragma: no cover
|
||||
raise WolfCryptError("Key decode error (%d)" % self.size)
|
||||
|
|
@ -1732,7 +1729,7 @@ if _lib.ED448_ENABLED:
|
|||
signature_size[0] = self.max_signature_size
|
||||
ctx_buf = _ffi.NULL
|
||||
ctx_buf_len = 0
|
||||
if (ctx != None):
|
||||
if ctx is not None:
|
||||
ctx_buf = t2b(ctx)
|
||||
ctx_buf_len = len(ctx_buf)
|
||||
|
||||
|
|
@ -2031,9 +2028,9 @@ if _lib.ML_KEM_ENABLED:
|
|||
|
||||
|
||||
if _lib.ML_DSA_ENABLED:
|
||||
ML_DSA_KEYGEN_SEED_LENGTH = 32
|
||||
"""The length of a private key generation seed."""
|
||||
|
||||
ML_DSA_SIGNATURE_SEED_LENGTH = 32
|
||||
"""The length of a signature generation seed."""
|
||||
|
||||
class MlDsaType(IntEnum):
|
||||
"""
|
||||
`MlDsaType` specifies supported ML-DSA types.
|
||||
|
|
@ -2314,6 +2311,73 @@ if _lib.ML_DSA_ENABLED:
|
|||
|
||||
return _ffi.buffer(signature, out_size[0])[:]
|
||||
|
||||
def sign_with_seed(self, message, seed, ctx=None):
|
||||
"""
|
||||
:param message: message to be signed
|
||||
:type message: bytes or str
|
||||
:param seed: 32-byte seed for deterministic signature generation.
|
||||
:type seed: bytes
|
||||
:param ctx: context (optional, maximum 255 bytes)
|
||||
:type ctx: None for no context, str or bytes otherwise
|
||||
:return: signature
|
||||
:rtype: bytes
|
||||
"""
|
||||
msg_bytestype = t2b(message)
|
||||
in_size = self.sig_size
|
||||
signature = _ffi.new(f"byte[{in_size}]")
|
||||
out_size = _ffi.new("word32 *")
|
||||
out_size[0] = in_size
|
||||
|
||||
try:
|
||||
seed_view = memoryview(seed)
|
||||
except TypeError as exception:
|
||||
raise TypeError(
|
||||
"seed must support the buffer protocol, such as `bytes` or `bytearray`"
|
||||
) from exception
|
||||
if len(seed_view) != ML_DSA_SIGNATURE_SEED_LENGTH:
|
||||
raise ValueError(
|
||||
f"Seed for generating a signature must be {ML_DSA_SIGNATURE_SEED_LENGTH}"
|
||||
"bytes."
|
||||
)
|
||||
|
||||
if ctx is not None:
|
||||
ctx_bytestype = t2b(ctx)
|
||||
if len(ctx_bytestype) > 255:
|
||||
raise ValueError(
|
||||
f"context length {len(ctx_bytestype)} too large: must be 255 or less"
|
||||
)
|
||||
ret = _lib.wc_dilithium_sign_ctx_msg_with_seed(
|
||||
_ffi.from_buffer(ctx_bytestype),
|
||||
len(ctx_bytestype), # length must be < 256 bytes
|
||||
_ffi.from_buffer(msg_bytestype),
|
||||
len(msg_bytestype),
|
||||
signature,
|
||||
out_size,
|
||||
self.native_object,
|
||||
_ffi.from_buffer(seed_view),
|
||||
)
|
||||
if ret < 0: # pragma: no cover
|
||||
raise WolfCryptError("wc_dilithium_sign_ctx_msg_with_seed() error (%d)" % ret)
|
||||
else:
|
||||
ret = _lib.wc_dilithium_sign_msg_with_seed(
|
||||
_ffi.from_buffer(msg_bytestype),
|
||||
len(msg_bytestype),
|
||||
signature,
|
||||
out_size,
|
||||
self.native_object,
|
||||
_ffi.from_buffer(seed_view),
|
||||
)
|
||||
if ret < 0: # pragma: no cover
|
||||
raise WolfCryptError("wc_dilithium_sign_msg_with_seed() error (%d)" % ret)
|
||||
|
||||
|
||||
if in_size != out_size[0]:
|
||||
raise WolfCryptError(
|
||||
"in_size=%d and out_size=%d don't match" % (in_size, out_size[0])
|
||||
)
|
||||
|
||||
return _ffi.buffer(signature, out_size[0])[:]
|
||||
|
||||
class MlDsaPublic(_MlDsaBase):
|
||||
@property
|
||||
def key_size(self):
|
||||
|
|
|
|||
|
|
@ -31,10 +31,14 @@ class Random(object):
|
|||
A Cryptographically Secure Pseudo Random Number Generator - CSPRNG
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, nonce=_ffi.NULL, device_id=_lib.INVALID_DEVID):
|
||||
self.native_object = _ffi.new("WC_RNG *")
|
||||
|
||||
ret = _lib.wc_InitRng(self.native_object)
|
||||
if nonce == _ffi.NULL:
|
||||
nonce_size = 0
|
||||
else:
|
||||
nonce_size = len(nonce)
|
||||
ret = _lib.wc_InitRngNonce_ex(self.native_object, nonce, nonce_size, _ffi.NULL, device_id)
|
||||
if ret < 0: # pragma: no cover
|
||||
self.native_object = None
|
||||
raise WolfCryptError("RNG init error (%d)" % ret)
|
||||
|
|
|
|||
Loading…
Reference in New Issue