kyber512r3_polyvec.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. #include <stdint.h>
  2. #include "kyber512r3_params.h"
  3. #include "kyber512r3_poly.h"
  4. #include "kyber512r3_polyvec.h"
  5. S2N_ENSURE_PORTABLE_OPTIMIZATIONS
  6. /*************************************************
  7. * Name: polyvec_compress
  8. *
  9. * Description: Compress and serialize vector of polynomials
  10. *
  11. * Arguments: - uint8_t *r: pointer to output byte array
  12. * (needs space for S2N_KYBER_512_R3_POLYVECCOMPRESSEDBYTES)
  13. * - polyvec *a: pointer to input vector of polynomials
  14. **************************************************/
  15. void polyvec_compress(uint8_t r[S2N_KYBER_512_R3_POLYVECCOMPRESSEDBYTES], polyvec *a) {
  16. polyvec_csubq(a);
  17. uint16_t t[4];
  18. for (unsigned int i = 0; i < S2N_KYBER_512_R3_K; i++) {
  19. for (unsigned int j = 0; j < S2N_KYBER_512_R3_N / 4; j++) {
  20. for (unsigned int k = 0; k < 4; k++)
  21. t[k] = ((((uint32_t)a->vec[i].coeffs[4 * j + k] << 10) + S2N_KYBER_512_R3_Q / 2)
  22. / S2N_KYBER_512_R3_Q) & 0x3ff;
  23. r[0] = (t[0] >> 0);
  24. r[1] = (t[0] >> 8) | (t[1] << 2);
  25. r[2] = (t[1] >> 6) | (t[2] << 4);
  26. r[3] = (t[2] >> 4) | (t[3] << 6);
  27. r[4] = (t[3] >> 2);
  28. r += 5;
  29. }
  30. }
  31. }
  32. /*************************************************
  33. * Name: polyvec_decompress
  34. *
  35. * Description: De-serialize and decompress vector of polynomials;
  36. * approximate inverse of polyvec_compress
  37. *
  38. * Arguments: - polyvec *r: pointer to output vector of polynomials
  39. * - const uint8_t *a: pointer to input byte array
  40. * (of length S2N_KYBER_512_R3_POLYVECCOMPRESSEDBYTES)
  41. **************************************************/
  42. void polyvec_decompress(polyvec *r, const uint8_t a[S2N_KYBER_512_R3_POLYVECCOMPRESSEDBYTES]) {
  43. uint16_t t[4];
  44. for (unsigned int i = 0; i < S2N_KYBER_512_R3_K; i++) {
  45. for (unsigned int j = 0; j < S2N_KYBER_512_R3_N / 4; j++) {
  46. t[0] = (a[0] >> 0) | ((uint16_t)a[1] << 8);
  47. t[1] = (a[1] >> 2) | ((uint16_t)a[2] << 6);
  48. t[2] = (a[2] >> 4) | ((uint16_t)a[3] << 4);
  49. t[3] = (a[3] >> 6) | ((uint16_t)a[4] << 2);
  50. a += 5;
  51. for (unsigned int k = 0; k < 4; k++) {
  52. r->vec[i].coeffs[4 * j + k] = ((uint32_t)(t[k] & 0x3FF) * S2N_KYBER_512_R3_Q + 512) >> 10;
  53. }
  54. }
  55. }
  56. }
  57. /*************************************************
  58. * Name: polyvec_tobytes
  59. *
  60. * Description: Serialize vector of polynomials
  61. *
  62. * Arguments: - uint8_t *r: pointer to output byte array
  63. * (needs space for S2N_KYBER_512_R3_POLYVECBYTES)
  64. * - polyvec *a: pointer to input vector of polynomials
  65. **************************************************/
  66. void polyvec_tobytes(uint8_t r[S2N_KYBER_512_R3_POLYVECBYTES], polyvec *a) {
  67. for (unsigned int i = 0; i < S2N_KYBER_512_R3_K; i++) {
  68. poly_tobytes(r + i * S2N_KYBER_512_R3_POLYBYTES, &a->vec[i]);
  69. }
  70. }
  71. /*************************************************
  72. * Name: polyvec_frombytes
  73. *
  74. * Description: De-serialize vector of polynomials;
  75. * inverse of polyvec_tobytes
  76. *
  77. * Arguments: - uint8_t *r: pointer to output byte array
  78. * - const polyvec *a: pointer to input vector of polynomials
  79. * (of length S2N_KYBER_512_R3_POLYVECBYTES)
  80. **************************************************/
  81. void polyvec_frombytes(polyvec *r, const uint8_t a[S2N_KYBER_512_R3_POLYVECBYTES]) {
  82. for (unsigned int i = 0; i < S2N_KYBER_512_R3_K; i++) {
  83. poly_frombytes(&r->vec[i], a + i * S2N_KYBER_512_R3_POLYBYTES);
  84. }
  85. }
  86. /*************************************************
  87. * Name: polyvec_ntt
  88. *
  89. * Description: Apply forward NTT to all elements of a vector of polynomials
  90. *
  91. * Arguments: - polyvec *r: pointer to in/output vector of polynomials
  92. **************************************************/
  93. void polyvec_ntt(polyvec *r) {
  94. for (unsigned int i = 0; i < S2N_KYBER_512_R3_K; i++) {
  95. poly_ntt(&r->vec[i]);
  96. }
  97. }
  98. /*************************************************
  99. * Name: polyvec_invntt_tomont
  100. *
  101. * Description: Apply inverse NTT to all elements of a vector of polynomials
  102. * and multiply by Montgomery factor 2^16
  103. *
  104. * Arguments: - polyvec *r: pointer to in/output vector of polynomials
  105. **************************************************/
  106. void polyvec_invntt_tomont(polyvec *r) {
  107. for (unsigned int i = 0; i < S2N_KYBER_512_R3_K; i++) {
  108. poly_invntt_tomont(&r->vec[i]);
  109. }
  110. }
  111. /*************************************************
  112. * Name: polyvec_pointwise_acc_montgomery
  113. *
  114. * Description: Pointwise multiply elements of a and b, accumulate into r,
  115. * and multiply by 2^-16.
  116. *
  117. * Arguments: - poly *r: pointer to output polynomial
  118. * - const polyvec *a: pointer to first input vector of polynomials
  119. * - const polyvec *b: pointer to second input vector of polynomials
  120. **************************************************/
  121. void polyvec_pointwise_acc_montgomery(poly *r, const polyvec *a, const polyvec *b) {
  122. poly t;
  123. poly_basemul_montgomery(r, &a->vec[0], &b->vec[0]);
  124. for (unsigned int i = 1; i < S2N_KYBER_512_R3_K; i++) {
  125. poly_basemul_montgomery(&t, &a->vec[i], &b->vec[i]);
  126. poly_add(r, r, &t);
  127. }
  128. poly_reduce(r);
  129. }
  130. /*************************************************
  131. * Name: polyvec_reduce
  132. *
  133. * Description: Applies Barrett reduction to each coefficient
  134. * of each element of a vector of polynomials
  135. * for details of the Barrett reduction see comments in reduce.c
  136. *
  137. * Arguments: - poly *r: pointer to input/output polynomial
  138. **************************************************/
  139. void polyvec_reduce(polyvec *r) {
  140. for (unsigned int i = 0; i < S2N_KYBER_512_R3_K; i++) {
  141. poly_reduce(&r->vec[i]);
  142. }
  143. }
  144. /*************************************************
  145. * Name: polyvec_csubq
  146. *
  147. * Description: Applies conditional subtraction of q to each coefficient
  148. * of each element of a vector of polynomials
  149. * for details of conditional subtraction of q see comments in
  150. * reduce.c
  151. *
  152. * Arguments: - poly *r: pointer to input/output polynomial
  153. **************************************************/
  154. void polyvec_csubq(polyvec *r) {
  155. for (unsigned int i = 0; i < S2N_KYBER_512_R3_K; i++) {
  156. poly_csubq(&r->vec[i]);
  157. }
  158. }
  159. /*************************************************
  160. * Name: polyvec_add
  161. *
  162. * Description: Add vectors of polynomials
  163. *
  164. * Arguments: - polyvec *r: pointer to output vector of polynomials
  165. * - const polyvec *a: pointer to first input vector of polynomials
  166. * - const polyvec *b: pointer to second input vector of polynomials
  167. **************************************************/
  168. void polyvec_add(polyvec *r, const polyvec *a, const polyvec *b) {
  169. for (unsigned int i = 0; i < S2N_KYBER_512_R3_K; i++) {
  170. poly_add(&r->vec[i], &a->vec[i], &b->vec[i]);
  171. }
  172. }