kyber512r3_kem.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. #include <stddef.h>
  2. #include <stdint.h>
  3. #include "kyber512r3_indcpa.h"
  4. #include "kyber512r3_indcpa_avx2.h"
  5. #include "kyber512r3_params.h"
  6. #include "kyber512r3_symmetric.h"
  7. #include "pq-crypto/s2n_pq.h"
  8. #include "pq-crypto/s2n_pq_random.h"
  9. #include "tls/s2n_kem.h"
  10. #include "utils/s2n_safety.h"
  11. S2N_ENSURE_PORTABLE_OPTIMIZATIONS
  12. /*************************************************
  13. * Name: crypto_kem_keypair
  14. *
  15. * Description: Generates public and private key
  16. * for CCA-secure Kyber key encapsulation mechanism
  17. *
  18. * Arguments: - unsigned char *pk: pointer to output public key
  19. * (an already allocated array of S2N_KYBER_512_R3_PUBLIC_KEY_BYTES bytes)
  20. * - unsigned char *sk: pointer to output private key
  21. * (an already allocated array of S2N_KYBER_512_R3_SECRET_KEY_BYTES bytes)
  22. *
  23. * Returns 0 (success)
  24. **************************************************/
  25. int s2n_kyber_512_r3_crypto_kem_keypair(const struct s2n_kem *kem, uint8_t *pk, uint8_t *sk)
  26. {
  27. POSIX_ENSURE(s2n_pq_is_enabled(), S2N_ERR_PQ_DISABLED);
  28. #if defined(S2N_KYBER512R3_AVX2_BMI2)
  29. if (s2n_kyber512r3_is_avx2_bmi2_enabled()) {
  30. POSIX_GUARD(indcpa_keypair_avx2(pk, sk));
  31. } else
  32. #endif
  33. {
  34. POSIX_GUARD(indcpa_keypair(pk, sk));
  35. }
  36. for (size_t i = 0; i < S2N_KYBER_512_R3_INDCPA_PUBLICKEYBYTES; i++) {
  37. sk[i + S2N_KYBER_512_R3_INDCPA_SECRETKEYBYTES] = pk[i];
  38. }
  39. sha3_256(sk + S2N_KYBER_512_R3_SECRET_KEY_BYTES - 2 * S2N_KYBER_512_R3_SYMBYTES, pk, S2N_KYBER_512_R3_PUBLIC_KEY_BYTES);
  40. /* Value z for pseudo-random output on reject */
  41. 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));
  42. return S2N_SUCCESS;
  43. }
  44. /*************************************************
  45. * Name: crypto_kem_enc
  46. *
  47. * Description: Generates cipher text and shared
  48. * secret for given public key
  49. *
  50. * Arguments: - unsigned char *ct: pointer to output cipher text
  51. * (an already allocated array of S2N_KYBER_512_R3_CIPHERTEXT_BYTES bytes)
  52. * - unsigned char *ss: pointer to output shared secret
  53. * (an already allocated array of S2N_KYBER_512_R3_SHARED_SECRET_BYTES bytes)
  54. * - const unsigned char *pk: pointer to input public key
  55. * (an already allocated array of S2N_KYBER_512_R3_PUBLIC_KEY_BYTES bytes)
  56. *
  57. * Returns 0 (success)
  58. **************************************************/
  59. int s2n_kyber_512_r3_crypto_kem_enc(const struct s2n_kem *kem, uint8_t *ct, uint8_t *ss,
  60. const uint8_t *pk)
  61. {
  62. POSIX_ENSURE(s2n_pq_is_enabled(), S2N_ERR_PQ_DISABLED);
  63. uint8_t buf[2 * S2N_KYBER_512_R3_SYMBYTES];
  64. /* Will contain key, coins */
  65. uint8_t kr[2 * S2N_KYBER_512_R3_SYMBYTES];
  66. POSIX_GUARD_RESULT(s2n_get_random_bytes(buf, S2N_KYBER_512_R3_SYMBYTES));
  67. /* Don't release system RNG output */
  68. sha3_256(buf, buf, S2N_KYBER_512_R3_SYMBYTES);
  69. /* Multitarget countermeasure for coins + contributory KEM */
  70. sha3_256(buf + S2N_KYBER_512_R3_SYMBYTES, pk, S2N_KYBER_512_R3_PUBLIC_KEY_BYTES);
  71. sha3_512(kr, buf, 2 * S2N_KYBER_512_R3_SYMBYTES);
  72. /* coins are in kr+S2N_KYBER_512_R3_SYMBYTES */
  73. #if defined(S2N_KYBER512R3_AVX2_BMI2)
  74. if (s2n_kyber512r3_is_avx2_bmi2_enabled()) {
  75. indcpa_enc_avx2(ct, buf, pk, kr + S2N_KYBER_512_R3_SYMBYTES);
  76. } else
  77. #endif
  78. {
  79. indcpa_enc(ct, buf, pk, kr + S2N_KYBER_512_R3_SYMBYTES);
  80. }
  81. /* overwrite coins in kr with H(c) */
  82. sha3_256(kr + S2N_KYBER_512_R3_SYMBYTES, ct, S2N_KYBER_512_R3_CIPHERTEXT_BYTES);
  83. /* hash concatenation of pre-k and H(c) to k */
  84. shake256(ss, S2N_KYBER_512_R3_SSBYTES, kr, 2 * S2N_KYBER_512_R3_SYMBYTES);
  85. return S2N_SUCCESS;
  86. }
  87. /*************************************************
  88. * Name: crypto_kem_dec
  89. *
  90. * Description: Generates shared secret for given
  91. * cipher text and private key
  92. *
  93. * Arguments: - unsigned char *ss: pointer to output shared secret
  94. * (an already allocated array of S2N_KYBER_512_R3_SHARED_SECRET_BYTES bytes)
  95. * - const unsigned char *ct: pointer to input cipher text
  96. * (an already allocated array of S2N_KYBER_512_R3_CIPHERTEXT_BYTES bytes)
  97. * - const unsigned char *sk: pointer to input private key
  98. * (an already allocated array of S2N_KYBER_512_R3_SECRET_KEY_BYTES bytes)
  99. *
  100. * Returns 0.
  101. *
  102. * On failure, ss will contain a pseudo-random value.
  103. **************************************************/
  104. int s2n_kyber_512_r3_crypto_kem_dec(const struct s2n_kem *kem, uint8_t *ss, const uint8_t *ct,
  105. const uint8_t *sk)
  106. {
  107. POSIX_ENSURE(s2n_pq_is_enabled(), S2N_ERR_PQ_DISABLED);
  108. uint8_t buf[2 * S2N_KYBER_512_R3_SYMBYTES];
  109. /* Will contain key, coins */
  110. uint8_t kr[2 * S2N_KYBER_512_R3_SYMBYTES];
  111. uint8_t cmp[S2N_KYBER_512_R3_CIPHERTEXT_BYTES];
  112. const uint8_t *pk = sk + S2N_KYBER_512_R3_INDCPA_SECRETKEYBYTES;
  113. #if defined(S2N_KYBER512R3_AVX2_BMI2)
  114. if (s2n_kyber512r3_is_avx2_bmi2_enabled()) {
  115. indcpa_dec_avx2(buf, ct, sk);
  116. } else
  117. #endif
  118. {
  119. indcpa_dec(buf, ct, sk);
  120. }
  121. /* Multitarget countermeasure for coins + contributory KEM */
  122. for (size_t i = 0; i < S2N_KYBER_512_R3_SYMBYTES; i++) {
  123. buf[S2N_KYBER_512_R3_SYMBYTES + i] = sk[S2N_KYBER_512_R3_SECRET_KEY_BYTES - 2 * S2N_KYBER_512_R3_SYMBYTES + i];
  124. }
  125. sha3_512(kr, buf, 2 * S2N_KYBER_512_R3_SYMBYTES);
  126. /* coins are in kr+S2N_KYBER_512_R3_SYMBYTES */
  127. #if defined(S2N_KYBER512R3_AVX2_BMI2)
  128. if (s2n_kyber512r3_is_avx2_bmi2_enabled()) {
  129. indcpa_enc_avx2(cmp, buf, pk, kr + S2N_KYBER_512_R3_SYMBYTES);
  130. } else
  131. #endif
  132. {
  133. indcpa_enc(cmp, buf, pk, kr + S2N_KYBER_512_R3_SYMBYTES);
  134. }
  135. /* If ct and cmp are equal (dont_copy = 1), decryption has succeeded and we do NOT overwrite pre-k below.
  136. * If ct and cmp are not equal (dont_copy = 0), decryption fails and we do overwrite pre-k. */
  137. int dont_copy = s2n_constant_time_equals(ct, cmp, S2N_KYBER_512_R3_CIPHERTEXT_BYTES);
  138. /* overwrite coins in kr with H(c) */
  139. sha3_256(kr + S2N_KYBER_512_R3_SYMBYTES, ct, S2N_KYBER_512_R3_CIPHERTEXT_BYTES);
  140. /* Overwrite pre-k with z on re-encryption failure */
  141. POSIX_GUARD(s2n_constant_time_copy_or_dont(kr, sk + S2N_KYBER_512_R3_SECRET_KEY_BYTES - S2N_KYBER_512_R3_SYMBYTES,
  142. S2N_KYBER_512_R3_SYMBYTES, dont_copy));
  143. /* hash concatenation of pre-k and H(c) to k */
  144. shake256(ss, S2N_KYBER_512_R3_SSBYTES, kr, 2 * S2N_KYBER_512_R3_SYMBYTES);
  145. return S2N_SUCCESS;
  146. }