Skip to content

Commit d86081c

Browse files
committed
Process Copilot comments
- Use constant from ciphers.py - Raise ValueError or TypeError in sign_with_seed instead of assert - Add missing test case
1 parent fc09099 commit d86081c

2 files changed

Lines changed: 45 additions & 14 deletions

File tree

tests/test_mldsa.py

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,9 @@
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

31-
ML_DSA_SIGNATURE_SEED_LENGTH = 32
32-
3331
@pytest.fixture
3432
def rng():
3533
return Random()
@@ -159,8 +157,27 @@ def test_sign_with_seed(mldsa_type, rng):
159157
assert signature == signature_from_same_seed
160158

161159
# test that the seed size is checked:
162-
with pytest.raises(AssertionError):
160+
with pytest.raises(ValueError):
163161
_ = mldsa_priv.sign_with_seed(message, signature_seed[:-1])
164162

165-
with pytest.raises(AssertionError):
163+
# test that the seed type is checked (should be bytes-like, not string)
164+
with pytest.raises(TypeError):
166165
_ = mldsa_priv.sign_with_seed(message, "")
166+
167+
def test_sign_with_seed_and_context(mldsa_type, rng):
168+
signature_seed = rng.bytes(ML_DSA_SIGNATURE_SEED_LENGTH)
169+
mldsa_priv = MlDsaPrivate.make_key(mldsa_type, rng)
170+
pub_key = mldsa_priv.encode_pub_key()
171+
172+
# Import public key
173+
mldsa_pub = MlDsaPublic(mldsa_type)
174+
mldsa_pub.decode_key(pub_key)
175+
176+
# Sign a message
177+
message = b"This is a test message for ML-DSA signature"
178+
context = b"Some context for the signature"
179+
signature = mldsa_priv.sign_with_seed(message, signature_seed, ctx=context)
180+
assert len(signature) == mldsa_priv.sig_size
181+
# test that the context length is checked (more than 255 bytes is invalid):
182+
with pytest.raises(ValueError):
183+
_ = mldsa_priv.sign_with_seed(message, signature_seed[:-1], ctx=bytes(1000))

wolfcrypt/ciphers.py

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2031,6 +2031,9 @@ def decapsulate(self, ct):
20312031

20322032

20332033
if _lib.ML_DSA_ENABLED:
2034+
ML_DSA_SIGNATURE_SEED_LENGTH = 32
2035+
"""The length of a signature generation seed."""
2036+
20342037
class MlDsaType(IntEnum):
20352038
"""
20362039
`MlDsaType` specifies supported ML-DSA types.
@@ -2152,9 +2155,7 @@ def verify(self, signature, message):
21522155
return res[0] == 1
21532156

21542157
class MlDsaPrivate(_MlDsaBase):
2155-
_SIGNATURE_SEED_LENGTH = 32
2156-
"""The length of a signature generation seed."""
2157-
2158+
21582159
@classmethod
21592160
def make_key(cls, mldsa_type, rng=Random()):
21602161
"""
@@ -2289,7 +2290,7 @@ def sign_with_seed(self, message, seed, ctx=None):
22892290
:type message: bytes or str
22902291
:param seed: 32-byte seed for deterministic signature generation.
22912292
:type seed: bytes
2292-
:param ctx: context (optional)
2293+
:param ctx: context (optional, maximum 255 bytes)
22932294
:type ctx: None for no context, str or bytes otherwise
22942295
:return: signature
22952296
:rtype: bytes
@@ -2300,20 +2301,33 @@ def sign_with_seed(self, message, seed, ctx=None):
23002301
out_size = _ffi.new("word32 *")
23012302
out_size[0] = in_size
23022303

2303-
assert isinstance(seed, bytes) and len(seed) == MlDsaPrivate._SIGNATURE_SEED_LENGTH, \
2304-
f"Seed for generating a signature must be {MlDsaPrivate._SIGNATURE_SEED_LENGTH} bytes."
2304+
try:
2305+
seed_view = memoryview(seed)
2306+
except TypeError as exception:
2307+
raise TypeError(
2308+
"seed must support the buffer protocol, such as `bytes` or `bytearray`"
2309+
) from exception
2310+
if len(seed_view) != ML_DSA_SIGNATURE_SEED_LENGTH:
2311+
raise ValueError(
2312+
f"Seed for generating a signature must be {ML_DSA_SIGNATURE_SEED_LENGTH}"
2313+
"bytes."
2314+
)
23052315

23062316
if ctx is not None:
23072317
ctx_bytestype = t2b(ctx)
2318+
if len(ctx_bytestype) > 255:
2319+
raise ValueError(
2320+
f"context length {len(ctx_bytestype)} too large: must be 255 or less"
2321+
)
23082322
ret = _lib.wc_dilithium_sign_ctx_msg_with_seed(
23092323
_ffi.from_buffer(ctx_bytestype),
2310-
len(ctx_bytestype),
2324+
len(ctx_bytestype), # length must be < 256 bytes
23112325
_ffi.from_buffer(msg_bytestype),
23122326
len(msg_bytestype),
23132327
signature,
23142328
out_size,
23152329
self.native_object,
2316-
_ffi.from_buffer(seed),
2330+
_ffi.from_buffer(seed_view),
23172331
)
23182332
if ret < 0: # pragma: no cover
23192333
raise WolfCryptError("wc_dilithium_sign_ctx_msg_with_seed() error (%d)" % ret)
@@ -2324,7 +2338,7 @@ def sign_with_seed(self, message, seed, ctx=None):
23242338
signature,
23252339
out_size,
23262340
self.native_object,
2327-
_ffi.from_buffer(seed),
2341+
_ffi.from_buffer(seed_view),
23282342
)
23292343
if ret < 0: # pragma: no cover
23302344
raise WolfCryptError("wc_dilithium_sign_msg_with_seed() error (%d)" % ret)

0 commit comments

Comments
 (0)