Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.
 
 
 

181 righe
4.7 KiB

  1. /*
  2. This file is for Benes network related functions
  3. */
  4. #include "benes.h"
  5. #include "params.h"
  6. #include "transpose.h"
  7. #include "util.h"
  8. /* middle layers of the benes network */
  9. static void layer_in(uint64_t data[2][64], uint64_t *bits, int lgs) {
  10. int i, j, s;
  11. uint64_t d;
  12. s = 1 << lgs;
  13. for (i = 0; i < 64; i += s * 2) {
  14. for (j = i; j < i + s; j++) {
  15. d = (data[0][j + 0] ^ data[0][j + s]);
  16. d &= (*bits++);
  17. data[0][j + 0] ^= d;
  18. data[0][j + s] ^= d;
  19. d = (data[1][j + 0] ^ data[1][j + s]);
  20. d &= (*bits++);
  21. data[1][j + 0] ^= d;
  22. data[1][j + s] ^= d;
  23. }
  24. }
  25. }
  26. /* first and last layers of the benes network */
  27. static void layer_ex(uint64_t *data, uint64_t *bits, int lgs) {
  28. int i, j, s;
  29. uint64_t d;
  30. s = 1 << lgs;
  31. for (i = 0; i < 128; i += s * 2) {
  32. for (j = i; j < i + s; j++) {
  33. d = (data[j + 0] ^ data[j + s]);
  34. d &= (*bits++);
  35. data[j + 0] ^= d;
  36. data[j + s] ^= d;
  37. }
  38. }
  39. }
  40. /* input: r, sequence of bits to be permuted */
  41. /* bits, condition bits of the Benes network */
  42. /* rev, 0 for normal application; !0 for inverse */
  43. /* output: r, permuted bits */
  44. void PQCLEAN_MCELIECE6960119_CLEAN_apply_benes(unsigned char *r, const unsigned char *bits, int rev) {
  45. int i, iter, inc;
  46. unsigned char *r_ptr = r;
  47. const unsigned char *bits_ptr;
  48. uint64_t r_int_v[2][64];
  49. uint64_t r_int_h[2][64];
  50. uint64_t b_int_v[64];
  51. uint64_t b_int_h[64];
  52. //
  53. if (rev) {
  54. bits_ptr = bits + 12288;
  55. inc = -1024;
  56. } else {
  57. bits_ptr = bits;
  58. inc = 0;
  59. }
  60. for (i = 0; i < 64; i++) {
  61. r_int_v[0][i] = PQCLEAN_MCELIECE6960119_CLEAN_load8(r_ptr + i * 16 + 0);
  62. r_int_v[1][i] = PQCLEAN_MCELIECE6960119_CLEAN_load8(r_ptr + i * 16 + 8);
  63. }
  64. PQCLEAN_MCELIECE6960119_CLEAN_transpose_64x64(r_int_h[0], r_int_v[0]);
  65. PQCLEAN_MCELIECE6960119_CLEAN_transpose_64x64(r_int_h[1], r_int_v[1]);
  66. for (iter = 0; iter <= 6; iter++) {
  67. for (i = 0; i < 64; i++) {
  68. b_int_v[i] = PQCLEAN_MCELIECE6960119_CLEAN_load8(bits_ptr);
  69. bits_ptr += 8;
  70. }
  71. bits_ptr += inc;
  72. PQCLEAN_MCELIECE6960119_CLEAN_transpose_64x64(b_int_h, b_int_v);
  73. layer_ex(r_int_h[0], b_int_h, iter);
  74. }
  75. PQCLEAN_MCELIECE6960119_CLEAN_transpose_64x64(r_int_v[0], r_int_h[0]);
  76. PQCLEAN_MCELIECE6960119_CLEAN_transpose_64x64(r_int_v[1], r_int_h[1]);
  77. for (iter = 0; iter <= 5; iter++) {
  78. for (i = 0; i < 64; i++) {
  79. b_int_v[i] = PQCLEAN_MCELIECE6960119_CLEAN_load8(bits_ptr);
  80. bits_ptr += 8;
  81. }
  82. bits_ptr += inc;
  83. layer_in(r_int_v, b_int_v, iter);
  84. }
  85. for (iter = 4; iter >= 0; iter--) {
  86. for (i = 0; i < 64; i++) {
  87. b_int_v[i] = PQCLEAN_MCELIECE6960119_CLEAN_load8(bits_ptr);
  88. bits_ptr += 8;
  89. }
  90. bits_ptr += inc;
  91. layer_in(r_int_v, b_int_v, iter);
  92. }
  93. PQCLEAN_MCELIECE6960119_CLEAN_transpose_64x64(r_int_h[0], r_int_v[0]);
  94. PQCLEAN_MCELIECE6960119_CLEAN_transpose_64x64(r_int_h[1], r_int_v[1]);
  95. for (iter = 6; iter >= 0; iter--) {
  96. for (i = 0; i < 64; i++) {
  97. b_int_v[i] = PQCLEAN_MCELIECE6960119_CLEAN_load8(bits_ptr);
  98. bits_ptr += 8;
  99. }
  100. bits_ptr += inc;
  101. PQCLEAN_MCELIECE6960119_CLEAN_transpose_64x64(b_int_h, b_int_v);
  102. layer_ex(r_int_h[0], b_int_h, iter);
  103. }
  104. PQCLEAN_MCELIECE6960119_CLEAN_transpose_64x64(r_int_v[0], r_int_h[0]);
  105. PQCLEAN_MCELIECE6960119_CLEAN_transpose_64x64(r_int_v[1], r_int_h[1]);
  106. for (i = 0; i < 64; i++) {
  107. PQCLEAN_MCELIECE6960119_CLEAN_store8(r_ptr + i * 16 + 0, r_int_v[0][i]);
  108. PQCLEAN_MCELIECE6960119_CLEAN_store8(r_ptr + i * 16 + 8, r_int_v[1][i]);
  109. }
  110. }
  111. /* input: condition bits c */
  112. /* output: support s */
  113. void PQCLEAN_MCELIECE6960119_CLEAN_support_gen(gf *s, const unsigned char *c) {
  114. gf a;
  115. int i, j;
  116. unsigned char L[ GFBITS ][ (1 << GFBITS) / 8 ];
  117. for (i = 0; i < GFBITS; i++) {
  118. for (j = 0; j < (1 << GFBITS) / 8; j++) {
  119. L[i][j] = 0;
  120. }
  121. }
  122. for (i = 0; i < (1 << GFBITS); i++) {
  123. a = PQCLEAN_MCELIECE6960119_CLEAN_bitrev((gf) i);
  124. for (j = 0; j < GFBITS; j++) {
  125. L[j][ i / 8 ] |= ((a >> j) & 1) << (i % 8);
  126. }
  127. }
  128. for (j = 0; j < GFBITS; j++) {
  129. PQCLEAN_MCELIECE6960119_CLEAN_apply_benes(L[j], c, 0);
  130. }
  131. for (i = 0; i < SYS_N; i++) {
  132. s[i] = 0;
  133. for (j = GFBITS - 1; j >= 0; j--) {
  134. s[i] <<= 1;
  135. s[i] |= (L[j][i / 8] >> (i % 8)) & 1;
  136. }
  137. }
  138. }