-
Notifications
You must be signed in to change notification settings - Fork 29
ML-DSA: Add optional context to signing and verification #90
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -134,3 +134,21 @@ def test_sign_verify(mldsa_type, rng): | |||||
| # 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 | ||||||
|
||||||
| # Verify with ctx for signature generated without | |
| # Verify with ctx for signature generated without context |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2124,27 +2124,42 @@ def _encode_pub_key(self): | |
|
|
||
| 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 | ||
| """ | ||
| sig_bytestype = t2b(signature) | ||
| 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) | ||
danielinux marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
@@ -2246,12 +2261,14 @@ 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=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 @@ def sign(self, message, rng=Random()): | |
| 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), | ||
|
Comment on lines
+2281
to
+2286
|
||
| 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) | ||
|
Comment on lines
2303
to
2304
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new FFI declarations use different types for ctxLen: wc_dilithium_sign_ctx_msg declares ctxLen as byte, but wc_dilithium_verify_ctx_msg declares ctxLen as word32. Please confirm the correct signature in the wolfSSL headers and make these consistent; if ctxLen is actually word32, the current byte declaration will truncate lengths >255 at the ABI boundary.