Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 

106 lignes
3.1 KiB

  1. #include "params.h"
  2. #include "rounding.h"
  3. /*************************************************
  4. * Name: power2round
  5. *
  6. * Description: For finite field element a, compute a0, a1 such that
  7. * a mod Q = a1*2^D + a0 with -2^{D-1} < a0 <= 2^{D-1}.
  8. * Assumes a to be standard representative.
  9. *
  10. * Arguments: - uint32_t a: input element
  11. * - uint32_t *a0: pointer to output element Q + a0
  12. *
  13. * Returns a1.
  14. **************************************************/
  15. uint32_t PQCLEAN_DILITHIUM4_CLEAN_power2round(uint32_t a, uint32_t *a0) {
  16. uint32_t t;
  17. /* Centralized remainder mod 2^D */
  18. t = a & ((1U << D) - 1);
  19. t -= ((1U << (D - 1)) + 1);
  20. t += ((uint32_t)((int32_t)t >> 31) & (1U << D));
  21. t -= ((1U << (D - 1)) - 1);
  22. *a0 = (Q + t);
  23. a = (a - t) >> D;
  24. return a;
  25. }
  26. /*************************************************
  27. * Name: decompose
  28. *
  29. * Description: For finite field element a, compute high and low bits a0, a1 such
  30. * that a mod Q = a1*ALPHA + a0 with -ALPHA/2 < a0 <= ALPHA/2 except
  31. * if a1 = (Q-1)/ALPHA where we set a1 = 0 and
  32. * -ALPHA/2 <= a0 = a mod Q - Q < 0. Assumes a to be standard
  33. * representative.
  34. *
  35. * Arguments: - uint32_t a: input element
  36. * - uint32_t *a0: pointer to output element Q + a0
  37. *
  38. * Returns a1.
  39. **************************************************/
  40. uint32_t PQCLEAN_DILITHIUM4_CLEAN_decompose(uint32_t a, uint32_t *a0) {
  41. int32_t t, u;
  42. /* Centralized remainder mod ALPHA */
  43. t = a & 0x7FFFF;
  44. t += (int32_t) ((a >> 19) << 9);
  45. t -= ALPHA / 2 + 1;
  46. t += (t >> 31) & ALPHA;
  47. t -= ALPHA / 2 - 1;
  48. a -= (uint32_t) t;
  49. /* Divide by ALPHA (possible to avoid) */
  50. u = (int32_t) a - 1;
  51. u >>= 31;
  52. a = (a >> 19) + 1;
  53. a -= u & 1;
  54. /* Border case */
  55. *a0 = Q + (uint32_t)t - (a >> 4);
  56. a &= 0xF;
  57. return a;
  58. }
  59. /*************************************************
  60. * Name: make_hint
  61. *
  62. * Description: Compute hint bit indicating whether the low bits of the
  63. * input element overflow into the high bits. Inputs assumed to be
  64. * standard representatives.
  65. *
  66. * Arguments: - uint32_t a0: low bits of input element
  67. * - uint32_t a1: high bits of input element
  68. *
  69. * Returns 1 if high bits of a and b differ and 0 otherwise.
  70. **************************************************/
  71. unsigned int PQCLEAN_DILITHIUM4_CLEAN_make_hint(uint32_t a0, uint32_t a1) {
  72. if (a0 <= GAMMA2 || a0 > Q - GAMMA2 || (a0 == Q - GAMMA2 && a1 == 0)) {
  73. return 0;
  74. }
  75. return 1;
  76. }
  77. /*************************************************
  78. * Name: use_hint
  79. *
  80. * Description: Correct high bits according to hint.
  81. *
  82. * Arguments: - uint32_t a: input element
  83. * - unsigned int hint: hint bit
  84. *
  85. * Returns corrected high bits.
  86. **************************************************/
  87. uint32_t PQCLEAN_DILITHIUM4_CLEAN_use_hint(uint32_t a, unsigned int hint) {
  88. uint32_t a0, a1;
  89. a1 = PQCLEAN_DILITHIUM4_CLEAN_decompose(a, &a0);
  90. if (hint == 0) {
  91. return a1;
  92. }
  93. if (a0 > Q) {
  94. return (a1 + 1) & 0xF;
  95. }
  96. return (a1 - 1) & 0xF;
  97. }