-
Notifications
You must be signed in to change notification settings - Fork 118
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
Add internal APIs for ML-DSA #1999
base: main
Are you sure you want to change the base?
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #1999 +/- ##
==========================================
+ Coverage 78.89% 78.90% +0.01%
==========================================
Files 595 594 -1
Lines 102451 102434 -17
Branches 14527 14524 -3
==========================================
- Hits 80827 80825 -2
+ Misses 20976 20958 -18
- Partials 648 651 +3 ☔ View full report in Codecov by Sentry. 🚨 Try these New Features:
|
uint8_t *private_key); | ||
uint8_t *secret_key); | ||
|
||
int ml_dsa_65_keypair_internal(uint8_t *public_key, |
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.
Why internal? We used deterministic
for ML-KEM.
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.
We used deterministic
for ML-KEM as we wrote these functions before the final release of the standard came out, and we were working from the IPD and naming conventions from the PQC mailing list. Since the release of FIPS 203, 204 final, we now see these deterministic methods described as internal
, so to make the implementation of the standard clearer I named them internal and added descriptors to the standard itself, e.g.:
/*************************************************
* Name: crypto_sign_keypair_internal
*
* Description: FIPS 204: Algorithm 6 ML-DSA.KeyGen_internal.
* Generates public and private key. Internal API.
...
- `ntt.c`, `poly.c`, `reduce.c`, `reduce.h`: have been modified with a code refactor. The function `fqmul` has been added to bring mode code consistency with Kyber/ML-KEM. See https://github.com/aws/aws-lc/pull/1748 for more details on this change. | ||
- `reduce.c`: a small fix to documentation has been made on the bounds of `reduce32`. | ||
- `poly.c`: a small fix to documentation has been made on the bounds of `poly_reduce`. | ||
- `polyvec.c`: a small fix to documentation has been made on the bounds of `polyveck_reduce`. | ||
|
||
**Testing** | ||
|
||
The KATs were obtained from https://github.com/pq-crystals/dilithium/tree/master/ref/nistkat. | ||
To compile the KAT programs on Linux or macOS, go to the `ref/` directory and run `make nistkat`. This will produce executables within `nistkat` which once executed will produce the KATs: `PQCsignKAT_Dilithium2.rsp`, `PQCsignKAT_Dilithium3.rsp`,`PQCsignKAT_Dilithium5.rsp`. | ||
The KATs were obtained from https://github.com/post-quantum-cryptography/KAT. |
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.
I know why, but please explain why our file MLDSA_65_hedged_pure.txt doesn't match https://github.com/post-quantum-cryptography/KAT/blob/main/MLDSA/kat_MLDSA_65_hedged_pure.rsp
uint8_t seedbuf[2*SEEDBYTES + CRHBYTES]; | ||
uint8_t tr[TRBYTES]; | ||
const uint8_t *rho, *rhoprime, *key; | ||
polyvecl mat[DILITHIUM_K_MAX]; | ||
polyvecl s1, s1hat; | ||
polyveck s2, t1, t0; | ||
|
||
/* Get randomness for rho, rhoprime and key */ | ||
pq_custom_randombytes(seedbuf, SEEDBYTES); | ||
OPENSSL_memcpy(seedbuf, seed, SEEDBYTES); |
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.
At first I thought this looked weird and was wondering why not just use seed
directly, but I see they put more stuff into seedbuf
down below. Seems a bit weird and a fragile construction.
seedbuf[SEEDBYTES+0] = params->k; | ||
seedbuf[SEEDBYTES+1] = params->l; |
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.
How does this work? seedbuf
is an array of uint8_t
, so each index in the array can only hold 8 bits and k
/l
are both size_t which could be 64 bits each.
int crypto_sign_keypair(ml_dsa_params *params, uint8_t *pk, uint8_t *sk) { | ||
uint8_t seed[SEEDBYTES]; | ||
/* Get randomness for rho, rhoprime and key */ | ||
RAND_bytes(seed, SEEDBYTES); |
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.
RAND_bytes can never fail, but you should still check the return code so static analysis tools don't complain about not checking the return value.
#ifdef DILITHIUM_RANDOMIZED_SIGNING | ||
if (!RAND_bytes(rnd, RNDBYTES)) | ||
return -1; | ||
#else | ||
for(i=0;i<RNDBYTES;i++) | ||
rnd[i] = 0; | ||
#endif |
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.
Why is this a compile time option and not two normal APIs for sign and sign_deterministic?
if(ctxlen > 255) | ||
return -1; |
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.
Here and in other spots in this PR please update the code to always add the brackets even for single line statements.
if(ctxlen > 255) | |
return -1; | |
if(ctxlen > 255) { | |
return -1; | |
} |
@@ -19,7 +18,6 @@ | |||
|
|||
#include "../test/file_test.h" | |||
#include "../test/test_util.h" | |||
#include "../rand_extra/pq_custom_randombytes.h" |
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.
🎉
for(i = 0; i < ctxstr.size(); i++) { | ||
m_prime[2 + i] = ctxstr[i]; | ||
} |
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.
Can this just use memcpy to be simpler and maybe faster?
for(i = 0; i < ctxlen; i++) | ||
pre[2 + i] = ctx[i]; |
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.
memcpy here too? Either way needs {}
Issues:
Resolves #CryptoAlg-2723
Description of changes:
This PR adds the internal functions from FIPS 204: Module-Lattice-Based Digital Signature Standard. We base this implementation on the upstream reference implementation of ML-DSA pq-crystals/dilithium@444cdcc. However, the upstream commit only includes implementation of
ML-DSA.Sign_internal
andML-DSA.Verify_internal
, so we also includeML-DSA.KeyGen_internal
to complete the implementation.Changes:
ML-DSA.KeyGen
as crypto_sign_keypairML-DSA.Sign
as crypto_sign_signatureML-DSA.Verify
as crypto_sign_verifyML-DSA.KeyGen_internal
as crypto_sign_keypair_internalML-DSA.Sign_internal
as crypto_sign_signature_internalML-DSA.Verify_internal
as crypto_sign_verify_internalpqdsa
API:pq_custom_randombytes.{c/h}
Call-outs:
We can remove the testing mechanism for the KATs
pq_custom_randombytes
as we now support KATs that use the internal functions that provide randomness via an input seed.Testing:
The KATs have been migrated to use the internal functions.
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license.