You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

167 lines
6.4 KiB

  1. #include "ntt.h"
  2. #include "poly.h"
  3. #include "polyvec.h"
  4. #include <stdint.h>
  5. /*************************************************
  6. * Name: polyvec_compress
  7. *
  8. * Description: Compress and serialize vector of polynomials
  9. *
  10. * Arguments: - uint8_t *r: pointer to output byte array
  11. * - const polyvec *a: pointer to input vector of polynomials
  12. **************************************************/
  13. void PQCLEAN_KYBER76890S_AVX2_polyvec_compress(uint8_t *r, polyvec *a) {
  14. PQCLEAN_KYBER76890S_AVX2_polyvec_csubq(a);
  15. uint16_t t[4];
  16. for (size_t i = 0; i < KYBER_K; i++) {
  17. for (size_t j = 0; j < KYBER_N / 4; j++) {
  18. for (size_t k = 0; k < 4; k++) {
  19. t[k] = ((((uint32_t)a->vec[i].coeffs[4 * j + k] << 10) + KYBER_Q / 2) / KYBER_Q) & 0x3ff;
  20. }
  21. r[5 * j + 0] = (uint8_t)t[0];
  22. r[5 * j + 1] = (uint8_t)((t[0] >> 8) | ((t[1] & 0x3f) << 2));
  23. r[5 * j + 2] = (uint8_t)((t[1] >> 6) | ((t[2] & 0x0f) << 4));
  24. r[5 * j + 3] = (uint8_t)((t[2] >> 4) | ((t[3] & 0x03) << 6));
  25. r[5 * j + 4] = (uint8_t)((t[3] >> 2));
  26. }
  27. r += 320;
  28. }
  29. }
  30. /*************************************************
  31. * Name: polyvec_decompress
  32. *
  33. * Description: De-serialize and decompress vector of polynomials;
  34. * approximate inverse of polyvec_compress
  35. *
  36. * Arguments: - polyvec *r: pointer to output vector of polynomials
  37. * - uint8_t *a: pointer to input byte array
  38. **************************************************/
  39. void PQCLEAN_KYBER76890S_AVX2_polyvec_decompress(polyvec *r, const uint8_t *a) {
  40. for (size_t i = 0; i < KYBER_K; i++) {
  41. for (size_t j = 0; j < KYBER_N / 4; j++) {
  42. r->vec[i].coeffs[4 * j + 0] = (int16_t)( (((a[5 * j + 0] | (((uint32_t)a[5 * j + 1] & 0x03) << 8)) * KYBER_Q) + 512) >> 10);
  43. r->vec[i].coeffs[4 * j + 1] = (int16_t)(((((a[5 * j + 1] >> 2) | (((uint32_t)a[5 * j + 2] & 0x0f) << 6)) * KYBER_Q) + 512) >> 10);
  44. r->vec[i].coeffs[4 * j + 2] = (int16_t)(((((a[5 * j + 2] >> 4) | (((uint32_t)a[5 * j + 3] & 0x3f) << 4)) * KYBER_Q) + 512) >> 10);
  45. r->vec[i].coeffs[4 * j + 3] = (int16_t)(((((a[5 * j + 3] >> 6) | (((uint32_t)a[5 * j + 4] & 0xff) << 2)) * KYBER_Q) + 512) >> 10);
  46. }
  47. a += 320;
  48. }
  49. }
  50. /*************************************************
  51. * Name: polyvec_tobytes
  52. *
  53. * Description: Serialize vector of polynomials
  54. *
  55. * Arguments: - uint8_t *r: pointer to output byte array
  56. * - const polyvec *a: pointer to input vector of polynomials
  57. **************************************************/
  58. void PQCLEAN_KYBER76890S_AVX2_polyvec_tobytes(uint8_t *r, polyvec *a) {
  59. for (size_t i = 0; i < KYBER_K; i++) {
  60. PQCLEAN_KYBER76890S_AVX2_poly_tobytes(r + i * KYBER_POLYBYTES, &a->vec[i]);
  61. }
  62. }
  63. /*************************************************
  64. * Name: polyvec_frombytes
  65. *
  66. * Description: De-serialize vector of polynomials;
  67. * inverse of polyvec_tobytes
  68. *
  69. * Arguments: - uint8_t *r: pointer to output byte array
  70. * - const polyvec *a: pointer to input vector of polynomials
  71. **************************************************/
  72. void PQCLEAN_KYBER76890S_AVX2_polyvec_frombytes(polyvec *r, const uint8_t *a) {
  73. for (size_t i = 0; i < KYBER_K; i++) {
  74. PQCLEAN_KYBER76890S_AVX2_poly_frombytes(&r->vec[i], a + i * KYBER_POLYBYTES);
  75. }
  76. }
  77. /*************************************************
  78. * Name: polyvec_ntt
  79. *
  80. * Description: Apply forward NTT to all elements of a vector of polynomials
  81. *
  82. * Arguments: - polyvec *r: pointer to in/output vector of polynomials
  83. **************************************************/
  84. void PQCLEAN_KYBER76890S_AVX2_polyvec_ntt(polyvec *r) {
  85. for (size_t i = 0; i < KYBER_K; i++) {
  86. PQCLEAN_KYBER76890S_AVX2_poly_ntt(&r->vec[i]);
  87. }
  88. }
  89. /*************************************************
  90. * Name: polyvec_invntt
  91. *
  92. * Description: Apply inverse NTT to all elements of a vector of polynomials
  93. *
  94. * Arguments: - polyvec *r: pointer to in/output vector of polynomials
  95. **************************************************/
  96. void PQCLEAN_KYBER76890S_AVX2_polyvec_invntt(polyvec *r) {
  97. for (size_t i = 0; i < KYBER_K; i++) {
  98. PQCLEAN_KYBER76890S_AVX2_poly_invntt(&r->vec[i]);
  99. }
  100. }
  101. /*************************************************
  102. * Name: polyvec_pointwise_acc
  103. *
  104. * Description: Pointwise multiply elements of a and b and accumulate into r
  105. *
  106. * Arguments: - poly *r: pointer to output polynomial
  107. * - const polyvec *a: pointer to first input vector of polynomials
  108. * - const polyvec *b: pointer to second input vector of polynomials
  109. **************************************************/
  110. void PQCLEAN_KYBER76890S_AVX2_polyvec_pointwise_acc(poly *r, const polyvec *a, const polyvec *b) {
  111. PQCLEAN_KYBER76890S_AVX2_basemul_acc_avx(r->coeffs,
  112. a->vec->coeffs,
  113. b->vec->coeffs,
  114. PQCLEAN_KYBER76890S_AVX2_zetas_exp + 152);
  115. PQCLEAN_KYBER76890S_AVX2_basemul_acc_avx(r->coeffs + 64,
  116. a->vec->coeffs + 64,
  117. b->vec->coeffs + 64,
  118. PQCLEAN_KYBER76890S_AVX2_zetas_exp + 184);
  119. PQCLEAN_KYBER76890S_AVX2_basemul_acc_avx(r->coeffs + 128,
  120. a->vec->coeffs + 128,
  121. b->vec->coeffs + 128,
  122. PQCLEAN_KYBER76890S_AVX2_zetas_exp + 348);
  123. PQCLEAN_KYBER76890S_AVX2_basemul_acc_avx(r->coeffs + 192,
  124. a->vec->coeffs + 192,
  125. b->vec->coeffs + 192,
  126. PQCLEAN_KYBER76890S_AVX2_zetas_exp + 380);
  127. }
  128. // FIXME
  129. void PQCLEAN_KYBER76890S_AVX2_polyvec_reduce(polyvec *r) {
  130. for (size_t i = 0; i < KYBER_K; i++) {
  131. PQCLEAN_KYBER76890S_AVX2_poly_reduce(&r->vec[i]);
  132. }
  133. }
  134. // FIXME
  135. void PQCLEAN_KYBER76890S_AVX2_polyvec_csubq(polyvec *r) {
  136. for (size_t i = 0; i < KYBER_K; i++) {
  137. PQCLEAN_KYBER76890S_AVX2_poly_csubq(&r->vec[i]);
  138. }
  139. }
  140. /*************************************************
  141. * Name: polyvec_add
  142. *
  143. * Description: Add vectors of polynomials
  144. *
  145. * Arguments: - polyvec *r: pointer to output vector of polynomials
  146. * - const polyvec *a: pointer to first input vector of polynomials
  147. * - const polyvec *b: pointer to second input vector of polynomials
  148. **************************************************/
  149. void PQCLEAN_KYBER76890S_AVX2_polyvec_add(polyvec *r, const polyvec *a, const polyvec *b) {
  150. for (size_t i = 0; i < KYBER_K; i++) {
  151. PQCLEAN_KYBER76890S_AVX2_poly_add(&r->vec[i], &a->vec[i], &b->vec[i]);
  152. }
  153. }