Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 

112 linhas
3.3 KiB

  1. #include "cbd.h"
  2. /*************************************************
  3. * Name: load_littleendian
  4. *
  5. * Description: load bytes into a 64-bit integer
  6. * in little-endian order
  7. *
  8. * Arguments: - const unsigned char *x: pointer to input byte array
  9. * - bytes: number of bytes to load, has to be <=
  10. *8
  11. *
  12. * Returns 64-bit unsigned integer loaded from x
  13. **************************************************/
  14. static uint64_t load_littleendian(const unsigned char *x, int bytes) {
  15. int i;
  16. uint64_t r = x[0];
  17. for (i = 1; i < bytes; i++) {
  18. r |= (uint64_t)x[i] << (8 * i);
  19. }
  20. return r;
  21. }
  22. /*************************************************
  23. * Name: cbd
  24. *
  25. * Description: Given an array of uniformly random bytes, compute
  26. * polynomial with coefficients distributed according to
  27. * a centered binomial distribution with parameter KYBER_ETA
  28. *
  29. * Arguments: - poly *r: pointer to output polynomial
  30. * - const unsigned char *buf: pointer to input byte array
  31. **************************************************/
  32. void PQCLEAN_KYBER768_cbd(poly *r, const unsigned char *buf) {
  33. #if KYBER_ETA == 3
  34. uint32_t t, d, a[4], b[4];
  35. int i, j;
  36. for (i = 0; i < KYBER_N / 4; i++) {
  37. t = load_littleendian(buf + 3 * i, 3);
  38. d = 0;
  39. for (j = 0; j < 3; j++)
  40. d += (t >> j) & 0x249249;
  41. a[0] = d & 0x7;
  42. b[0] = (d >> 3) & 0x7;
  43. a[1] = (d >> 6) & 0x7;
  44. b[1] = (d >> 9) & 0x7;
  45. a[2] = (d >> 12) & 0x7;
  46. b[2] = (d >> 15) & 0x7;
  47. a[3] = (d >> 18) & 0x7;
  48. b[3] = (d >> 21);
  49. r->coeffs[4 * i + 0] = a[0] + KYBER_Q - b[0];
  50. r->coeffs[4 * i + 1] = a[1] + KYBER_Q - b[1];
  51. r->coeffs[4 * i + 2] = a[2] + KYBER_Q - b[2];
  52. r->coeffs[4 * i + 3] = a[3] + KYBER_Q - b[3];
  53. }
  54. #elif KYBER_ETA == 4
  55. uint32_t t, d, a[4], b[4];
  56. int i, j;
  57. for (i = 0; i < KYBER_N / 4; i++) {
  58. t = load_littleendian(buf + 4 * i, 4);
  59. d = 0;
  60. for (j = 0; j < 4; j++) {
  61. d += (t >> j) & 0x11111111;
  62. }
  63. a[0] = d & 0xf;
  64. b[0] = (d >> 4) & 0xf;
  65. a[1] = (d >> 8) & 0xf;
  66. b[1] = (d >> 12) & 0xf;
  67. a[2] = (d >> 16) & 0xf;
  68. b[2] = (d >> 20) & 0xf;
  69. a[3] = (d >> 24) & 0xf;
  70. b[3] = (d >> 28);
  71. r->coeffs[4 * i + 0] = a[0] + KYBER_Q - b[0];
  72. r->coeffs[4 * i + 1] = a[1] + KYBER_Q - b[1];
  73. r->coeffs[4 * i + 2] = a[2] + KYBER_Q - b[2];
  74. r->coeffs[4 * i + 3] = a[3] + KYBER_Q - b[3];
  75. }
  76. #elif KYBER_ETA == 5
  77. uint64_t t, d, a[4], b[4];
  78. int i, j;
  79. for (i = 0; i < KYBER_N / 4; i++) {
  80. t = load_littleendian(buf + 5 * i, 5);
  81. d = 0;
  82. for (j = 0; j < 5; j++)
  83. d += (t >> j) & 0x0842108421UL;
  84. a[0] = d & 0x1f;
  85. b[0] = (d >> 5) & 0x1f;
  86. a[1] = (d >> 10) & 0x1f;
  87. b[1] = (d >> 15) & 0x1f;
  88. a[2] = (d >> 20) & 0x1f;
  89. b[2] = (d >> 25) & 0x1f;
  90. a[3] = (d >> 30) & 0x1f;
  91. b[3] = (d >> 35);
  92. r->coeffs[4 * i + 0] = a[0] + KYBER_Q - b[0];
  93. r->coeffs[4 * i + 1] = a[1] + KYBER_Q - b[1];
  94. r->coeffs[4 * i + 2] = a[2] + KYBER_Q - b[2];
  95. r->coeffs[4 * i + 3] = a[3] + KYBER_Q - b[3];
  96. }
  97. #else
  98. #error "poly_getnoise in poly.c only supports eta in {3,4,5}"
  99. #endif
  100. }