Skip to content

Commit 9ebe2fe

Browse files
authored
Merge branch 'master' into ml-dsa-sign-with-context
2 parents 2cf0b70 + ac6eee4 commit 9ebe2fe

11 files changed

Lines changed: 171 additions & 43 deletions

File tree

scripts/build_ffi.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
from distutils.util import get_platform
2727
from cffi import FFI
2828
import shutil
29-
import glob
3029
from wolfcrypt._version import __wolfssl_version__ as version
3130

3231
def local_path(path):
@@ -332,7 +331,7 @@ def get_features(local_wolfssl, features):
332331

333332
for d in include_dirs:
334333
if not os.path.exists(d):
335-
e = "Invalid wolfSSL include dir: .".format(d)
334+
e = f"Invalid wolfSSL include dir: {d}"
336335
raise FileNotFoundError(e)
337336

338337
options = os.path.join(d, "wolfssl", "options.h")
@@ -543,6 +542,8 @@ def build_ffi(local_wolfssl, features):
543542
typedef struct { ...; } OS_Seed;
544543
545544
int wc_InitRng(WC_RNG*);
545+
int wc_InitRngNonce(WC_RNG*, byte*, word32);
546+
int wc_InitRngNonce_ex(WC_RNG*, byte*, word32, void*, int);
546547
int wc_RNG_GenerateBlock(WC_RNG*, byte*, word32);
547548
int wc_RNG_GenerateByte(WC_RNG*, byte*);
548549
int wc_FreeRng(WC_RNG*);
@@ -1032,6 +1033,8 @@ def build_ffi(local_wolfssl, features):
10321033
int wc_dilithium_import_public(const byte* in, word32 inLen, dilithium_key* key);
10331034
int wc_dilithium_sign_msg(const byte* msg, word32 msgLen, byte* sig, word32* sigLen, dilithium_key* key, WC_RNG* rng);
10341035
int wc_dilithium_sign_ctx_msg(const byte* ctx, byte ctxLen, const byte* msg, word32 msgLen, byte* sig, word32* sigLen, dilithium_key* key, WC_RNG* rng);
1036+
int wc_dilithium_sign_msg_with_seed(const byte* msg, word32 msgLen, byte* sig, word32* sigLen, dilithium_key* key, const byte* seed);
1037+
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);
10351038
int wc_dilithium_verify_msg(const byte* sig, word32 sigLen, const byte* msg, word32 msgLen, int* res, dilithium_key* key);
10361039
int wc_dilithium_verify_ctx_msg(const byte* sig, word32 sigLen, const byte* ctx, word32 ctxLen, const byte* msg, word32 msgLen, int* res, dilithium_key* key);
10371040
typedef dilithium_key MlDsaKey;

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@
2222
# pylint: disable=wrong-import-position
2323

2424
import os
25+
import re
2526
import sys
2627
from setuptools import setup, find_packages
2728

2829
os.chdir(os.path.dirname(sys.argv[0]) or ".")
2930

30-
import re
3131
VERSIONFILE = "wolfcrypt/_version.py"
3232
verstrline = open(VERSIONFILE, "rt").read()
3333
VSRE = r"^__version__ = ['\"]([^'\"]*)['\"]"

tests/test_aesgcmstream.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,10 @@
2323
from wolfcrypt._ffi import lib as _lib
2424

2525
if _lib.AESGCM_STREAM_ENABLED:
26-
from collections import namedtuple
2726
import pytest
2827
from wolfcrypt.utils import t2b
2928
from wolfcrypt.exceptions import WolfCryptError
30-
from binascii import hexlify as b2h, unhexlify as h2b
29+
from binascii import hexlify as b2h
3130
from wolfcrypt.ciphers import AesGcmStream
3231

3332
def test_encrypt():

tests/test_chacha20poly1305.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
import pytest
2828
from wolfcrypt.utils import t2b
2929
from wolfcrypt.exceptions import WolfCryptError
30-
from binascii import hexlify as b2h, unhexlify as h2b
30+
from binascii import unhexlify as h2b
3131
from wolfcrypt.ciphers import ChaCha20Poly1305
3232

3333
def test_encrypt_decrypt():

tests/test_ciphers.py

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323
from collections import namedtuple
2424
import random
2525
import pytest
26-
from wolfcrypt._ffi import ffi as _ffi
2726
from wolfcrypt._ffi import lib as _lib
27+
from wolfcrypt.ciphers import MODE_CTR, MODE_ECB, MODE_CBC, WolfCryptError
2828
from wolfcrypt.utils import t2b, h2b
2929
import os
3030

@@ -43,20 +43,16 @@
4343
from wolfcrypt.ciphers import ChaCha
4444

4545
if _lib.RSA_ENABLED:
46-
from wolfcrypt.ciphers import (RsaPrivate, RsaPublic, HASH_TYPE_SHA256, MGF1SHA256, HASH_TYPE_SHA, MGF1SHA1)
46+
from wolfcrypt.ciphers import RsaPrivate, RsaPublic, HASH_TYPE_SHA256, HASH_TYPE_SHA
4747

4848
if _lib.ECC_ENABLED:
49-
from wolfcrypt.ciphers import (EccPrivate, EccPublic)
49+
from wolfcrypt.ciphers import EccPrivate, EccPublic
5050

5151
if _lib.ED25519_ENABLED:
52-
from wolfcrypt.ciphers import (Ed25519Private, Ed25519Public)
52+
from wolfcrypt.ciphers import Ed25519Private, Ed25519Public
5353

5454
if _lib.ED448_ENABLED:
55-
from wolfcrypt.ciphers import (Ed448Private, Ed448Public)
56-
57-
from wolfcrypt.ciphers import (
58-
MODE_CTR, MODE_ECB, MODE_CBC, WolfCryptError
59-
)
55+
from wolfcrypt.ciphers import Ed448Private, Ed448Public
6056

6157

6258
@pytest.fixture

tests/test_hashes.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222

2323
from collections import namedtuple
2424
import pytest
25-
from wolfcrypt._ffi import ffi as _ffi
2625
from wolfcrypt._ffi import lib as _lib
2726
from wolfcrypt.utils import t2b
2827

tests/test_mldsa.py

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
if _lib.ML_DSA_ENABLED:
2626
import pytest
2727

28-
from wolfcrypt.ciphers import MlDsaPrivate, MlDsaPublic, MlDsaType
28+
from wolfcrypt.ciphers import MlDsaPrivate, MlDsaPublic, MlDsaType, ML_DSA_SIGNATURE_SEED_LENGTH
2929
from wolfcrypt.random import Random
3030

3131
@pytest.fixture
@@ -134,7 +134,7 @@ def test_sign_verify(mldsa_type, rng):
134134
# Verify with wrong message
135135
wrong_message = b"This is a wrong message for ML-DSA signature"
136136
assert not mldsa_pub.verify(signature, wrong_message)
137-
137+
138138
# Verify a signature generated without a context but where a context
139139
# is provided during verify
140140
ctx = b"This is a test context for ML-DSA signature"
@@ -156,3 +156,51 @@ def test_sign_verify(mldsa_type, rng):
156156

157157
# Verify with wrong context
158158
assert not mldsa_pub.verify(signature, message, ctx=wrong_ctx)
159+
160+
def test_sign_with_seed(mldsa_type, rng):
161+
signature_seed = rng.bytes(ML_DSA_SIGNATURE_SEED_LENGTH)
162+
mldsa_priv = MlDsaPrivate.make_key(mldsa_type, rng)
163+
pub_key = mldsa_priv.encode_pub_key()
164+
165+
# Import public key
166+
mldsa_pub = MlDsaPublic(mldsa_type)
167+
mldsa_pub.decode_key(pub_key)
168+
169+
# Sign a message
170+
message = b"This is a test message for ML-DSA signature"
171+
signature = mldsa_priv.sign_with_seed(message, signature_seed)
172+
assert len(signature) == mldsa_priv.sig_size
173+
174+
# Verify the signature using public key
175+
assert mldsa_pub.verify(signature, message)
176+
177+
# re-generate from the same seed:
178+
signature_from_same_seed = mldsa_priv.sign_with_seed(message, signature_seed)
179+
assert signature == signature_from_same_seed
180+
181+
# test that the seed size is checked:
182+
with pytest.raises(ValueError):
183+
_ = mldsa_priv.sign_with_seed(message, signature_seed[:-1])
184+
185+
# test that the seed type is checked (should be bytes-like, not string)
186+
with pytest.raises(TypeError):
187+
_ = mldsa_priv.sign_with_seed(message, "")
188+
189+
def test_sign_with_seed_and_context(mldsa_type, rng):
190+
signature_seed = rng.bytes(ML_DSA_SIGNATURE_SEED_LENGTH)
191+
mldsa_priv = MlDsaPrivate.make_key(mldsa_type, rng)
192+
pub_key = mldsa_priv.encode_pub_key()
193+
194+
# Import public key
195+
mldsa_pub = MlDsaPublic(mldsa_type)
196+
mldsa_pub.decode_key(pub_key)
197+
198+
# Sign a message
199+
message = b"This is a test message for ML-DSA signature"
200+
context = b"Some context for the signature"
201+
signature = mldsa_priv.sign_with_seed(message, signature_seed, ctx=context)
202+
assert len(signature) == mldsa_priv.sig_size
203+
# test that the context length is checked (more than 255 bytes is invalid):
204+
with pytest.raises(ValueError):
205+
_ = mldsa_priv.sign_with_seed(message, signature_seed[:-1], ctx=bytes(1000))
206+

tests/test_random.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,14 @@ def test_bytes(rng):
3737
assert len(rng.bytes(1)) == 1
3838
assert len(rng.bytes(8)) == 8
3939
assert len(rng.bytes(128)) == 128
40+
41+
@pytest.fixture
42+
def rng_nonce():
43+
return Random(b"abcdefghijklmnopqrstuv")
44+
45+
def test_nonce_byte(rng_nonce):
46+
assert len(rng_nonce.byte()) == 1
47+
48+
@pytest.mark.parametrize("length", (1, 8, 128))
49+
def test_nonce_bytes(rng_nonce, length):
50+
assert len(rng_nonce.bytes(length)) == length

wolfcrypt/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,15 @@
4646
if top_level_py not in ["setup.py", "build_ffi.py"]:
4747
from wolfcrypt._ffi import ffi as _ffi
4848
from wolfcrypt._ffi import lib as _lib
49+
from wolfcrypt.exceptions import WolfCryptError
4950

5051
if hasattr(_lib, 'WC_RNG_SEED_CB_ENABLED'):
5152
if _lib.WC_RNG_SEED_CB_ENABLED:
5253
ret = _lib.wc_SetSeed_Cb(_ffi.addressof(_lib, "wc_GenerateSeed"))
5354
if ret < 0:
5455
raise WolfCryptError("wc_SetSeed_Cb failed (%d)" % ret)
5556
if _lib.FIPS_ENABLED and _lib.FIPS_VERSION >= 5:
56-
ret = _lib.wolfCrypt_SetPrivateKeyReadEnable_fips(1,
57-
_lib.WC_KEYTYPE_ALL);
57+
ret = _lib.wolfCrypt_SetPrivateKeyReadEnable_fips(1, _lib.WC_KEYTYPE_ALL)
5858
if ret < 0:
5959
raise WolfCryptError("wolfCrypt_SetPrivateKeyReadEnable_fips failed"
6060
" (%d)" % ret)

0 commit comments

Comments
 (0)