123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- #include <stddef.h>
- #include <stdint.h>
- #include "kyber512r3_indcpa.h"
- #include "kyber512r3_indcpa_avx2.h"
- #include "kyber512r3_params.h"
- #include "kyber512r3_symmetric.h"
- #include "pq-crypto/s2n_pq.h"
- #include "pq-crypto/s2n_pq_random.h"
- #include "tls/s2n_kem.h"
- #include "utils/s2n_safety.h"
- S2N_ENSURE_PORTABLE_OPTIMIZATIONS
- /*************************************************
- * Name: crypto_kem_keypair
- *
- * Description: Generates public and private key
- * for CCA-secure Kyber key encapsulation mechanism
- *
- * Arguments: - unsigned char *pk: pointer to output public key
- * (an already allocated array of S2N_KYBER_512_R3_PUBLIC_KEY_BYTES bytes)
- * - unsigned char *sk: pointer to output private key
- * (an already allocated array of S2N_KYBER_512_R3_SECRET_KEY_BYTES bytes)
- *
- * Returns 0 (success)
- **************************************************/
- int s2n_kyber_512_r3_crypto_kem_keypair(const struct s2n_kem *kem, uint8_t *pk, uint8_t *sk)
- {
- POSIX_ENSURE(s2n_pq_is_enabled(), S2N_ERR_PQ_DISABLED);
- #if defined(S2N_KYBER512R3_AVX2_BMI2)
- if (s2n_kyber512r3_is_avx2_bmi2_enabled()) {
- POSIX_GUARD(indcpa_keypair_avx2(pk, sk));
- } else
- #endif
- {
- POSIX_GUARD(indcpa_keypair(pk, sk));
- }
- for (size_t i = 0; i < S2N_KYBER_512_R3_INDCPA_PUBLICKEYBYTES; i++) {
- sk[i + S2N_KYBER_512_R3_INDCPA_SECRETKEYBYTES] = pk[i];
- }
- sha3_256(sk + S2N_KYBER_512_R3_SECRET_KEY_BYTES - 2 * S2N_KYBER_512_R3_SYMBYTES, pk, S2N_KYBER_512_R3_PUBLIC_KEY_BYTES);
- /* Value z for pseudo-random output on reject */
- POSIX_GUARD_RESULT(s2n_get_random_bytes(sk + S2N_KYBER_512_R3_SECRET_KEY_BYTES - S2N_KYBER_512_R3_SYMBYTES, S2N_KYBER_512_R3_SYMBYTES));
- return S2N_SUCCESS;
- }
- /*************************************************
- * Name: crypto_kem_enc
- *
- * Description: Generates cipher text and shared
- * secret for given public key
- *
- * Arguments: - unsigned char *ct: pointer to output cipher text
- * (an already allocated array of S2N_KYBER_512_R3_CIPHERTEXT_BYTES bytes)
- * - unsigned char *ss: pointer to output shared secret
- * (an already allocated array of S2N_KYBER_512_R3_SHARED_SECRET_BYTES bytes)
- * - const unsigned char *pk: pointer to input public key
- * (an already allocated array of S2N_KYBER_512_R3_PUBLIC_KEY_BYTES bytes)
- *
- * Returns 0 (success)
- **************************************************/
- int s2n_kyber_512_r3_crypto_kem_enc(const struct s2n_kem *kem, uint8_t *ct, uint8_t *ss,
- const uint8_t *pk)
- {
- POSIX_ENSURE(s2n_pq_is_enabled(), S2N_ERR_PQ_DISABLED);
- uint8_t buf[2 * S2N_KYBER_512_R3_SYMBYTES];
- /* Will contain key, coins */
- uint8_t kr[2 * S2N_KYBER_512_R3_SYMBYTES];
- POSIX_GUARD_RESULT(s2n_get_random_bytes(buf, S2N_KYBER_512_R3_SYMBYTES));
- /* Don't release system RNG output */
- sha3_256(buf, buf, S2N_KYBER_512_R3_SYMBYTES);
- /* Multitarget countermeasure for coins + contributory KEM */
- sha3_256(buf + S2N_KYBER_512_R3_SYMBYTES, pk, S2N_KYBER_512_R3_PUBLIC_KEY_BYTES);
- sha3_512(kr, buf, 2 * S2N_KYBER_512_R3_SYMBYTES);
- /* coins are in kr+S2N_KYBER_512_R3_SYMBYTES */
- #if defined(S2N_KYBER512R3_AVX2_BMI2)
- if (s2n_kyber512r3_is_avx2_bmi2_enabled()) {
- indcpa_enc_avx2(ct, buf, pk, kr + S2N_KYBER_512_R3_SYMBYTES);
- } else
- #endif
- {
- indcpa_enc(ct, buf, pk, kr + S2N_KYBER_512_R3_SYMBYTES);
- }
- /* overwrite coins in kr with H(c) */
- sha3_256(kr + S2N_KYBER_512_R3_SYMBYTES, ct, S2N_KYBER_512_R3_CIPHERTEXT_BYTES);
- /* hash concatenation of pre-k and H(c) to k */
- shake256(ss, S2N_KYBER_512_R3_SSBYTES, kr, 2 * S2N_KYBER_512_R3_SYMBYTES);
- return S2N_SUCCESS;
- }
- /*************************************************
- * Name: crypto_kem_dec
- *
- * Description: Generates shared secret for given
- * cipher text and private key
- *
- * Arguments: - unsigned char *ss: pointer to output shared secret
- * (an already allocated array of S2N_KYBER_512_R3_SHARED_SECRET_BYTES bytes)
- * - const unsigned char *ct: pointer to input cipher text
- * (an already allocated array of S2N_KYBER_512_R3_CIPHERTEXT_BYTES bytes)
- * - const unsigned char *sk: pointer to input private key
- * (an already allocated array of S2N_KYBER_512_R3_SECRET_KEY_BYTES bytes)
- *
- * Returns 0.
- *
- * On failure, ss will contain a pseudo-random value.
- **************************************************/
- int s2n_kyber_512_r3_crypto_kem_dec(const struct s2n_kem *kem, uint8_t *ss, const uint8_t *ct,
- const uint8_t *sk)
- {
- POSIX_ENSURE(s2n_pq_is_enabled(), S2N_ERR_PQ_DISABLED);
- uint8_t buf[2 * S2N_KYBER_512_R3_SYMBYTES];
- /* Will contain key, coins */
- uint8_t kr[2 * S2N_KYBER_512_R3_SYMBYTES];
- uint8_t cmp[S2N_KYBER_512_R3_CIPHERTEXT_BYTES];
- const uint8_t *pk = sk + S2N_KYBER_512_R3_INDCPA_SECRETKEYBYTES;
- #if defined(S2N_KYBER512R3_AVX2_BMI2)
- if (s2n_kyber512r3_is_avx2_bmi2_enabled()) {
- indcpa_dec_avx2(buf, ct, sk);
- } else
- #endif
- {
- indcpa_dec(buf, ct, sk);
- }
- /* Multitarget countermeasure for coins + contributory KEM */
- for (size_t i = 0; i < S2N_KYBER_512_R3_SYMBYTES; i++) {
- buf[S2N_KYBER_512_R3_SYMBYTES + i] = sk[S2N_KYBER_512_R3_SECRET_KEY_BYTES - 2 * S2N_KYBER_512_R3_SYMBYTES + i];
- }
- sha3_512(kr, buf, 2 * S2N_KYBER_512_R3_SYMBYTES);
- /* coins are in kr+S2N_KYBER_512_R3_SYMBYTES */
- #if defined(S2N_KYBER512R3_AVX2_BMI2)
- if (s2n_kyber512r3_is_avx2_bmi2_enabled()) {
- indcpa_enc_avx2(cmp, buf, pk, kr + S2N_KYBER_512_R3_SYMBYTES);
- } else
- #endif
- {
- indcpa_enc(cmp, buf, pk, kr + S2N_KYBER_512_R3_SYMBYTES);
- }
- /* If ct and cmp are equal (dont_copy = 1), decryption has succeeded and we do NOT overwrite pre-k below.
- * If ct and cmp are not equal (dont_copy = 0), decryption fails and we do overwrite pre-k. */
- int dont_copy = s2n_constant_time_equals(ct, cmp, S2N_KYBER_512_R3_CIPHERTEXT_BYTES);
- /* overwrite coins in kr with H(c) */
- sha3_256(kr + S2N_KYBER_512_R3_SYMBYTES, ct, S2N_KYBER_512_R3_CIPHERTEXT_BYTES);
- /* Overwrite pre-k with z on re-encryption failure */
- POSIX_GUARD(s2n_constant_time_copy_or_dont(kr, sk + S2N_KYBER_512_R3_SECRET_KEY_BYTES - S2N_KYBER_512_R3_SYMBYTES,
- S2N_KYBER_512_R3_SYMBYTES, dont_copy));
- /* hash concatenation of pre-k and H(c) to k */
- shake256(ss, S2N_KYBER_512_R3_SSBYTES, kr, 2 * S2N_KYBER_512_R3_SYMBYTES);
- return S2N_SUCCESS;
- }
|