Name the hash functions in the Kyber implementation
When I was experimenting with different hash functions, it was useful to split them out, and I think this is clearer anyway. E.g. there are two uses of SHAKE-256 in the round3 submission, but the spec gives them different names. XOF doesn't get its own abstraction because we need to stream data out of it. ML-KEM similarly names things, though it will replace the KDF with a hash J that only gets applied to the rejection value. Change-Id: I67f1ac0216e05f61557023229572ff5fb36ed529 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/64407 Commit-Queue: David Benjamin <davidben@google.com> Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
committed by
Boringssl LUCI CQ
parent
2d7adaea91
commit
3a035dc523
+28
-20
@@ -28,6 +28,22 @@
|
||||
// See
|
||||
// https://pq-crystals.org/kyber/data/kyber-specification-round3-20210804.pdf
|
||||
|
||||
static void prf(uint8_t *out, size_t out_len, const uint8_t in[33]) {
|
||||
BORINGSSL_keccak(out, out_len, in, 33, boringssl_shake256);
|
||||
}
|
||||
|
||||
static void hash_h(uint8_t out[32], const uint8_t *in, size_t len) {
|
||||
BORINGSSL_keccak(out, 32, in, len, boringssl_sha3_256);
|
||||
}
|
||||
|
||||
static void hash_g(uint8_t out[64], const uint8_t *in, size_t len) {
|
||||
BORINGSSL_keccak(out, 64, in, len, boringssl_sha3_512);
|
||||
}
|
||||
|
||||
static void kdf(uint8_t *out, size_t out_len, const uint8_t *in, size_t len) {
|
||||
BORINGSSL_keccak(out, out_len, in, len, boringssl_shake256);
|
||||
}
|
||||
|
||||
#define DEGREE 256
|
||||
#define RANK 3
|
||||
|
||||
@@ -315,7 +331,7 @@ static void scalar_centered_binomial_distribution_eta_2_with_prf(
|
||||
scalar *out, const uint8_t input[33]) {
|
||||
uint8_t entropy[128];
|
||||
static_assert(sizeof(entropy) == 2 * /*kEta=*/2 * DEGREE / 8, "");
|
||||
BORINGSSL_keccak(entropy, sizeof(entropy), input, 33, boringssl_shake256);
|
||||
prf(entropy, sizeof(entropy), input);
|
||||
|
||||
for (int i = 0; i < DEGREE; i += 2) {
|
||||
uint8_t byte = entropy[i / 2];
|
||||
@@ -611,7 +627,7 @@ void KYBER_generate_key_external_entropy(
|
||||
const uint8_t entropy[KYBER_GENERATE_KEY_ENTROPY]) {
|
||||
struct private_key *priv = private_key_from_external(out_private_key);
|
||||
uint8_t hashed[64];
|
||||
BORINGSSL_keccak(hashed, sizeof(hashed), entropy, 32, boringssl_sha3_512);
|
||||
hash_g(hashed, entropy, 32);
|
||||
const uint8_t *const rho = hashed;
|
||||
const uint8_t *const sigma = hashed + 32;
|
||||
OPENSSL_memcpy(priv->pub.rho, hashed, sizeof(priv->pub.rho));
|
||||
@@ -631,9 +647,8 @@ void KYBER_generate_key_external_entropy(
|
||||
abort();
|
||||
}
|
||||
|
||||
BORINGSSL_keccak(priv->pub.public_key_hash, sizeof(priv->pub.public_key_hash),
|
||||
out_encoded_public_key, KYBER_PUBLIC_KEY_BYTES,
|
||||
boringssl_sha3_256);
|
||||
hash_h(priv->pub.public_key_hash, out_encoded_public_key,
|
||||
KYBER_PUBLIC_KEY_BYTES);
|
||||
OPENSSL_memcpy(priv->fo_failure_secret, entropy + 32, 32);
|
||||
}
|
||||
|
||||
@@ -707,14 +722,11 @@ void KYBER_encap_external_entropy(
|
||||
OPENSSL_memcpy(input + KYBER_ENCAP_ENTROPY, pub->public_key_hash,
|
||||
sizeof(input) - KYBER_ENCAP_ENTROPY);
|
||||
uint8_t prekey_and_randomness[64];
|
||||
BORINGSSL_keccak(prekey_and_randomness, sizeof(prekey_and_randomness), input,
|
||||
sizeof(input), boringssl_sha3_512);
|
||||
hash_g(prekey_and_randomness, input, sizeof(input));
|
||||
encrypt_cpa(out_ciphertext, pub, entropy, prekey_and_randomness + 32);
|
||||
BORINGSSL_keccak(prekey_and_randomness + 32, 32, out_ciphertext,
|
||||
KYBER_CIPHERTEXT_BYTES, boringssl_sha3_256);
|
||||
BORINGSSL_keccak(out_shared_secret, KYBER_SHARED_SECRET_BYTES,
|
||||
prekey_and_randomness, sizeof(prekey_and_randomness),
|
||||
boringssl_shake256);
|
||||
hash_h(prekey_and_randomness + 32, out_ciphertext, KYBER_CIPHERTEXT_BYTES);
|
||||
kdf(out_shared_secret, KYBER_SHARED_SECRET_BYTES, prekey_and_randomness,
|
||||
sizeof(prekey_and_randomness));
|
||||
}
|
||||
|
||||
// Algorithm 6 of the Kyber spec.
|
||||
@@ -749,8 +761,7 @@ void KYBER_decap(uint8_t out_shared_secret[KYBER_SHARED_SECRET_BYTES],
|
||||
OPENSSL_memcpy(decrypted + 32, priv->pub.public_key_hash,
|
||||
sizeof(decrypted) - 32);
|
||||
uint8_t prekey_and_randomness[64];
|
||||
BORINGSSL_keccak(prekey_and_randomness, sizeof(prekey_and_randomness),
|
||||
decrypted, sizeof(decrypted), boringssl_sha3_512);
|
||||
hash_g(prekey_and_randomness, decrypted, sizeof(decrypted));
|
||||
uint8_t expected_ciphertext[KYBER_CIPHERTEXT_BYTES];
|
||||
encrypt_cpa(expected_ciphertext, &priv->pub, decrypted,
|
||||
prekey_and_randomness + 32);
|
||||
@@ -763,10 +774,8 @@ void KYBER_decap(uint8_t out_shared_secret[KYBER_SHARED_SECRET_BYTES],
|
||||
input[i] = constant_time_select_8(mask, prekey_and_randomness[i],
|
||||
priv->fo_failure_secret[i]);
|
||||
}
|
||||
BORINGSSL_keccak(input + 32, 32, ciphertext, KYBER_CIPHERTEXT_BYTES,
|
||||
boringssl_sha3_256);
|
||||
BORINGSSL_keccak(out_shared_secret, KYBER_SHARED_SECRET_BYTES, input,
|
||||
sizeof(input), boringssl_shake256);
|
||||
hash_h(input + 32, ciphertext, KYBER_CIPHERTEXT_BYTES);
|
||||
kdf(out_shared_secret, KYBER_SHARED_SECRET_BYTES, input, sizeof(input));
|
||||
}
|
||||
|
||||
int KYBER_marshal_public_key(CBB *out,
|
||||
@@ -794,8 +803,7 @@ int KYBER_parse_public_key(struct KYBER_public_key *public_key, CBS *in) {
|
||||
CBS_len(in) != 0) {
|
||||
return 0;
|
||||
}
|
||||
BORINGSSL_keccak(pub->public_key_hash, sizeof(pub->public_key_hash),
|
||||
CBS_data(&orig_in), CBS_len(&orig_in), boringssl_sha3_256);
|
||||
hash_h(pub->public_key_hash, CBS_data(&orig_in), CBS_len(&orig_in));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user