Skip to content

Commit

Permalink
ML-KEM keygen Pairwise Consistency Test (#1969)
Browse files Browse the repository at this point in the history
This change implements the ML-KEM Pairwise Consistency Test (PCT)
for key generation as required by FIPS 140-3 Implementation Guidance.
This effectively triples the runtime of key generation.
  • Loading branch information
dkostic authored Nov 5, 2024
1 parent b6490a0 commit f3a7ced
Showing 1 changed file with 38 additions and 10 deletions.
48 changes: 38 additions & 10 deletions crypto/fipsmodule/ml_kem/ml_kem_ref/kem.c
Original file line number Diff line number Diff line change
@@ -1,14 +1,33 @@
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include "params.h"
#include "kem.h"
#include "indcpa.h"
#include "verify.h"
#include "reduce.h"
#include "symmetric.h"
#include "./params.h"
#include "./kem.h"
#include "./indcpa.h"
#include "./verify.h"
#include "./reduce.h"
#include "./symmetric.h"
#include "../../../internal.h"

#include "openssl/rand.h"

#if defined(AWSLC_FIPS)
// FIPS 203. Pair-wise Consistency Test (PCT) required per [FIPS 140-3 IG](https://csrc.nist.gov/csrc/media/Projects/cryptographic-module-validation-program/documents/fips%20140-3/FIPS%20140-3%20IG.pdf):
// The PCT consists of applying the encapsulation key to encapsulate a shared
// secret leading to ciphertext, and then applying decapsulation key to
// retrieve the same shared secret. Returns 0 if the PCT passes, 1 otherwise.
static int keygen_pct(ml_kem_params *params, const uint8_t *ek, const uint8_t *dk) {
uint8_t ct[KYBER_CIPHERTEXTBYTES_MAX];
uint8_t ss_enc[KYBER_SSBYTES];
uint8_t ss_dec[KYBER_SSBYTES];

crypto_kem_enc(params, ct, ss_enc, ek);
crypto_kem_dec(params, ss_dec, ct, dk);

return verify(ss_enc, ss_dec, KYBER_SSBYTES);
}
#endif

/*************************************************
* Name: crypto_kem_keypair_derand
*
Expand All @@ -22,7 +41,7 @@
* - uint8_t *coins: pointer to input randomness
* (an already allocated array filled with 2*KYBER_SYMBYTES random bytes)
**
* Returns 0 (success)
* Returns 0 on success, aborts on failure.
**************************************************/
int crypto_kem_keypair_derand(ml_kem_params *params,
uint8_t *pk,
Expand All @@ -34,6 +53,13 @@ int crypto_kem_keypair_derand(ml_kem_params *params,
hash_h(sk+params->secret_key_bytes-2*KYBER_SYMBYTES, pk, params->public_key_bytes);
/* Value z for pseudo-random output on reject */
memcpy(sk+params->secret_key_bytes-KYBER_SYMBYTES, coins+KYBER_SYMBYTES, KYBER_SYMBYTES);

#if defined(AWSLC_FIPS)
// Abort in case of PCT failure.
if (keygen_pct(params, pk, sk)) {
BORINGSSL_FIPS_abort();
}
#endif
return 0;
}

Expand All @@ -48,19 +74,21 @@ int crypto_kem_keypair_derand(ml_kem_params *params,
* - uint8_t *sk: pointer to output private key
* (an already allocated array of KYBER_SECRETKEYBYTES bytes)
*
* Returns 0 (success)
* Returns 0 on success, aborts on failure.
**************************************************/
int crypto_kem_keypair(ml_kem_params *params,
uint8_t *pk,
uint8_t *sk)
{
uint8_t coins[2*KYBER_SYMBYTES];
RAND_bytes(coins, 2*KYBER_SYMBYTES);
crypto_kem_keypair_derand(params, pk, sk, coins);
int res = crypto_kem_keypair_derand(params, pk, sk, coins);
assert(res == 0);

// FIPS 203. Section 3.3 Destruction of intermediate values.
OPENSSL_cleanse(coins, sizeof(coins));
return 0;

return res;
}

// Converts a centered representative |in| which is an integer in
Expand Down

0 comments on commit f3a7ced

Please sign in to comment.