Skip to content

Commit

Permalink
Add ML-DSA-44 and ML-DSA-87 to PQDSA API (#2009)
Browse files Browse the repository at this point in the history
This change adds ML-DSA-44 and ML-DSA-87 to AWS-LC. As we already have support for ML-DSA-65 through the PQDSA signature API (see #1963) and already support internal functions and KATs that use these internal APIs (see #1999), this change consists of:

- The addition of the 6 `pqdsa` APIs for ML-DSA-44 and ML-DSA-87:
`ml_dsa_{44/87}_keypair`, `ml_dsa_{44/87}_keypair_internal`,
`ml_dsa_{44/87}_sign`, `ml_dsa_{44/87}_sign_internal`,
`ml_dsa_{44/87}_verify`, and`ml_dsa_{44/87}_verify_internal`
- The function methods: `sig_ml_dsa_44_method` and
`sig_ml_dsa_87_method`
- The algorithm data structs: `sig_ml_dsa_44` and `sig_ml_dsa_87`

Integrating ML-DSA-44/87 into X.509 will be in a follow-up commit.

Benchmarking results:
```
Did 33000 MLDSA44 keygen operations in 1000554us (32981.7 ops/sec)
Did 8541 MLDSA44 signing operations in 1061153us (8048.8 ops/sec)
Did 32000 MLDSA44 verify operations in 1016751us (31472.8 ops/sec)
Did 17000 MLDSA65 keygen operations in 1021812us (16637.1 ops/sec)
Did 6000 MLDSA65 signing operations in 1148331us (5225.0 ops/sec)
Did 20000 MLDSA65 verify operations in 1019696us (19613.7 ops/sec)
Did 12000 MLDSA87 keygen operations in 1011438us (11864.3 ops/sec)
Did 4344 MLDSA87 signing operations in 1043422us (4163.2 ops/sec)
Did 12000 MLDSA87 verify operations in 1027267us (11681.5 ops/sec)
```

Testing:
`ML-DSA-44/87` are added to the test harness.
This requires the inclusion of test harness raw public keys
`mldsa{44/87}kPublicKey` and encoded public keys
`mldsa{44/87}kPublicKeySPKI`.

The lengths of the encodings are well defined by
https://datatracker.ietf.org/doc/draft-ietf-lamps-dilithium-certificates/
  • Loading branch information
jakemas authored Dec 3, 2024
1 parent 0931fe2 commit 7c47081
Show file tree
Hide file tree
Showing 9 changed files with 4,934 additions and 1,052 deletions.
1,200 changes: 1,200 additions & 0 deletions crypto/dilithium/kat/MLDSA_44_hedged_pure.txt

Large diffs are not rendered by default.

1,200 changes: 1,200 additions & 0 deletions crypto/dilithium/kat/MLDSA_87_hedged_pure.txt

Large diffs are not rendered by default.

137 changes: 137 additions & 0 deletions crypto/dilithium/ml_dsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,74 @@
// those can be conditionally (or based on compile-time flags) called here,
// depending on platform support.

int ml_dsa_44_keypair(uint8_t *public_key /* OUT */,
uint8_t *private_key /* OUT */) {
ml_dsa_params params;
ml_dsa_44_params_init(&params);
return (crypto_sign_keypair(&params, public_key, private_key) == 0);
}

int ml_dsa_44_keypair_internal(uint8_t *public_key /* OUT */,
uint8_t *private_key /* OUT */,
const uint8_t *seed /* IN */) {
ml_dsa_params params;
ml_dsa_44_params_init(&params);
return crypto_sign_keypair_internal(&params, public_key, private_key, seed) == 0;
}

int ml_dsa_44_sign(const uint8_t *private_key /* IN */,
uint8_t *sig /* OUT */,
size_t *sig_len /* OUT */,
const uint8_t *message /* IN */,
size_t message_len /* IN */,
const uint8_t *ctx_string /* IN */,
size_t ctx_string_len /* IN */) {
ml_dsa_params params;
ml_dsa_44_params_init(&params);
return crypto_sign_signature(&params, sig, sig_len, message, message_len,
ctx_string, ctx_string_len, private_key) == 0;
}

int ml_dsa_44_sign_internal(const uint8_t *private_key /* IN */,
uint8_t *sig /* OUT */,
size_t *sig_len /* OUT */,
const uint8_t *message /* IN */,
size_t message_len /* IN */,
const uint8_t *pre /* IN */,
size_t pre_len /* IN */,
uint8_t *rnd /* IN */) {
ml_dsa_params params;
ml_dsa_44_params_init(&params);
return crypto_sign_signature_internal(&params, sig, sig_len, message, message_len,
pre, pre_len, rnd, private_key) == 0;
}

int ml_dsa_44_verify(const uint8_t *public_key /* IN */,
const uint8_t *sig /* IN */,
size_t sig_len /* IN */,
const uint8_t *message /* IN */,
size_t message_len /* IN */,
const uint8_t *ctx_string /* IN */,
size_t ctx_string_len /* IN */) {
ml_dsa_params params;
ml_dsa_44_params_init(&params);
return crypto_sign_verify(&params, sig, sig_len, message, message_len,
ctx_string, ctx_string_len, public_key) == 0;
}

int ml_dsa_44_verify_internal(const uint8_t *public_key /* IN */,
const uint8_t *sig /* IN */,
size_t sig_len /* IN */,
const uint8_t *message /* IN */,
size_t message_len /* IN */,
const uint8_t *pre /* IN */,
size_t pre_len /* IN */) {
ml_dsa_params params;
ml_dsa_44_params_init(&params);
return crypto_sign_verify_internal(&params, sig, sig_len, message, message_len,
pre, pre_len, public_key) == 0;
}

int ml_dsa_65_keypair(uint8_t *public_key /* OUT */,
uint8_t *private_key /* OUT */) {
ml_dsa_params params;
Expand Down Expand Up @@ -92,3 +160,72 @@ int ml_dsa_65_verify_internal(const uint8_t *public_key /* IN */,
return crypto_sign_verify_internal(&params, sig, sig_len, message, message_len,
pre, pre_len, public_key) == 0;
}

int ml_dsa_87_keypair(uint8_t *public_key /* OUT */,
uint8_t *private_key /* OUT */) {
ml_dsa_params params;
ml_dsa_87_params_init(&params);
return (crypto_sign_keypair(&params, public_key, private_key) == 0);
}

int ml_dsa_87_keypair_internal(uint8_t *public_key /* OUT */,
uint8_t *private_key /* OUT */,
const uint8_t *seed /* IN */) {
ml_dsa_params params;
ml_dsa_87_params_init(&params);
return crypto_sign_keypair_internal(&params, public_key, private_key, seed) == 0;
}

int ml_dsa_87_sign(const uint8_t *private_key /* IN */,
uint8_t *sig /* OUT */,
size_t *sig_len /* OUT */,
const uint8_t *message /* IN */,
size_t message_len /* IN */,
const uint8_t *ctx_string /* IN */,
size_t ctx_string_len /* IN */) {
ml_dsa_params params;
ml_dsa_87_params_init(&params);
return crypto_sign_signature(&params, sig, sig_len, message, message_len,
ctx_string, ctx_string_len, private_key) == 0;
}

int ml_dsa_87_sign_internal(const uint8_t *private_key /* IN */,
uint8_t *sig /* OUT */,
size_t *sig_len /* OUT */,
const uint8_t *message /* IN */,
size_t message_len /* IN */,
const uint8_t *pre /* IN */,
size_t pre_len /* IN */,
uint8_t *rnd /* IN */) {
ml_dsa_params params;
ml_dsa_87_params_init(&params);
return crypto_sign_signature_internal(&params, sig, sig_len, message, message_len,
pre, pre_len, rnd, private_key) == 0;
}

int ml_dsa_87_verify(const uint8_t *public_key /* IN */,
const uint8_t *sig /* IN */,
size_t sig_len /* IN */,
const uint8_t *message /* IN */,
size_t message_len /* IN */,
const uint8_t *ctx_string /* IN */,
size_t ctx_string_len /* IN */) {
ml_dsa_params params;
ml_dsa_87_params_init(&params);
return crypto_sign_verify(&params, sig, sig_len, message, message_len,
ctx_string, ctx_string_len, public_key) == 0;
}

int ml_dsa_87_verify_internal(const uint8_t *public_key /* IN */,
const uint8_t *sig /* IN */,
size_t sig_len /* IN */,
const uint8_t *message /* IN */,
size_t message_len /* IN */,
const uint8_t *pre /* IN */,
size_t pre_len /* IN */) {
ml_dsa_params params;
ml_dsa_87_params_init(&params);
return crypto_sign_verify_internal(&params, sig, sig_len, message, message_len,
pre, pre_len, public_key) == 0;
}

67 changes: 67 additions & 0 deletions crypto/dilithium/ml_dsa.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,54 @@
#include <openssl/base.h>
#include <openssl/evp.h>

#define MLDSA44_PUBLIC_KEY_BYTES 1312
#define MLDSA44_PRIVATE_KEY_BYTES 2560
#define MLDSA44_SIGNATURE_BYTES 2420
#define MLDSA44_KEYGEN_SEED_BYTES 32
#define MLDSA44_SIGNATURE_SEED_BYTES 32

#define MLDSA65_PUBLIC_KEY_BYTES 1952
#define MLDSA65_PRIVATE_KEY_BYTES 4032
#define MLDSA65_SIGNATURE_BYTES 3309
#define MLDSA65_KEYGEN_SEED_BYTES 32
#define MLDSA65_SIGNATURE_SEED_BYTES 32

#define MLDSA87_PUBLIC_KEY_BYTES 2592
#define MLDSA87_PRIVATE_KEY_BYTES 4896
#define MLDSA87_SIGNATURE_BYTES 4627
#define MLDSA87_KEYGEN_SEED_BYTES 32
#define MLDSA87_SIGNATURE_SEED_BYTES 32

#if defined(__cplusplus)
extern "C" {
#endif
int ml_dsa_44_keypair(uint8_t *public_key,
uint8_t *secret_key);

int ml_dsa_44_keypair_internal(uint8_t *public_key,
uint8_t *private_key,
const uint8_t *seed);

int ml_dsa_44_sign(const uint8_t *private_key,
uint8_t *sig, size_t *sig_len,
const uint8_t *message, size_t message_len,
const uint8_t *ctx_string, size_t ctx_len);

int ml_dsa_44_sign_internal(const uint8_t *private_key,
uint8_t *sig, size_t *sig_len,
const uint8_t *message, size_t message_len,
const uint8_t *pre, size_t pre_len,
uint8_t *rnd);

int ml_dsa_44_verify(const uint8_t *public_key,
const uint8_t *sig, size_t sig_len,
const uint8_t *message, size_t message_len,
const uint8_t *ctx_string, size_t ctx_string_len);

int ml_dsa_44_verify_internal(const uint8_t *public_key,
const uint8_t *sig, size_t sig_len,
const uint8_t *message, size_t message_len,
const uint8_t *pre, size_t pre_len);

int ml_dsa_65_keypair(uint8_t *public_key,
uint8_t *secret_key);
Expand Down Expand Up @@ -46,6 +85,34 @@ int ml_dsa_65_verify_internal(const uint8_t *public_key,
const uint8_t *sig, size_t sig_len,
const uint8_t *message, size_t message_len,
const uint8_t *pre, size_t pre_len);

int ml_dsa_87_keypair(uint8_t *public_key,
uint8_t *secret_key);

int ml_dsa_87_keypair_internal(uint8_t *public_key,
uint8_t *private_key,
const uint8_t *seed);

int ml_dsa_87_sign(const uint8_t *private_key,
uint8_t *sig, size_t *sig_len,
const uint8_t *message, size_t message_len,
const uint8_t *ctx_string, size_t ctx_len);

int ml_dsa_87_sign_internal(const uint8_t *private_key,
uint8_t *sig, size_t *sig_len,
const uint8_t *message, size_t message_len,
const uint8_t *pre, size_t pre_len,
uint8_t *rnd);

int ml_dsa_87_verify(const uint8_t *public_key,
const uint8_t *sig, size_t sig_len,
const uint8_t *message, size_t message_len,
const uint8_t *ctx_string, size_t ctx_string_len);

int ml_dsa_87_verify_internal(const uint8_t *public_key,
const uint8_t *sig, size_t sig_len,
const uint8_t *message, size_t message_len,
const uint8_t *pre, size_t pre_len);
#if defined(__cplusplus)
}
#endif
Expand Down
Loading

0 comments on commit 7c47081

Please sign in to comment.