ML-DSA: Add optional context to signing and verification
parent
5b13e52d57
commit
9a10f58601
|
|
@ -1031,7 +1031,9 @@ 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_ctx_msg(const byte* ctx, byte ctxLen, const byte* msg, word32 msgLen, byte* sig, word32* sigLen, dilithium_key* key, WC_RNG* rng);
|
||||
int wc_dilithium_verify_msg(const byte* sig, word32 sigLen, const byte* msg, word32 msgLen, int* res, dilithium_key* key);
|
||||
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);
|
||||
typedef dilithium_key MlDsaKey;
|
||||
int wc_MlDsaKey_GetPrivLen(MlDsaKey* key, int* len);
|
||||
int wc_MlDsaKey_GetPubLen(MlDsaKey* key, int* len);
|
||||
|
|
|
|||
|
|
@ -134,3 +134,21 @@ if _lib.ML_DSA_ENABLED:
|
|||
# Verify with wrong message
|
||||
wrong_message = b"This is a wrong message for ML-DSA signature"
|
||||
assert not mldsa_pub.verify(signature, wrong_message)
|
||||
|
||||
# Verify with ctx for signature generated without
|
||||
ctx = b"This is a test context for ML-DSA signature"
|
||||
wrong_ctx = b"This is a wrong context for ML-DSA signature"
|
||||
assert not mldsa_pub.verify(signature, message, ctx=wrong_ctx)
|
||||
|
||||
# Sign a message with context
|
||||
signature = mldsa_priv.sign(message, rng, ctx=ctx)
|
||||
assert len(signature) == mldsa_priv.sig_size
|
||||
|
||||
# Verify the signature by MlDsaPrivate
|
||||
assert mldsa_priv.verify(signature, message, ctx=ctx)
|
||||
|
||||
# Verify the signature by MlDsaPublic
|
||||
assert mldsa_pub.verify(signature, message, ctx=ctx)
|
||||
|
||||
# Verify with wrong ctx
|
||||
assert not mldsa_pub.verify(signature, message, ctx=wrong_ctx)
|
||||
|
|
|
|||
|
|
@ -2124,12 +2124,14 @@ if _lib.ML_DSA_ENABLED:
|
|||
|
||||
return _ffi.buffer(pub_key, out_size[0])[:]
|
||||
|
||||
def verify(self, signature, message):
|
||||
def verify(self, signature, message, ctx=None):
|
||||
"""
|
||||
:param signature: signature to be verified
|
||||
:type signature: bytes or str
|
||||
:param message: message to be verified
|
||||
:type message: bytes or str
|
||||
:param ctx: context (optional)
|
||||
:type ctx: None for no context, str or bytes otherwise
|
||||
:return: True if the verification is successful, False otherwise
|
||||
:rtype: bool
|
||||
"""
|
||||
|
|
@ -2137,14 +2139,27 @@ if _lib.ML_DSA_ENABLED:
|
|||
msg_bytestype = t2b(message)
|
||||
res = _ffi.new("int *")
|
||||
|
||||
ret = _lib.wc_dilithium_verify_msg(
|
||||
_ffi.from_buffer(sig_bytestype),
|
||||
len(sig_bytestype),
|
||||
_ffi.from_buffer(msg_bytestype),
|
||||
len(msg_bytestype),
|
||||
res,
|
||||
self.native_object,
|
||||
)
|
||||
if ctx is not None:
|
||||
ctx_bytestype = t2b(ctx)
|
||||
ret = _lib.wc_dilithium_verify_ctx_msg(
|
||||
_ffi.from_buffer(sig_bytestype),
|
||||
len(sig_bytestype),
|
||||
_ffi.from_buffer(ctx_bytestype),
|
||||
len(ctx_bytestype),
|
||||
_ffi.from_buffer(msg_bytestype),
|
||||
len(msg_bytestype),
|
||||
res,
|
||||
self.native_object,
|
||||
)
|
||||
else:
|
||||
ret = _lib.wc_dilithium_verify_msg(
|
||||
_ffi.from_buffer(sig_bytestype),
|
||||
len(sig_bytestype),
|
||||
_ffi.from_buffer(msg_bytestype),
|
||||
len(msg_bytestype),
|
||||
res,
|
||||
self.native_object,
|
||||
)
|
||||
|
||||
if ret < 0: # pragma: no cover
|
||||
raise WolfCryptError("wc_dilithium_verify_msg() error (%d)" % ret)
|
||||
|
|
@ -2246,12 +2261,14 @@ if _lib.ML_DSA_ENABLED:
|
|||
if pub_key is not None:
|
||||
self._decode_pub_key(pub_key)
|
||||
|
||||
def sign(self, message, rng=Random()):
|
||||
def sign(self, message, rng=Random(), ctx=None):
|
||||
"""
|
||||
:param message: message to be signed
|
||||
:type message: bytes or str
|
||||
:param rng: random number generator for sign
|
||||
:type rng: Random
|
||||
:param ctx: context (optional)
|
||||
:type ctx: None for no context, str or bytes otherwise
|
||||
:return: signature
|
||||
:rtype: bytes
|
||||
"""
|
||||
|
|
@ -2261,14 +2278,27 @@ if _lib.ML_DSA_ENABLED:
|
|||
out_size = _ffi.new("word32 *")
|
||||
out_size[0] = in_size
|
||||
|
||||
ret = _lib.wc_dilithium_sign_msg(
|
||||
_ffi.from_buffer(msg_bytestype),
|
||||
len(msg_bytestype),
|
||||
signature,
|
||||
out_size,
|
||||
self.native_object,
|
||||
rng.native_object,
|
||||
)
|
||||
if ctx is not None:
|
||||
ctx_bytestype = t2b(ctx)
|
||||
ret = _lib.wc_dilithium_sign_ctx_msg(
|
||||
_ffi.from_buffer(ctx_bytestype),
|
||||
len(ctx_bytestype),
|
||||
_ffi.from_buffer(msg_bytestype),
|
||||
len(msg_bytestype),
|
||||
signature,
|
||||
out_size,
|
||||
self.native_object,
|
||||
rng.native_object,
|
||||
)
|
||||
else:
|
||||
ret = _lib.wc_dilithium_sign_msg(
|
||||
_ffi.from_buffer(msg_bytestype),
|
||||
len(msg_bytestype),
|
||||
signature,
|
||||
out_size,
|
||||
self.native_object,
|
||||
rng.native_object,
|
||||
)
|
||||
|
||||
if ret < 0: # pragma: no cover
|
||||
raise WolfCryptError("wc_dilithium_sign_msg() error (%d)" % ret)
|
||||
|
|
|
|||
Loading…
Reference in New Issue