Skip to content
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

Implement low-level derand API for Kyber #1552

Merged
merged 5 commits into from
May 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions crypto/kyber/pqcrystals_kyber_ref_common/indcpa.c
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand All @@ -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);

Expand Down
7 changes: 4 additions & 3 deletions crypto/kyber/pqcrystals_kyber_ref_common/indcpa.h
Original file line number Diff line number Diff line change
Expand Up @@ -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],
Expand Down
78 changes: 65 additions & 13 deletions crypto/kyber/pqcrystals_kyber_ref_common/kem.c
Original file line number Diff line number Diff line change
@@ -1,12 +1,40 @@
#include "kem.h"
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#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);
andrewhop marked this conversation as resolved.
Show resolved Hide resolved
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
*
Expand All @@ -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<KYBER_INDCPA_PUBLICKEYBYTES;i++)
sk[i+KYBER_INDCPA_SECRETKEYBYTES] = pk[i];
hash_h(sk+KYBER_SECRETKEYBYTES-2*KYBER_SYMBYTES, pk, KYBER_PUBLICKEYBYTES);
/* Value z for pseudo-random output on reject */
pq_custom_randombytes(sk+KYBER_SECRETKEYBYTES-KYBER_SYMBYTES, KYBER_SYMBYTES);
uint8_t coins[2*KYBER_SYMBYTES];
pq_custom_randombytes(coins, KYBER_SYMBYTES);
pq_custom_randombytes(coins + KYBER_SYMBYTES, KYBER_SYMBYTES);
Comment on lines +55 to +56
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There a reason not for this to just be a single call for 2*KYBER_SYMBYTES?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, Andrew asked the same thing :) #1552 (comment).

crypto_kem_keypair_derand(pk, sk, coins);
return 0;
}

/*************************************************
* Name: crypto_kem_enc
* Name: crypto_kem_enc_derand
*
* Description: Generates cipher text and shared
* secret for given public key
Expand All @@ -45,20 +70,22 @@ int crypto_kem_keypair(uint8_t *pk,
* (an already allocated array of KYBER_SSBYTES bytes)
* - const uint8_t *pk: pointer to input public key
* (an already allocated array of KYBER_PUBLICKEYBYTES bytes)
* - const uint8_t *coins: pointer to input randomness
* (an already allocated array filled with KYBER_SYMBYTES random bytes)
*
* Returns 0 (success)
**************************************************/
int crypto_kem_enc(uint8_t *ct,
uint8_t *ss,
const uint8_t *pk)
int crypto_kem_enc_derand(uint8_t *ct,
uint8_t *ss,
const uint8_t *pk,
const uint8_t coins[KYBER_SYMBYTES])
{
uint8_t buf[2*KYBER_SYMBYTES];
/* Will contain key, coins */
uint8_t kr[2*KYBER_SYMBYTES];

pq_custom_randombytes(buf, KYBER_SYMBYTES);
/* Don't release system RNG output */
hash_h(buf, buf, KYBER_SYMBYTES);
hash_h(buf, coins, KYBER_SYMBYTES);

/* Multitarget countermeasure for coins + contributory KEM */
hash_h(buf+KYBER_SYMBYTES, pk, KYBER_PUBLICKEYBYTES);
Expand All @@ -74,6 +101,31 @@ int crypto_kem_enc(uint8_t *ct,
return 0;
}

/*************************************************
* Name: crypto_kem_enc
*
* Description: Generates cipher text and shared
* secret for given public key
*
* Arguments: - uint8_t *ct: pointer to output cipher text
* (an already allocated array of KYBER_CIPHERTEXTBYTES bytes)
* - uint8_t *ss: pointer to output shared secret
* (an already allocated array of KYBER_SSBYTES bytes)
* - const uint8_t *pk: pointer to input public key
* (an already allocated array of KYBER_PUBLICKEYBYTES bytes)
*
* Returns 0 (success)
**************************************************/
int crypto_kem_enc(uint8_t *ct,
uint8_t *ss,
const uint8_t *pk)
{
uint8_t coins[KYBER_SYMBYTES];
pq_custom_randombytes(coins, KYBER_SYMBYTES);
crypto_kem_enc_derand(ct, ss, pk, coins);
return 0;
}

/*************************************************
* Name: crypto_kem_dec
*
Expand Down
6 changes: 6 additions & 0 deletions crypto/kyber/pqcrystals_kyber_ref_common/kem.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,15 @@
#endif
#endif

#define crypto_kem_keypair_derand KYBER_NAMESPACE(keypair_derand)
int crypto_kem_keypair_derand(uint8_t *pk, uint8_t *sk, const uint8_t coins[2*KYBER_SYMBYTES]);

#define crypto_kem_keypair KYBER_NAMESPACE(keypair)
int crypto_kem_keypair(uint8_t *pk, uint8_t *sk);

#define crypto_kem_enc_derand KYBER_NAMESPACE(enc_derand)
int crypto_kem_enc_derand(uint8_t *ct, uint8_t *ss, const uint8_t *pk, const uint8_t coins[KYBER_SYMBYTES]);

#define crypto_kem_enc KYBER_NAMESPACE(enc)
int crypto_kem_enc(uint8_t *ct, uint8_t *ss, const uint8_t *pk);

Expand Down
Loading