Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.
 
 
 

134 rindas
4.1 KiB

  1. #include <assert.h>
  2. #include <stddef.h>
  3. #include <stdint.h>
  4. #include <string.h>
  5. #include "fips202.h"
  6. #include "gf31.h"
  7. #include "params.h"
  8. /* This performs a full unique reduction mod 13 on x; x can be any unsigned
  9. 16-bit integer (i.e. in the range [0, 65535]) */
  10. gf31 PQCLEAN_MQDSS64_CLEAN_mod31(gf31 x) {
  11. gf31 t;
  12. t = (gf31)(x & 31);
  13. x >>= 5;
  14. t = (gf31)(t + (x & 31));
  15. x >>= 5;
  16. t = (gf31)(t + (x & 31));
  17. x >>= 5;
  18. t = (gf31)(t + (x & 31));
  19. t = (gf31)((t >> 5) + (t & 31));
  20. t = (gf31)((t >> 5) + (t & 31));
  21. return (gf31)((t != 31) * t);
  22. }
  23. /* Given a vector of N elements in the range [0, 31], this reduces the elements
  24. to the range [0, 30] by mapping 31 to 0 (i.e reduction mod 31) */
  25. void PQCLEAN_MQDSS64_CLEAN_vgf31_unique(gf31 *out, const gf31 *in) {
  26. int i;
  27. for (i = 0; i < N; i++) {
  28. out[i] = (gf31)((1 - (in[i] == 31)) * in[i]);
  29. }
  30. }
  31. /* Given a vector of 16-bit integers (i.e. in [0, 65535], this reduces the
  32. elements to the range [0, 30] by mapping 31 to 0 (i.e reduction mod 31) */
  33. void PQCLEAN_MQDSS64_CLEAN_vgf31_shorten_unique(gf31 *out, const gf31 *in) {
  34. int i;
  35. for (i = 0; i < N; i++) {
  36. out[i] = PQCLEAN_MQDSS64_CLEAN_mod31(in[i]);
  37. }
  38. }
  39. /* Given a seed, samples len gf31 elements (in the range [0, 30]), and places
  40. them in a vector of 16-bit elements */
  41. void PQCLEAN_MQDSS64_CLEAN_gf31_nrand(gf31 *out, int len, const unsigned char *seed, size_t seedlen) {
  42. int i = 0, j;
  43. shake256ctx shakestate;
  44. unsigned char shakeblock[SHAKE256_RATE];
  45. shake256_absorb(&shakestate, seed, seedlen);
  46. while (i < len) {
  47. shake256_squeezeblocks(shakeblock, 1, &shakestate);
  48. for (j = 0; j < SHAKE256_RATE && i < len; j++) {
  49. if ((shakeblock[j] & 31) != 31) {
  50. out[i] = (shakeblock[j] & 31);
  51. i++;
  52. }
  53. }
  54. }
  55. }
  56. /* Given a seed, samples len gf31 elements, transposed into unsigned range,
  57. i.e. in the range [-15, 15], and places them in an array of 8-bit integers.
  58. This is used for the expansion of F, which wants packed elements. */
  59. void PQCLEAN_MQDSS64_CLEAN_gf31_nrand_schar(signed char *out, int len, const unsigned char *seed, size_t seedlen) {
  60. int i = 0, j;
  61. shake256ctx shakestate;
  62. unsigned char shakeblock[SHAKE256_RATE];
  63. shake256_absorb(&shakestate, seed, seedlen);
  64. while (i < len) {
  65. shake256_squeezeblocks(shakeblock, 1, &shakestate);
  66. for (j = 0; j < SHAKE256_RATE && i < len; j++) {
  67. if ((shakeblock[j] & 31) != 31) {
  68. out[i] = (signed char)(((signed char)shakeblock[j] & 31) - 15);
  69. i++;
  70. }
  71. }
  72. }
  73. }
  74. /* Unpacks an array of packed GF31 elements to one element per gf31.
  75. Assumes that there is sufficient empty space available at the end of the
  76. array to unpack. Can perform in-place. */
  77. void PQCLEAN_MQDSS64_CLEAN_gf31_nunpack(gf31 *out, const unsigned char *in, unsigned int n) {
  78. size_t i;
  79. unsigned int j = ((n * 5) >> 3) - 1;
  80. unsigned int d = 0;
  81. for (i = n; i > 0; i--) {
  82. out[i - 1] = (gf31)((in[j] >> d) & 31);
  83. d += 5;
  84. if (d > 8) {
  85. d -= 8;
  86. j--;
  87. out[i - 1] = (gf31)(out[i - 1] ^ ((in[j] << (5 - d)) & 31));
  88. }
  89. }
  90. }
  91. /* Packs an array of GF31 elements from gf31's to concatenated 5-bit values.
  92. Assumes that there is sufficient space available to unpack.
  93. Can perform in-place. */
  94. void PQCLEAN_MQDSS64_CLEAN_gf31_npack(unsigned char *out, const gf31 *in, unsigned int n) {
  95. unsigned int i = 0;
  96. unsigned int j;
  97. int d = 3;
  98. for (j = 0; j < n; j++) {
  99. assert(in[j] < 31);
  100. }
  101. /* There will be ceil(5n / 8) output blocks */
  102. memset(out, 0, ((5 * n + 7) & (unsigned int)~7) >> 3);
  103. for (j = 0; j < n; j++) {
  104. if (d < 0) {
  105. d += 8;
  106. out[i] = (unsigned char)((out[i] & (255 << (d - 3))) |
  107. ((in[j] >> (8 - d)) & ~(255 << (d - 3))));
  108. i++;
  109. }
  110. out[i] = (unsigned char)((out[i] & ~(31 << d)) | ((in[j] << d) & (31 << d)));
  111. d -= 5;
  112. }
  113. }