kyber512r3_cbd.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. #include <stdint.h>
  2. #include "kyber512r3_params.h"
  3. #include "kyber512r3_cbd.h"
  4. S2N_ENSURE_PORTABLE_OPTIMIZATIONS
  5. /*************************************************
  6. * Name: load32_littleendian
  7. *
  8. * Description: load 4 bytes into a 32-bit integer
  9. * in little-endian order
  10. *
  11. * Arguments: - const uint8_t *x: pointer to input byte array
  12. *
  13. * Returns 32-bit unsigned integer loaded from x
  14. **************************************************/
  15. static uint32_t load32_littleendian(const uint8_t x[4]) {
  16. uint32_t r;
  17. r = (uint32_t)x[0];
  18. r |= (uint32_t)x[1] << 8;
  19. r |= (uint32_t)x[2] << 16;
  20. r |= (uint32_t)x[3] << 24;
  21. return r;
  22. }
  23. /*************************************************
  24. * Name: load24_littleendian
  25. *
  26. * Description: load 3 bytes into a 32-bit integer
  27. * in little-endian order
  28. * This function is only needed for Kyber-512
  29. *
  30. * Arguments: - const uint8_t *x: pointer to input byte array
  31. *
  32. * Returns 32-bit unsigned integer loaded from x (most significant byte is zero)
  33. **************************************************/
  34. static uint32_t load24_littleendian(const uint8_t x[3]) {
  35. uint32_t r;
  36. r = (uint32_t)x[0];
  37. r |= (uint32_t)x[1] << 8;
  38. r |= (uint32_t)x[2] << 16;
  39. return r;
  40. }
  41. /*************************************************
  42. * Name: cbd2
  43. *
  44. * Description: Given an array of uniformly random bytes, compute
  45. * polynomial with coefficients distributed according to
  46. * a centered binomial distribution with parameter eta=2
  47. *
  48. * Arguments: - poly *r: pointer to output polynomial
  49. * - const uint8_t *buf: pointer to input byte array
  50. **************************************************/
  51. static void cbd2(poly *r, const uint8_t buf[2 * S2N_KYBER_512_R3_N / 4]) {
  52. unsigned int i, j;
  53. for (i = 0; i < S2N_KYBER_512_R3_N / 8; i++) {
  54. uint32_t t = load32_littleendian(buf + 4 * i);
  55. uint32_t d = t & 0x55555555;
  56. d += (t >> 1) & 0x55555555;
  57. for (j = 0; j < 8; j++) {
  58. int16_t a = (d >> (4 * j + 0)) & 0x3;
  59. int16_t b = (d >> (4 * j + 2)) & 0x3;
  60. r->coeffs[8 * i + j] = a - b;
  61. }
  62. }
  63. }
  64. /*************************************************
  65. * Name: cbd3
  66. *
  67. * Description: Given an array of uniformly random bytes, compute
  68. * polynomial with coefficients distributed according to
  69. * a centered binomial distribution with parameter eta=3
  70. * This function is only needed for Kyber-512
  71. *
  72. * Arguments: - poly *r: pointer to output polynomial
  73. * - const uint8_t *buf: pointer to input byte array
  74. **************************************************/
  75. static void cbd3(poly *r, const uint8_t buf[3 * S2N_KYBER_512_R3_N / 4]) {
  76. unsigned int i, j;
  77. for (i = 0; i < S2N_KYBER_512_R3_N / 4; i++) {
  78. uint32_t t = load24_littleendian(buf + 3 * i);
  79. uint32_t d = t & 0x00249249;
  80. d += (t >> 1) & 0x00249249;
  81. d += (t >> 2) & 0x00249249;
  82. for (j = 0; j < 4; j++) {
  83. int16_t a = (d >> (6 * j + 0)) & 0x7;
  84. int16_t b = (d >> (6 * j + 3)) & 0x7;
  85. r->coeffs[4 * i + j] = a - b;
  86. }
  87. }
  88. }
  89. void cbd_eta1(poly *r, const uint8_t buf[S2N_KYBER_512_R3_ETA1 * S2N_KYBER_512_R3_N / 4]) {
  90. cbd3(r, buf);
  91. }
  92. void cbd_eta2(poly *r, const uint8_t buf[S2N_KYBER_512_R3_ETA2 * S2N_KYBER_512_R3_N / 4]) {
  93. cbd2(r, buf);
  94. }