Skip to content

Commit

Permalink
Drop "ipd" suffix from ML-KEM related code (#1797)
Browse files Browse the repository at this point in the history
In a previous PR (#1796)
we updated the ML-KEM implementation to conform to the
final FIPS 203 standard. In this change we remove the "ipd"
suffix from all ML-KEM related functions, files, etc.
  • Loading branch information
dkostic committed Aug 26, 2024
1 parent 79ec696 commit e0cc91b
Show file tree
Hide file tree
Showing 36 changed files with 194 additions and 170 deletions.
6 changes: 3 additions & 3 deletions crypto/evp_extra/evp_extra_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2072,9 +2072,9 @@ static const struct KnownKEM kKEMs[] = {
{"Kyber512r3", NID_KYBER512_R3, 800, 1632, 768, 32, 64, 32, "kyber/kat/kyber512r3.txt"},
{"Kyber768r3", NID_KYBER768_R3, 1184, 2400, 1088, 32, 64, 32, "kyber/kat/kyber768r3.txt"},
{"Kyber1024r3", NID_KYBER1024_R3, 1568, 3168, 1568, 32, 64, 32, "kyber/kat/kyber1024r3.txt"},
{"MLKEM512IPD", NID_MLKEM512IPD, 800, 1632, 768, 32, 64, 32, "ml_kem/kat/mlkem512ipd.txt"},
{"MLKEM768IPD", NID_MLKEM768IPD, 1184, 2400, 1088, 32, 64, 32, "ml_kem/kat/mlkem768ipd.txt"},
{"MLKEM1024IPD", NID_MLKEM1024IPD, 1568, 3168, 1568, 32, 64, 32, "ml_kem/kat/mlkem1024ipd.txt"},
{"MLKEM512", NID_MLKEM512, 800, 1632, 768, 32, 64, 32, "ml_kem/kat/mlkem512.txt"},
{"MLKEM768", NID_MLKEM768, 1184, 2400, 1088, 32, 64, 32, "ml_kem/kat/mlkem768.txt"},
{"MLKEM1024", NID_MLKEM1024, 1568, 3168, 1568, 32, 64, 32, "ml_kem/kat/mlkem1024.txt"},
};

class PerKEMTest : public testing::TestWithParam<KnownKEM> {};
Expand Down
6 changes: 3 additions & 3 deletions crypto/kem/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ typedef struct {
extern const KEM_METHOD kem_kyber512r3_method;
extern const KEM_METHOD kem_kyber768r3_method;
extern const KEM_METHOD kem_kyber1024r3_method;
extern const KEM_METHOD kem_ml_kem_512_ipd_method;
extern const KEM_METHOD kem_ml_kem_768_ipd_method;
extern const KEM_METHOD kem_ml_kem_1024_ipd_method;
extern const KEM_METHOD kem_ml_kem_512_method;
extern const KEM_METHOD kem_ml_kem_768_method;
extern const KEM_METHOD kem_ml_kem_1024_method;

// KEM structure and helper functions.
typedef struct {
Expand Down
72 changes: 36 additions & 36 deletions crypto/kem/kem.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@
static const uint8_t kOIDKyber512r3[] = {0xff, 0xff, 0xff, 0xff};
static const uint8_t kOIDKyber768r3[] = {0xff, 0xff, 0xff, 0xff};
static const uint8_t kOIDKyber1024r3[] = {0xff, 0xff, 0xff, 0xff};
static const uint8_t kOIDMLKEM512IPD[] = {0xff, 0xff, 0xff, 0xff};
static const uint8_t kOIDMLKEM768IPD[] = {0xff, 0xff, 0xff, 0xff};
static const uint8_t kOIDMLKEM1024IPD[] = {0xff, 0xff, 0xff, 0xff};
static const uint8_t kOIDMLKEM512[] = {0xff, 0xff, 0xff, 0xff};
static const uint8_t kOIDMLKEM768[] = {0xff, 0xff, 0xff, 0xff};
static const uint8_t kOIDMLKEM1024[] = {0xff, 0xff, 0xff, 0xff};

static const KEM built_in_kems[AWSLC_NUM_BUILT_IN_KEMS] = {
{
Expand Down Expand Up @@ -72,43 +72,43 @@ static const KEM built_in_kems[AWSLC_NUM_BUILT_IN_KEMS] = {
&kem_kyber1024r3_method, // kem.method
},
{
NID_MLKEM512IPD, // kem.nid
kOIDMLKEM512IPD, // kem.oid
sizeof(kOIDMLKEM512IPD), // kem.oid_len
"MLKEM512 IPD", // kem.comment
MLKEM512IPD_PUBLIC_KEY_BYTES, // kem.public_key_len
MLKEM512IPD_SECRET_KEY_BYTES, // kem.secret_key_len
MLKEM512IPD_CIPHERTEXT_BYTES, // kem.ciphertext_len
MLKEM512IPD_SHARED_SECRET_LEN, // kem.shared_secret_len
MLKEM512IPD_KEYGEN_SEED_LEN, // kem.keygen_seed_len
MLKEM512IPD_ENCAPS_SEED_LEN, // kem.encaps_seed_len
&kem_ml_kem_512_ipd_method, // kem.method
NID_MLKEM512, // kem.nid
kOIDMLKEM512, // kem.oid
sizeof(kOIDMLKEM512), // kem.oid_len
"MLKEM512 ", // kem.comment
MLKEM512_PUBLIC_KEY_BYTES, // kem.public_key_len
MLKEM512_SECRET_KEY_BYTES, // kem.secret_key_len
MLKEM512_CIPHERTEXT_BYTES, // kem.ciphertext_len
MLKEM512_SHARED_SECRET_LEN, // kem.shared_secret_len
MLKEM512_KEYGEN_SEED_LEN, // kem.keygen_seed_len
MLKEM512_ENCAPS_SEED_LEN, // kem.encaps_seed_len
&kem_ml_kem_512_method, // kem.method
},
{
NID_MLKEM768IPD, // kem.nid
kOIDMLKEM768IPD, // kem.oid
sizeof(kOIDMLKEM768IPD), // kem.oid_len
"MLKEM768 IPD", // kem.comment
MLKEM768IPD_PUBLIC_KEY_BYTES, // kem.public_key_len
MLKEM768IPD_SECRET_KEY_BYTES, // kem.secret_key_len
MLKEM768IPD_CIPHERTEXT_BYTES, // kem.ciphertext_len
MLKEM768IPD_SHARED_SECRET_LEN, // kem.shared_secret_len
MLKEM768IPD_KEYGEN_SEED_LEN, // kem.keygen_seed_len
MLKEM768IPD_ENCAPS_SEED_LEN, // kem.encaps_seed_len
&kem_ml_kem_768_ipd_method, // kem.method
NID_MLKEM768, // kem.nid
kOIDMLKEM768, // kem.oid
sizeof(kOIDMLKEM768), // kem.oid_len
"MLKEM768 ", // kem.comment
MLKEM768_PUBLIC_KEY_BYTES, // kem.public_key_len
MLKEM768_SECRET_KEY_BYTES, // kem.secret_key_len
MLKEM768_CIPHERTEXT_BYTES, // kem.ciphertext_len
MLKEM768_SHARED_SECRET_LEN, // kem.shared_secret_len
MLKEM768_KEYGEN_SEED_LEN, // kem.keygen_seed_len
MLKEM768_ENCAPS_SEED_LEN, // kem.encaps_seed_len
&kem_ml_kem_768_method, // kem.method
},
{
NID_MLKEM1024IPD, // kem.nid
kOIDMLKEM1024IPD, // kem.oid
sizeof(kOIDMLKEM1024IPD), // kem.oid_len
"MLKEM1024 IPD", // kem.comment
MLKEM1024IPD_PUBLIC_KEY_BYTES, // kem.public_key_len
MLKEM1024IPD_SECRET_KEY_BYTES, // kem.secret_key_len
MLKEM1024IPD_CIPHERTEXT_BYTES, // kem.ciphertext_len
MLKEM1024IPD_SHARED_SECRET_LEN, // kem.shared_secret_len
MLKEM1024IPD_KEYGEN_SEED_LEN, // kem.keygen_seed_len
MLKEM1024IPD_ENCAPS_SEED_LEN, // kem.encaps_seed_len
&kem_ml_kem_1024_ipd_method, // kem.method
NID_MLKEM1024, // kem.nid
kOIDMLKEM1024, // kem.oid
sizeof(kOIDMLKEM1024), // kem.oid_len
"MLKEM1024 ", // kem.comment
MLKEM1024_PUBLIC_KEY_BYTES, // kem.public_key_len
MLKEM1024_SECRET_KEY_BYTES, // kem.secret_key_len
MLKEM1024_CIPHERTEXT_BYTES, // kem.ciphertext_len
MLKEM1024_SHARED_SECRET_LEN, // kem.shared_secret_len
MLKEM1024_KEYGEN_SEED_LEN, // kem.keygen_seed_len
MLKEM1024_ENCAPS_SEED_LEN, // kem.encaps_seed_len
&kem_ml_kem_1024_method, // kem.method
},
};

Expand Down
96 changes: 48 additions & 48 deletions crypto/kem/kem_methods.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,116 +124,116 @@ const KEM_METHOD kem_kyber1024r3_method = {
kyber1024r3_decaps,
};

static int ml_kem_512_ipd_keygen_deterministic(uint8_t *public_key,
static int ml_kem_512_keygen_deterministic(uint8_t *public_key,
uint8_t *secret_key,
const uint8_t *seed) {
return ml_kem_512_ipd_keypair_deterministic(public_key, secret_key, seed) == 0;
return ml_kem_512_keypair_deterministic(public_key, secret_key, seed) == 0;
}

static int ml_kem_512_ipd_keygen(uint8_t *public_key,
static int ml_kem_512_keygen(uint8_t *public_key,
uint8_t *secret_key) {
return ml_kem_512_ipd_keypair(public_key, secret_key) == 0;
return ml_kem_512_keypair(public_key, secret_key) == 0;
}

static int ml_kem_512_ipd_encaps_deterministic(uint8_t *ciphertext,
static int ml_kem_512_encaps_deterministic(uint8_t *ciphertext,
uint8_t *shared_secret,
const uint8_t *public_key,
const uint8_t *seed) {
return ml_kem_512_ipd_encapsulate_deterministic(ciphertext, shared_secret, public_key, seed) == 0;
return ml_kem_512_encapsulate_deterministic(ciphertext, shared_secret, public_key, seed) == 0;
}

static int ml_kem_512_ipd_encaps(uint8_t *ciphertext,
static int ml_kem_512_encaps(uint8_t *ciphertext,
uint8_t *shared_secret,
const uint8_t *public_key) {
return ml_kem_512_ipd_encapsulate(ciphertext, shared_secret, public_key) == 0;
return ml_kem_512_encapsulate(ciphertext, shared_secret, public_key) == 0;
}

static int ml_kem_512_ipd_decaps(uint8_t *shared_secret,
static int ml_kem_512_decaps(uint8_t *shared_secret,
const uint8_t *ciphertext,
const uint8_t *secret_key) {
return ml_kem_512_ipd_decapsulate(shared_secret, ciphertext, secret_key) == 0;
return ml_kem_512_decapsulate(shared_secret, ciphertext, secret_key) == 0;
}

const KEM_METHOD kem_ml_kem_512_ipd_method = {
ml_kem_512_ipd_keygen_deterministic,
ml_kem_512_ipd_keygen,
ml_kem_512_ipd_encaps_deterministic,
ml_kem_512_ipd_encaps,
ml_kem_512_ipd_decaps,
const KEM_METHOD kem_ml_kem_512_method = {
ml_kem_512_keygen_deterministic,
ml_kem_512_keygen,
ml_kem_512_encaps_deterministic,
ml_kem_512_encaps,
ml_kem_512_decaps,
};

static int ml_kem_768_ipd_keygen_deterministic(uint8_t *public_key,
static int ml_kem_768_keygen_deterministic(uint8_t *public_key,
uint8_t *secret_key,
const uint8_t *seed) {
return ml_kem_768_ipd_keypair_deterministic(public_key, secret_key, seed) == 0;
return ml_kem_768_keypair_deterministic(public_key, secret_key, seed) == 0;
}

static int ml_kem_768_ipd_keygen(uint8_t *public_key,
static int ml_kem_768_keygen(uint8_t *public_key,
uint8_t *secret_key) {
return ml_kem_768_ipd_keypair(public_key, secret_key) == 0;
return ml_kem_768_keypair(public_key, secret_key) == 0;
}

static int ml_kem_768_ipd_encaps_deterministic(uint8_t *ciphertext,
static int ml_kem_768_encaps_deterministic(uint8_t *ciphertext,
uint8_t *shared_secret,
const uint8_t *public_key,
const uint8_t *seed) {
return ml_kem_768_ipd_encapsulate_deterministic(ciphertext, shared_secret, public_key, seed) == 0;
return ml_kem_768_encapsulate_deterministic(ciphertext, shared_secret, public_key, seed) == 0;
}

static int ml_kem_768_ipd_encaps(uint8_t *ciphertext,
static int ml_kem_768_encaps(uint8_t *ciphertext,
uint8_t *shared_secret,
const uint8_t *public_key) {
return ml_kem_768_ipd_encapsulate(ciphertext, shared_secret, public_key) == 0;
return ml_kem_768_encapsulate(ciphertext, shared_secret, public_key) == 0;
}

static int ml_kem_768_ipd_decaps(uint8_t *shared_secret,
static int ml_kem_768_decaps(uint8_t *shared_secret,
const uint8_t *ciphertext,
const uint8_t *secret_key) {
return ml_kem_768_ipd_decapsulate(shared_secret, ciphertext, secret_key) == 0;
return ml_kem_768_decapsulate(shared_secret, ciphertext, secret_key) == 0;
}

const KEM_METHOD kem_ml_kem_768_ipd_method = {
ml_kem_768_ipd_keygen_deterministic,
ml_kem_768_ipd_keygen,
ml_kem_768_ipd_encaps_deterministic,
ml_kem_768_ipd_encaps,
ml_kem_768_ipd_decaps,
const KEM_METHOD kem_ml_kem_768_method = {
ml_kem_768_keygen_deterministic,
ml_kem_768_keygen,
ml_kem_768_encaps_deterministic,
ml_kem_768_encaps,
ml_kem_768_decaps,
};

static int ml_kem_1024_ipd_keygen_deterministic(uint8_t *public_key,
static int ml_kem_1024_keygen_deterministic(uint8_t *public_key,
uint8_t *secret_key,
const uint8_t *seed) {
return ml_kem_1024_ipd_keypair_deterministic(public_key, secret_key, seed) == 0;
return ml_kem_1024_keypair_deterministic(public_key, secret_key, seed) == 0;
}

static int ml_kem_1024_ipd_keygen(uint8_t *public_key,
static int ml_kem_1024_keygen(uint8_t *public_key,
uint8_t *secret_key) {
return ml_kem_1024_ipd_keypair(public_key, secret_key) == 0;
return ml_kem_1024_keypair(public_key, secret_key) == 0;
}

static int ml_kem_1024_ipd_encaps_deterministic(uint8_t *ciphertext,
static int ml_kem_1024_encaps_deterministic(uint8_t *ciphertext,
uint8_t *shared_secret,
const uint8_t *public_key,
const uint8_t *seed) {
return ml_kem_1024_ipd_encapsulate_deterministic(ciphertext, shared_secret, public_key, seed) == 0;
return ml_kem_1024_encapsulate_deterministic(ciphertext, shared_secret, public_key, seed) == 0;
}

static int ml_kem_1024_ipd_encaps(uint8_t *ciphertext,
static int ml_kem_1024_encaps(uint8_t *ciphertext,
uint8_t *shared_secret,
const uint8_t *public_key) {
return ml_kem_1024_ipd_encapsulate(ciphertext, shared_secret, public_key) == 0;
return ml_kem_1024_encapsulate(ciphertext, shared_secret, public_key) == 0;
}

static int ml_kem_1024_ipd_decaps(uint8_t *shared_secret,
static int ml_kem_1024_decaps(uint8_t *shared_secret,
const uint8_t *ciphertext,
const uint8_t *secret_key) {
return ml_kem_1024_ipd_decapsulate(shared_secret, ciphertext, secret_key) == 0;
return ml_kem_1024_decapsulate(shared_secret, ciphertext, secret_key) == 0;
}

const KEM_METHOD kem_ml_kem_1024_ipd_method = {
ml_kem_1024_ipd_keygen_deterministic,
ml_kem_1024_ipd_keygen,
ml_kem_1024_ipd_encaps_deterministic,
ml_kem_1024_ipd_encaps,
ml_kem_1024_ipd_decaps,
const KEM_METHOD kem_ml_kem_1024_method = {
ml_kem_1024_keygen_deterministic,
ml_kem_1024_keygen,
ml_kem_1024_encaps_deterministic,
ml_kem_1024_encaps,
ml_kem_1024_decaps,
};
9 changes: 4 additions & 5 deletions crypto/ml_kem/README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
# AWS-LC ML-KEM readme file

The source code in this folder implements ML-KEM-ipd as defined in FIPS 203 (Initial Public Draft) Module-Lattice-Based Key-Encapsulation Mechanism Standard ([link](https://csrc.nist.gov/pubs/fips/203/ipd)).

NOTE: THIS IS AN IMPLEMENTATION OF THE DRAFT VERSION OF FIPS 203, NOT THE FINAL STANDARD. WE WILL CHANGE THIS IMPLEMENTATION TO CONFORM WITH THE STANDARD WHEN IT BECOMES OFFICIAL AND PUBLIC.
The source code in this folder implements ML-KEM as defined in FIPS 203 Module-Lattice-Based Key-Encapsulation Mechanism Standard ([link](https://csrc.nist.gov/pubs/fips/203/final).

**Source code origin and modifications.** The source code was imported from a branch of the official repository of the Crystals-Kyber team that follows the standard draft: https://github.com/pq-crystals/kyber/tree/standard. The code was taken at [commit](https://github.com/pq-crystals/kyber/commit/11d00ff1f20cfca1f72d819e5a45165c1e0a2816) as of 03/26/2024. At the moment, only the reference C implementation is imported.

The following changes were made to the source code in `ml_kem_ipd_ref_common` directory:
The code was refactored in [this PR](https://github.com/aws/aws-lc/pull/1763) by parametrizing all functions that depend on values that are specific to a parameter set, i.e., that directly or indirectly depend on the value of KYBER_K. To do this, in `params.h` we defined a structure that holds those ML-KEM parameters and functions
that initialize a given structure with values corresponding to a parameter set. This structure is then passed to every function that requires it as a function argument. In addition, the following changes were made to the source code in `ml_kem_ref` directory:
- `randombytes.{h|c}` are deleted because we are using the randomness generation functions provided by AWS-LC.
- `kem.c`: call to randombytes function is replaced with a call to RAND_bytes and the appropriate header file is included (openssl/rand.h).
- `fips202.{h|c}` are deleted and the ones from `crypto/kyber/pqcrystals_kyber_ref_common` directory are used.
- `symmetric-shake.c`: unnecessary include of fips202.h is removed.
- `api.h`: `pqcrystals` prefix substituted with `ml_kem` (to be able to build alongside `crypto/kyber`).
- `poly.c`: the `poly_frommsg` function was modified to address the constant-time issue described [here](https://github.com/pq-crystals/kyber/commit/9b8d30698a3e7449aeb34e62339d4176f11e3c6c).

The KATs were generated by compiling and running the KAT generator tests from the official repository. Specifically, running `make` in the `ref` folder produces `nistkat/PQCgenKAT_kem512` binary that can generates the test vectors. The files in `ml_kem/kat/mlkem{512|768|1024}ipd.txt` utilize the deterministic API for testing, and instead use the intermediate seed values (`keypair_coins` and `encap_coins`) instead of a call to randomness generation. The same intermediate values can be extracted from the official repository from the `coins` generated during keypair, and encapsulate.
**Testing.** The KATs were obtained from an independent implementation of ML-KEM written in SPARK Ada subset: https://github.com/awslabs/LibMLKEM.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit e0cc91b

Please sign in to comment.