diff --git a/crypto/kyber/pqcrystals_kyber_ref_common/indcpa.c b/crypto/kyber/pqcrystals_kyber_ref_common/indcpa.c index c406cef20f..07befaf6c4 100644 --- a/crypto/kyber/pqcrystals_kyber_ref_common/indcpa.c +++ b/crypto/kyber/pqcrystals_kyber_ref_common/indcpa.c @@ -200,10 +200,13 @@ void gen_matrix(polyvec *a, const uint8_t seed[KYBER_SYMBYTES], int transposed) * Arguments: - uint8_t *pk: pointer to output public key * (of length KYBER_INDCPA_PUBLICKEYBYTES bytes) * - uint8_t *sk: pointer to output private key - (of length KYBER_INDCPA_SECRETKEYBYTES bytes) +* (of length KYBER_INDCPA_SECRETKEYBYTES bytes) +* - const uint8_t *coins: pointer to input randomness +* (of length KYBER_SYMBYTES bytes) **************************************************/ -void indcpa_keypair(uint8_t pk[KYBER_INDCPA_PUBLICKEYBYTES], - uint8_t sk[KYBER_INDCPA_SECRETKEYBYTES]) +void indcpa_keypair_derand(uint8_t pk[KYBER_INDCPA_PUBLICKEYBYTES], + uint8_t sk[KYBER_INDCPA_SECRETKEYBYTES], + const uint8_t coins[KYBER_SYMBYTES]) { unsigned int i; uint8_t buf[2*KYBER_SYMBYTES]; @@ -212,8 +215,7 @@ void indcpa_keypair(uint8_t pk[KYBER_INDCPA_PUBLICKEYBYTES], uint8_t nonce = 0; polyvec a[KYBER_K], e, pkpv, skpv; - pq_custom_randombytes(buf, KYBER_SYMBYTES); - hash_g(buf, buf, KYBER_SYMBYTES); + hash_g(buf, coins, KYBER_SYMBYTES); gen_a(a, publicseed); diff --git a/crypto/kyber/pqcrystals_kyber_ref_common/indcpa.h b/crypto/kyber/pqcrystals_kyber_ref_common/indcpa.h index 57bd5ead3a..de808e26ed 100644 --- a/crypto/kyber/pqcrystals_kyber_ref_common/indcpa.h +++ b/crypto/kyber/pqcrystals_kyber_ref_common/indcpa.h @@ -7,9 +7,10 @@ #define gen_matrix KYBER_NAMESPACE(gen_matrix) void gen_matrix(polyvec *a, const uint8_t seed[KYBER_SYMBYTES], int transposed); -#define indcpa_keypair KYBER_NAMESPACE(indcpa_keypair) -void indcpa_keypair(uint8_t pk[KYBER_INDCPA_PUBLICKEYBYTES], - uint8_t sk[KYBER_INDCPA_SECRETKEYBYTES]); +#define indcpa_keypair_derand KYBER_NAMESPACE(indcpa_keypair_derand) +void indcpa_keypair_derand(uint8_t pk[KYBER_INDCPA_PUBLICKEYBYTES], + uint8_t sk[KYBER_INDCPA_SECRETKEYBYTES], + const uint8_t coins[KYBER_SYMBYTES]); #define indcpa_enc KYBER_NAMESPACE(indcpa_enc) void indcpa_enc(uint8_t c[KYBER_INDCPA_BYTES], diff --git a/crypto/kyber/pqcrystals_kyber_ref_common/kem.c b/crypto/kyber/pqcrystals_kyber_ref_common/kem.c index 1e19e0add7..d07cf46fac 100644 --- a/crypto/kyber/pqcrystals_kyber_ref_common/kem.c +++ b/crypto/kyber/pqcrystals_kyber_ref_common/kem.c @@ -1,12 +1,40 @@ #include "kem.h" #include #include +#include #include "indcpa.h" #include "params.h" #include "symmetric.h" #include "verify.h" #include "../../rand_extra/pq_custom_randombytes.h" +/************************************************* +* Name: crypto_kem_keypair_derand +* +* Description: Generates public and private key +* for CCA-secure Kyber key encapsulation mechanism +* +* Arguments: - uint8_t *pk: pointer to output public key +* (an already allocated array of KYBER_PUBLICKEYBYTES bytes) +* - uint8_t *sk: pointer to output private key +* (an already allocated array of KYBER_SECRETKEYBYTES bytes) +* - uint8_t *coins: pointer to input randomness +* (an already allocated array filled with 2*KYBER_SYMBYTES random bytes) +** +* Returns 0 (success) +**************************************************/ +int crypto_kem_keypair_derand(uint8_t *pk, + uint8_t *sk, + const uint8_t coins[2*KYBER_SYMBYTES]) +{ + indcpa_keypair_derand(pk, sk, coins); + memcpy(sk+KYBER_INDCPA_SECRETKEYBYTES, pk, KYBER_PUBLICKEYBYTES); + hash_h(sk+KYBER_SECRETKEYBYTES-2*KYBER_SYMBYTES, pk, KYBER_PUBLICKEYBYTES); + /* Value z for pseudo-random output on reject */ + memcpy(sk + KYBER_SECRETKEYBYTES - KYBER_SYMBYTES, coins + KYBER_SYMBYTES, KYBER_SYMBYTES); + return 0; +} + /************************************************* * Name: crypto_kem_keypair * @@ -23,18 +51,15 @@ int crypto_kem_keypair(uint8_t *pk, uint8_t *sk) { - size_t i; - indcpa_keypair(pk, sk); - for(i=0;i