pq_crypto 0.3.2 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +56 -0
  3. data/CHANGELOG.md +37 -0
  4. data/GET_STARTED.md +361 -40
  5. data/README.md +58 -241
  6. data/SECURITY.md +101 -82
  7. data/ext/pqcrypto/extconf.rb +40 -7
  8. data/ext/pqcrypto/mldsa_api.h +71 -1
  9. data/ext/pqcrypto/mlkem_api.h +24 -0
  10. data/ext/pqcrypto/pq_externalmu.c +14 -1
  11. data/ext/pqcrypto/pqcrypto_ruby_secure.c +484 -81
  12. data/ext/pqcrypto/pqcrypto_secure.c +179 -72
  13. data/ext/pqcrypto/pqcrypto_secure.h +87 -7
  14. data/ext/pqcrypto/pqcrypto_version.h +7 -0
  15. data/ext/pqcrypto/vendor/.vendored +1 -1
  16. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/LICENSE +5 -0
  17. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/Makefile +19 -0
  18. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/Makefile.Microsoft_nmake +23 -0
  19. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/api.h +18 -0
  20. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/cbd.c +83 -0
  21. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/cbd.h +11 -0
  22. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/indcpa.c +327 -0
  23. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/indcpa.h +22 -0
  24. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/kem.c +164 -0
  25. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/kem.h +23 -0
  26. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/ntt.c +146 -0
  27. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/ntt.h +14 -0
  28. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/params.h +36 -0
  29. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/poly.c +311 -0
  30. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/poly.h +37 -0
  31. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/polyvec.c +198 -0
  32. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/polyvec.h +26 -0
  33. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/reduce.c +41 -0
  34. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/reduce.h +13 -0
  35. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/symmetric-shake.c +71 -0
  36. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/symmetric.h +30 -0
  37. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/verify.c +67 -0
  38. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-1024/clean/verify.h +13 -0
  39. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/LICENSE +5 -0
  40. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/Makefile +19 -0
  41. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/Makefile.Microsoft_nmake +23 -0
  42. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/api.h +18 -0
  43. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/cbd.c +108 -0
  44. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/cbd.h +11 -0
  45. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/indcpa.c +327 -0
  46. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/indcpa.h +22 -0
  47. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/kem.c +164 -0
  48. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/kem.h +23 -0
  49. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/ntt.c +146 -0
  50. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/ntt.h +14 -0
  51. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/params.h +36 -0
  52. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/poly.c +299 -0
  53. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/poly.h +37 -0
  54. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/polyvec.c +188 -0
  55. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/polyvec.h +26 -0
  56. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/reduce.c +41 -0
  57. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/reduce.h +13 -0
  58. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/symmetric-shake.c +71 -0
  59. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/symmetric.h +30 -0
  60. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/verify.c +67 -0
  61. data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-512/clean/verify.h +13 -0
  62. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/LICENSE +5 -0
  63. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/Makefile +19 -0
  64. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/Makefile.Microsoft_nmake +23 -0
  65. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/api.h +50 -0
  66. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/ntt.c +98 -0
  67. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/ntt.h +10 -0
  68. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/packing.c +261 -0
  69. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/packing.h +31 -0
  70. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/params.h +44 -0
  71. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/poly.c +848 -0
  72. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/poly.h +52 -0
  73. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/polyvec.c +415 -0
  74. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/polyvec.h +65 -0
  75. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/reduce.c +69 -0
  76. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/reduce.h +17 -0
  77. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/rounding.c +98 -0
  78. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/rounding.h +14 -0
  79. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/sign.c +407 -0
  80. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/sign.h +47 -0
  81. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/symmetric-shake.c +26 -0
  82. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-44/clean/symmetric.h +34 -0
  83. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/LICENSE +5 -0
  84. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/Makefile +19 -0
  85. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/Makefile.Microsoft_nmake +23 -0
  86. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/api.h +50 -0
  87. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/ntt.c +98 -0
  88. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/ntt.h +10 -0
  89. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/packing.c +261 -0
  90. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/packing.h +31 -0
  91. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/params.h +44 -0
  92. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/poly.c +823 -0
  93. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/poly.h +52 -0
  94. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/polyvec.c +415 -0
  95. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/polyvec.h +65 -0
  96. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/reduce.c +69 -0
  97. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/reduce.h +17 -0
  98. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/rounding.c +92 -0
  99. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/rounding.h +14 -0
  100. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/sign.c +407 -0
  101. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/sign.h +47 -0
  102. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/symmetric-shake.c +26 -0
  103. data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-87/clean/symmetric.h +34 -0
  104. data/lib/pq_crypto/algorithm_registry.rb +200 -0
  105. data/lib/pq_crypto/hybrid_kem.rb +1 -12
  106. data/lib/pq_crypto/kem.rb +104 -13
  107. data/lib/pq_crypto/pkcs8.rb +387 -0
  108. data/lib/pq_crypto/serialization.rb +1 -14
  109. data/lib/pq_crypto/signature.rb +123 -17
  110. data/lib/pq_crypto/spki.rb +131 -0
  111. data/lib/pq_crypto/version.rb +1 -1
  112. data/lib/pq_crypto.rb +78 -19
  113. data/script/vendor_libs.rb +4 -0
  114. metadata +95 -3
@@ -0,0 +1,14 @@
1
+ #ifndef PQCLEAN_MLKEM1024_CLEAN_NTT_H
2
+ #define PQCLEAN_MLKEM1024_CLEAN_NTT_H
3
+ #include "params.h"
4
+ #include <stdint.h>
5
+
6
+ extern const int16_t PQCLEAN_MLKEM1024_CLEAN_zetas[128];
7
+
8
+ void PQCLEAN_MLKEM1024_CLEAN_ntt(int16_t r[256]);
9
+
10
+ void PQCLEAN_MLKEM1024_CLEAN_invntt(int16_t r[256]);
11
+
12
+ void PQCLEAN_MLKEM1024_CLEAN_basemul(int16_t r[2], const int16_t a[2], const int16_t b[2], int16_t zeta);
13
+
14
+ #endif
@@ -0,0 +1,36 @@
1
+ #ifndef PQCLEAN_MLKEM1024_CLEAN_PARAMS_H
2
+ #define PQCLEAN_MLKEM1024_CLEAN_PARAMS_H
3
+
4
+
5
+
6
+
7
+
8
+ /* Don't change parameters below this line */
9
+
10
+ #define KYBER_N 256
11
+ #define KYBER_Q 3329
12
+
13
+ #define KYBER_SYMBYTES 32 /* size in bytes of hashes, and seeds */
14
+ #define KYBER_SSBYTES 32 /* size in bytes of shared key */
15
+
16
+ #define KYBER_POLYBYTES 384
17
+ #define KYBER_POLYVECBYTES (KYBER_K * KYBER_POLYBYTES)
18
+
19
+ #define KYBER_K 4
20
+ #define KYBER_ETA1 2
21
+ #define KYBER_POLYCOMPRESSEDBYTES 160
22
+ #define KYBER_POLYVECCOMPRESSEDBYTES (KYBER_K * 352)
23
+
24
+ #define KYBER_ETA2 2
25
+
26
+ #define KYBER_INDCPA_MSGBYTES (KYBER_SYMBYTES)
27
+ #define KYBER_INDCPA_PUBLICKEYBYTES (KYBER_POLYVECBYTES + KYBER_SYMBYTES)
28
+ #define KYBER_INDCPA_SECRETKEYBYTES (KYBER_POLYVECBYTES)
29
+ #define KYBER_INDCPA_BYTES (KYBER_POLYVECCOMPRESSEDBYTES + KYBER_POLYCOMPRESSEDBYTES)
30
+
31
+ #define KYBER_PUBLICKEYBYTES (KYBER_INDCPA_PUBLICKEYBYTES)
32
+ /* 32 bytes of additional space to save H(pk) */
33
+ #define KYBER_SECRETKEYBYTES (KYBER_INDCPA_SECRETKEYBYTES + KYBER_INDCPA_PUBLICKEYBYTES + 2*KYBER_SYMBYTES)
34
+ #define KYBER_CIPHERTEXTBYTES (KYBER_INDCPA_BYTES)
35
+
36
+ #endif
@@ -0,0 +1,311 @@
1
+ #include "cbd.h"
2
+ #include "ntt.h"
3
+ #include "params.h"
4
+ #include "poly.h"
5
+ #include "reduce.h"
6
+ #include "symmetric.h"
7
+ #include "verify.h"
8
+ #include <stdint.h>
9
+
10
+ /*************************************************
11
+ * Name: PQCLEAN_MLKEM1024_CLEAN_poly_compress
12
+ *
13
+ * Description: Compression and subsequent serialization of a polynomial
14
+ *
15
+ * Arguments: - uint8_t *r: pointer to output byte array
16
+ * (of length KYBER_POLYCOMPRESSEDBYTES)
17
+ * - const poly *a: pointer to input polynomial
18
+ **************************************************/
19
+ void PQCLEAN_MLKEM1024_CLEAN_poly_compress(uint8_t r[KYBER_POLYCOMPRESSEDBYTES], const poly *a) {
20
+ unsigned int i, j;
21
+ int16_t u;
22
+ uint32_t d0;
23
+ uint8_t t[8];
24
+
25
+ for (i = 0; i < KYBER_N / 8; i++) {
26
+ for (j = 0; j < 8; j++) {
27
+ // map to positive standard representatives
28
+ u = a->coeffs[8 * i + j];
29
+ u += (u >> 15) & KYBER_Q;
30
+ /* t[j] = ((((uint32_t)u << 5) + KYBER_Q/2)/KYBER_Q) & 31; */
31
+ d0 = u << 5;
32
+ d0 += 1664;
33
+ d0 *= 40318;
34
+ d0 >>= 27;
35
+ t[j] = d0 & 0x1f;
36
+ }
37
+
38
+ r[0] = (t[0] >> 0) | (t[1] << 5);
39
+ r[1] = (t[1] >> 3) | (t[2] << 2) | (t[3] << 7);
40
+ r[2] = (t[3] >> 1) | (t[4] << 4);
41
+ r[3] = (t[4] >> 4) | (t[5] << 1) | (t[6] << 6);
42
+ r[4] = (t[6] >> 2) | (t[7] << 3);
43
+ r += 5;
44
+ }
45
+ }
46
+
47
+ /*************************************************
48
+ * Name: PQCLEAN_MLKEM1024_CLEAN_poly_decompress
49
+ *
50
+ * Description: De-serialization and subsequent decompression of a polynomial;
51
+ * approximate inverse of PQCLEAN_MLKEM1024_CLEAN_poly_compress
52
+ *
53
+ * Arguments: - poly *r: pointer to output polynomial
54
+ * - const uint8_t *a: pointer to input byte array
55
+ * (of length KYBER_POLYCOMPRESSEDBYTES bytes)
56
+ **************************************************/
57
+ void PQCLEAN_MLKEM1024_CLEAN_poly_decompress(poly *r, const uint8_t a[KYBER_POLYCOMPRESSEDBYTES]) {
58
+ size_t i;
59
+
60
+ size_t j;
61
+ uint8_t t[8];
62
+ for (i = 0; i < KYBER_N / 8; i++) {
63
+ t[0] = (a[0] >> 0);
64
+ t[1] = (a[0] >> 5) | (a[1] << 3);
65
+ t[2] = (a[1] >> 2);
66
+ t[3] = (a[1] >> 7) | (a[2] << 1);
67
+ t[4] = (a[2] >> 4) | (a[3] << 4);
68
+ t[5] = (a[3] >> 1);
69
+ t[6] = (a[3] >> 6) | (a[4] << 2);
70
+ t[7] = (a[4] >> 3);
71
+ a += 5;
72
+
73
+ for (j = 0; j < 8; j++) {
74
+ r->coeffs[8 * i + j] = ((uint32_t)(t[j] & 31) * KYBER_Q + 16) >> 5;
75
+ }
76
+ }
77
+ }
78
+
79
+ /*************************************************
80
+ * Name: PQCLEAN_MLKEM1024_CLEAN_poly_tobytes
81
+ *
82
+ * Description: Serialization of a polynomial
83
+ *
84
+ * Arguments: - uint8_t *r: pointer to output byte array
85
+ * (needs space for KYBER_POLYBYTES bytes)
86
+ * - const poly *a: pointer to input polynomial
87
+ **************************************************/
88
+ void PQCLEAN_MLKEM1024_CLEAN_poly_tobytes(uint8_t r[KYBER_POLYBYTES], const poly *a) {
89
+ size_t i;
90
+ uint16_t t0, t1;
91
+
92
+ for (i = 0; i < KYBER_N / 2; i++) {
93
+ // map to positive standard representatives
94
+ t0 = a->coeffs[2 * i];
95
+ t0 += ((int16_t)t0 >> 15) & KYBER_Q;
96
+ t1 = a->coeffs[2 * i + 1];
97
+ t1 += ((int16_t)t1 >> 15) & KYBER_Q;
98
+ r[3 * i + 0] = (uint8_t)(t0 >> 0);
99
+ r[3 * i + 1] = (uint8_t)((t0 >> 8) | (t1 << 4));
100
+ r[3 * i + 2] = (uint8_t)(t1 >> 4);
101
+ }
102
+ }
103
+
104
+ /*************************************************
105
+ * Name: PQCLEAN_MLKEM1024_CLEAN_poly_frombytes
106
+ *
107
+ * Description: De-serialization of a polynomial;
108
+ * inverse of PQCLEAN_MLKEM1024_CLEAN_poly_tobytes
109
+ *
110
+ * Arguments: - poly *r: pointer to output polynomial
111
+ * - const uint8_t *a: pointer to input byte array
112
+ * (of KYBER_POLYBYTES bytes)
113
+ **************************************************/
114
+ void PQCLEAN_MLKEM1024_CLEAN_poly_frombytes(poly *r, const uint8_t a[KYBER_POLYBYTES]) {
115
+ size_t i;
116
+ for (i = 0; i < KYBER_N / 2; i++) {
117
+ r->coeffs[2 * i] = ((a[3 * i + 0] >> 0) | ((uint16_t)a[3 * i + 1] << 8)) & 0xFFF;
118
+ r->coeffs[2 * i + 1] = ((a[3 * i + 1] >> 4) | ((uint16_t)a[3 * i + 2] << 4)) & 0xFFF;
119
+ }
120
+ }
121
+
122
+ /*************************************************
123
+ * Name: PQCLEAN_MLKEM1024_CLEAN_poly_frommsg
124
+ *
125
+ * Description: Convert 32-byte message to polynomial
126
+ *
127
+ * Arguments: - poly *r: pointer to output polynomial
128
+ * - const uint8_t *msg: pointer to input message
129
+ **************************************************/
130
+ void PQCLEAN_MLKEM1024_CLEAN_poly_frommsg(poly *r, const uint8_t msg[KYBER_INDCPA_MSGBYTES]) {
131
+ size_t i, j;
132
+
133
+ for (i = 0; i < KYBER_N / 8; i++) {
134
+ for (j = 0; j < 8; j++) {
135
+ r->coeffs[8 * i + j] = 0;
136
+ PQCLEAN_MLKEM1024_CLEAN_cmov_int16(r->coeffs + 8 * i + j, ((KYBER_Q + 1) / 2), (msg[i] >> j) & 1);
137
+ }
138
+ }
139
+ }
140
+
141
+ /*************************************************
142
+ * Name: PQCLEAN_MLKEM1024_CLEAN_poly_tomsg
143
+ *
144
+ * Description: Convert polynomial to 32-byte message
145
+ *
146
+ * Arguments: - uint8_t *msg: pointer to output message
147
+ * - const poly *a: pointer to input polynomial
148
+ **************************************************/
149
+ void PQCLEAN_MLKEM1024_CLEAN_poly_tomsg(uint8_t msg[KYBER_INDCPA_MSGBYTES], const poly *a) {
150
+ unsigned int i, j;
151
+ uint32_t t;
152
+
153
+ for (i = 0; i < KYBER_N / 8; i++) {
154
+ msg[i] = 0;
155
+ for (j = 0; j < 8; j++) {
156
+ t = a->coeffs[8 * i + j];
157
+ // t += ((int16_t)t >> 15) & KYBER_Q;
158
+ // t = (((t << 1) + KYBER_Q/2)/KYBER_Q) & 1;
159
+ t <<= 1;
160
+ t += 1665;
161
+ t *= 80635;
162
+ t >>= 28;
163
+ t &= 1;
164
+ msg[i] |= t << j;
165
+ }
166
+ }
167
+ }
168
+
169
+ /*************************************************
170
+ * Name: PQCLEAN_MLKEM1024_CLEAN_poly_getnoise_eta1
171
+ *
172
+ * Description: Sample a polynomial deterministically from a seed and a nonce,
173
+ * with output polynomial close to centered binomial distribution
174
+ * with parameter KYBER_ETA1
175
+ *
176
+ * Arguments: - poly *r: pointer to output polynomial
177
+ * - const uint8_t *seed: pointer to input seed
178
+ * (of length KYBER_SYMBYTES bytes)
179
+ * - uint8_t nonce: one-byte input nonce
180
+ **************************************************/
181
+ void PQCLEAN_MLKEM1024_CLEAN_poly_getnoise_eta1(poly *r, const uint8_t seed[KYBER_SYMBYTES], uint8_t nonce) {
182
+ uint8_t buf[KYBER_ETA1 * KYBER_N / 4];
183
+ prf(buf, sizeof(buf), seed, nonce);
184
+ PQCLEAN_MLKEM1024_CLEAN_poly_cbd_eta1(r, buf);
185
+ }
186
+
187
+ /*************************************************
188
+ * Name: PQCLEAN_MLKEM1024_CLEAN_poly_getnoise_eta2
189
+ *
190
+ * Description: Sample a polynomial deterministically from a seed and a nonce,
191
+ * with output polynomial close to centered binomial distribution
192
+ * with parameter KYBER_ETA2
193
+ *
194
+ * Arguments: - poly *r: pointer to output polynomial
195
+ * - const uint8_t *seed: pointer to input seed
196
+ * (of length KYBER_SYMBYTES bytes)
197
+ * - uint8_t nonce: one-byte input nonce
198
+ **************************************************/
199
+ void PQCLEAN_MLKEM1024_CLEAN_poly_getnoise_eta2(poly *r, const uint8_t seed[KYBER_SYMBYTES], uint8_t nonce) {
200
+ uint8_t buf[KYBER_ETA2 * KYBER_N / 4];
201
+ prf(buf, sizeof(buf), seed, nonce);
202
+ PQCLEAN_MLKEM1024_CLEAN_poly_cbd_eta2(r, buf);
203
+ }
204
+
205
+
206
+ /*************************************************
207
+ * Name: PQCLEAN_MLKEM1024_CLEAN_poly_ntt
208
+ *
209
+ * Description: Computes negacyclic number-theoretic transform (NTT) of
210
+ * a polynomial in place;
211
+ * inputs assumed to be in normal order, output in bitreversed order
212
+ *
213
+ * Arguments: - uint16_t *r: pointer to in/output polynomial
214
+ **************************************************/
215
+ void PQCLEAN_MLKEM1024_CLEAN_poly_ntt(poly *r) {
216
+ PQCLEAN_MLKEM1024_CLEAN_ntt(r->coeffs);
217
+ PQCLEAN_MLKEM1024_CLEAN_poly_reduce(r);
218
+ }
219
+
220
+ /*************************************************
221
+ * Name: PQCLEAN_MLKEM1024_CLEAN_poly_invntt_tomont
222
+ *
223
+ * Description: Computes inverse of negacyclic number-theoretic transform (NTT)
224
+ * of a polynomial in place;
225
+ * inputs assumed to be in bitreversed order, output in normal order
226
+ *
227
+ * Arguments: - uint16_t *a: pointer to in/output polynomial
228
+ **************************************************/
229
+ void PQCLEAN_MLKEM1024_CLEAN_poly_invntt_tomont(poly *r) {
230
+ PQCLEAN_MLKEM1024_CLEAN_invntt(r->coeffs);
231
+ }
232
+
233
+ /*************************************************
234
+ * Name: PQCLEAN_MLKEM1024_CLEAN_poly_basemul_montgomery
235
+ *
236
+ * Description: Multiplication of two polynomials in NTT domain
237
+ *
238
+ * Arguments: - poly *r: pointer to output polynomial
239
+ * - const poly *a: pointer to first input polynomial
240
+ * - const poly *b: pointer to second input polynomial
241
+ **************************************************/
242
+ void PQCLEAN_MLKEM1024_CLEAN_poly_basemul_montgomery(poly *r, const poly *a, const poly *b) {
243
+ size_t i;
244
+ for (i = 0; i < KYBER_N / 4; i++) {
245
+ PQCLEAN_MLKEM1024_CLEAN_basemul(&r->coeffs[4 * i], &a->coeffs[4 * i], &b->coeffs[4 * i], PQCLEAN_MLKEM1024_CLEAN_zetas[64 + i]);
246
+ PQCLEAN_MLKEM1024_CLEAN_basemul(&r->coeffs[4 * i + 2], &a->coeffs[4 * i + 2], &b->coeffs[4 * i + 2], -PQCLEAN_MLKEM1024_CLEAN_zetas[64 + i]);
247
+ }
248
+ }
249
+
250
+ /*************************************************
251
+ * Name: PQCLEAN_MLKEM1024_CLEAN_poly_tomont
252
+ *
253
+ * Description: Inplace conversion of all coefficients of a polynomial
254
+ * from normal domain to Montgomery domain
255
+ *
256
+ * Arguments: - poly *r: pointer to input/output polynomial
257
+ **************************************************/
258
+ void PQCLEAN_MLKEM1024_CLEAN_poly_tomont(poly *r) {
259
+ size_t i;
260
+ const int16_t f = (1ULL << 32) % KYBER_Q;
261
+ for (i = 0; i < KYBER_N; i++) {
262
+ r->coeffs[i] = PQCLEAN_MLKEM1024_CLEAN_montgomery_reduce((int32_t)r->coeffs[i] * f);
263
+ }
264
+ }
265
+
266
+ /*************************************************
267
+ * Name: PQCLEAN_MLKEM1024_CLEAN_poly_reduce
268
+ *
269
+ * Description: Applies Barrett reduction to all coefficients of a polynomial
270
+ * for details of the Barrett reduction see comments in reduce.c
271
+ *
272
+ * Arguments: - poly *r: pointer to input/output polynomial
273
+ **************************************************/
274
+ void PQCLEAN_MLKEM1024_CLEAN_poly_reduce(poly *r) {
275
+ size_t i;
276
+ for (i = 0; i < KYBER_N; i++) {
277
+ r->coeffs[i] = PQCLEAN_MLKEM1024_CLEAN_barrett_reduce(r->coeffs[i]);
278
+ }
279
+ }
280
+
281
+ /*************************************************
282
+ * Name: PQCLEAN_MLKEM1024_CLEAN_poly_add
283
+ *
284
+ * Description: Add two polynomials; no modular reduction is performed
285
+ *
286
+ * Arguments: - poly *r: pointer to output polynomial
287
+ * - const poly *a: pointer to first input polynomial
288
+ * - const poly *b: pointer to second input polynomial
289
+ **************************************************/
290
+ void PQCLEAN_MLKEM1024_CLEAN_poly_add(poly *r, const poly *a, const poly *b) {
291
+ size_t i;
292
+ for (i = 0; i < KYBER_N; i++) {
293
+ r->coeffs[i] = a->coeffs[i] + b->coeffs[i];
294
+ }
295
+ }
296
+
297
+ /*************************************************
298
+ * Name: PQCLEAN_MLKEM1024_CLEAN_poly_sub
299
+ *
300
+ * Description: Subtract two polynomials; no modular reduction is performed
301
+ *
302
+ * Arguments: - poly *r: pointer to output polynomial
303
+ * - const poly *a: pointer to first input polynomial
304
+ * - const poly *b: pointer to second input polynomial
305
+ **************************************************/
306
+ void PQCLEAN_MLKEM1024_CLEAN_poly_sub(poly *r, const poly *a, const poly *b) {
307
+ size_t i;
308
+ for (i = 0; i < KYBER_N; i++) {
309
+ r->coeffs[i] = a->coeffs[i] - b->coeffs[i];
310
+ }
311
+ }
@@ -0,0 +1,37 @@
1
+ #ifndef PQCLEAN_MLKEM1024_CLEAN_POLY_H
2
+ #define PQCLEAN_MLKEM1024_CLEAN_POLY_H
3
+ #include "params.h"
4
+ #include <stdint.h>
5
+
6
+ /*
7
+ * Elements of R_q = Z_q[X]/(X^n + 1). Represents polynomial
8
+ * coeffs[0] + X*coeffs[1] + X^2*coeffs[2] + ... + X^{n-1}*coeffs[n-1]
9
+ */
10
+ typedef struct {
11
+ int16_t coeffs[KYBER_N];
12
+ } poly;
13
+
14
+ void PQCLEAN_MLKEM1024_CLEAN_poly_compress(uint8_t r[KYBER_POLYCOMPRESSEDBYTES], const poly *a);
15
+ void PQCLEAN_MLKEM1024_CLEAN_poly_decompress(poly *r, const uint8_t a[KYBER_POLYCOMPRESSEDBYTES]);
16
+
17
+ void PQCLEAN_MLKEM1024_CLEAN_poly_tobytes(uint8_t r[KYBER_POLYBYTES], const poly *a);
18
+ void PQCLEAN_MLKEM1024_CLEAN_poly_frombytes(poly *r, const uint8_t a[KYBER_POLYBYTES]);
19
+
20
+ void PQCLEAN_MLKEM1024_CLEAN_poly_frommsg(poly *r, const uint8_t msg[KYBER_INDCPA_MSGBYTES]);
21
+ void PQCLEAN_MLKEM1024_CLEAN_poly_tomsg(uint8_t msg[KYBER_INDCPA_MSGBYTES], const poly *a);
22
+
23
+ void PQCLEAN_MLKEM1024_CLEAN_poly_getnoise_eta1(poly *r, const uint8_t seed[KYBER_SYMBYTES], uint8_t nonce);
24
+
25
+ void PQCLEAN_MLKEM1024_CLEAN_poly_getnoise_eta2(poly *r, const uint8_t seed[KYBER_SYMBYTES], uint8_t nonce);
26
+
27
+ void PQCLEAN_MLKEM1024_CLEAN_poly_ntt(poly *r);
28
+ void PQCLEAN_MLKEM1024_CLEAN_poly_invntt_tomont(poly *r);
29
+ void PQCLEAN_MLKEM1024_CLEAN_poly_basemul_montgomery(poly *r, const poly *a, const poly *b);
30
+ void PQCLEAN_MLKEM1024_CLEAN_poly_tomont(poly *r);
31
+
32
+ void PQCLEAN_MLKEM1024_CLEAN_poly_reduce(poly *r);
33
+
34
+ void PQCLEAN_MLKEM1024_CLEAN_poly_add(poly *r, const poly *a, const poly *b);
35
+ void PQCLEAN_MLKEM1024_CLEAN_poly_sub(poly *r, const poly *a, const poly *b);
36
+
37
+ #endif
@@ -0,0 +1,198 @@
1
+ #include "params.h"
2
+ #include "poly.h"
3
+ #include "polyvec.h"
4
+ #include <stdint.h>
5
+
6
+ /*************************************************
7
+ * Name: PQCLEAN_MLKEM1024_CLEAN_polyvec_compress
8
+ *
9
+ * Description: Compress and serialize vector of polynomials
10
+ *
11
+ * Arguments: - uint8_t *r: pointer to output byte array
12
+ * (needs space for KYBER_POLYVECCOMPRESSEDBYTES)
13
+ * - const polyvec *a: pointer to input vector of polynomials
14
+ **************************************************/
15
+ void PQCLEAN_MLKEM1024_CLEAN_polyvec_compress(uint8_t r[KYBER_POLYVECCOMPRESSEDBYTES], const polyvec *a) {
16
+ unsigned int i, j, k;
17
+ uint64_t d0;
18
+
19
+ uint16_t t[8];
20
+ for (i = 0; i < KYBER_K; i++) {
21
+ for (j = 0; j < KYBER_N / 8; j++) {
22
+ for (k = 0; k < 8; k++) {
23
+ t[k] = a->vec[i].coeffs[8 * j + k];
24
+ t[k] += ((int16_t)t[k] >> 15) & KYBER_Q;
25
+ /* t[k] = ((((uint32_t)t[k] << 11) + KYBER_Q/2)/KYBER_Q) & 0x7ff; */
26
+ d0 = t[k];
27
+ d0 <<= 11;
28
+ d0 += 1664;
29
+ d0 *= 645084;
30
+ d0 >>= 31;
31
+ t[k] = d0 & 0x7ff;
32
+ }
33
+
34
+ r[ 0] = (uint8_t)(t[0] >> 0);
35
+ r[ 1] = (uint8_t)((t[0] >> 8) | (t[1] << 3));
36
+ r[ 2] = (uint8_t)((t[1] >> 5) | (t[2] << 6));
37
+ r[ 3] = (uint8_t)(t[2] >> 2);
38
+ r[ 4] = (uint8_t)((t[2] >> 10) | (t[3] << 1));
39
+ r[ 5] = (uint8_t)((t[3] >> 7) | (t[4] << 4));
40
+ r[ 6] = (uint8_t)((t[4] >> 4) | (t[5] << 7));
41
+ r[ 7] = (uint8_t)(t[5] >> 1);
42
+ r[ 8] = (uint8_t)((t[5] >> 9) | (t[6] << 2));
43
+ r[ 9] = (uint8_t)((t[6] >> 6) | (t[7] << 5));
44
+ r[10] = (uint8_t)(t[7] >> 3);
45
+ r += 11;
46
+ }
47
+ }
48
+ }
49
+
50
+ /*************************************************
51
+ * Name: PQCLEAN_MLKEM1024_CLEAN_polyvec_decompress
52
+ *
53
+ * Description: De-serialize and decompress vector of polynomials;
54
+ * approximate inverse of PQCLEAN_MLKEM1024_CLEAN_polyvec_compress
55
+ *
56
+ * Arguments: - polyvec *r: pointer to output vector of polynomials
57
+ * - const uint8_t *a: pointer to input byte array
58
+ * (of length KYBER_POLYVECCOMPRESSEDBYTES)
59
+ **************************************************/
60
+ void PQCLEAN_MLKEM1024_CLEAN_polyvec_decompress(polyvec *r, const uint8_t a[KYBER_POLYVECCOMPRESSEDBYTES]) {
61
+ unsigned int i, j, k;
62
+
63
+ uint16_t t[8];
64
+ for (i = 0; i < KYBER_K; i++) {
65
+ for (j = 0; j < KYBER_N / 8; j++) {
66
+ t[0] = (a[0] >> 0) | ((uint16_t)a[ 1] << 8);
67
+ t[1] = (a[1] >> 3) | ((uint16_t)a[ 2] << 5);
68
+ t[2] = (a[2] >> 6) | ((uint16_t)a[ 3] << 2) | ((uint16_t)a[4] << 10);
69
+ t[3] = (a[4] >> 1) | ((uint16_t)a[ 5] << 7);
70
+ t[4] = (a[5] >> 4) | ((uint16_t)a[ 6] << 4);
71
+ t[5] = (a[6] >> 7) | ((uint16_t)a[ 7] << 1) | ((uint16_t)a[8] << 9);
72
+ t[6] = (a[8] >> 2) | ((uint16_t)a[ 9] << 6);
73
+ t[7] = (a[9] >> 5) | ((uint16_t)a[10] << 3);
74
+ a += 11;
75
+
76
+ for (k = 0; k < 8; k++) {
77
+ r->vec[i].coeffs[8 * j + k] = ((uint32_t)(t[k] & 0x7FF) * KYBER_Q + 1024) >> 11;
78
+ }
79
+ }
80
+ }
81
+ }
82
+
83
+ /*************************************************
84
+ * Name: PQCLEAN_MLKEM1024_CLEAN_polyvec_tobytes
85
+ *
86
+ * Description: Serialize vector of polynomials
87
+ *
88
+ * Arguments: - uint8_t *r: pointer to output byte array
89
+ * (needs space for KYBER_POLYVECBYTES)
90
+ * - const polyvec *a: pointer to input vector of polynomials
91
+ **************************************************/
92
+ void PQCLEAN_MLKEM1024_CLEAN_polyvec_tobytes(uint8_t r[KYBER_POLYVECBYTES], const polyvec *a) {
93
+ unsigned int i;
94
+ for (i = 0; i < KYBER_K; i++) {
95
+ PQCLEAN_MLKEM1024_CLEAN_poly_tobytes(r + i * KYBER_POLYBYTES, &a->vec[i]);
96
+ }
97
+ }
98
+
99
+ /*************************************************
100
+ * Name: PQCLEAN_MLKEM1024_CLEAN_polyvec_frombytes
101
+ *
102
+ * Description: De-serialize vector of polynomials;
103
+ * inverse of PQCLEAN_MLKEM1024_CLEAN_polyvec_tobytes
104
+ *
105
+ * Arguments: - uint8_t *r: pointer to output byte array
106
+ * - const polyvec *a: pointer to input vector of polynomials
107
+ * (of length KYBER_POLYVECBYTES)
108
+ **************************************************/
109
+ void PQCLEAN_MLKEM1024_CLEAN_polyvec_frombytes(polyvec *r, const uint8_t a[KYBER_POLYVECBYTES]) {
110
+ unsigned int i;
111
+ for (i = 0; i < KYBER_K; i++) {
112
+ PQCLEAN_MLKEM1024_CLEAN_poly_frombytes(&r->vec[i], a + i * KYBER_POLYBYTES);
113
+ }
114
+ }
115
+
116
+ /*************************************************
117
+ * Name: PQCLEAN_MLKEM1024_CLEAN_polyvec_ntt
118
+ *
119
+ * Description: Apply forward NTT to all elements of a vector of polynomials
120
+ *
121
+ * Arguments: - polyvec *r: pointer to in/output vector of polynomials
122
+ **************************************************/
123
+ void PQCLEAN_MLKEM1024_CLEAN_polyvec_ntt(polyvec *r) {
124
+ unsigned int i;
125
+ for (i = 0; i < KYBER_K; i++) {
126
+ PQCLEAN_MLKEM1024_CLEAN_poly_ntt(&r->vec[i]);
127
+ }
128
+ }
129
+
130
+ /*************************************************
131
+ * Name: PQCLEAN_MLKEM1024_CLEAN_polyvec_invntt_tomont
132
+ *
133
+ * Description: Apply inverse NTT to all elements of a vector of polynomials
134
+ * and multiply by Montgomery factor 2^16
135
+ *
136
+ * Arguments: - polyvec *r: pointer to in/output vector of polynomials
137
+ **************************************************/
138
+ void PQCLEAN_MLKEM1024_CLEAN_polyvec_invntt_tomont(polyvec *r) {
139
+ unsigned int i;
140
+ for (i = 0; i < KYBER_K; i++) {
141
+ PQCLEAN_MLKEM1024_CLEAN_poly_invntt_tomont(&r->vec[i]);
142
+ }
143
+ }
144
+
145
+ /*************************************************
146
+ * Name: PQCLEAN_MLKEM1024_CLEAN_polyvec_basemul_acc_montgomery
147
+ *
148
+ * Description: Multiply elements of a and b in NTT domain, accumulate into r,
149
+ * and multiply by 2^-16.
150
+ *
151
+ * Arguments: - poly *r: pointer to output polynomial
152
+ * - const polyvec *a: pointer to first input vector of polynomials
153
+ * - const polyvec *b: pointer to second input vector of polynomials
154
+ **************************************************/
155
+ void PQCLEAN_MLKEM1024_CLEAN_polyvec_basemul_acc_montgomery(poly *r, const polyvec *a, const polyvec *b) {
156
+ unsigned int i;
157
+ poly t;
158
+
159
+ PQCLEAN_MLKEM1024_CLEAN_poly_basemul_montgomery(r, &a->vec[0], &b->vec[0]);
160
+ for (i = 1; i < KYBER_K; i++) {
161
+ PQCLEAN_MLKEM1024_CLEAN_poly_basemul_montgomery(&t, &a->vec[i], &b->vec[i]);
162
+ PQCLEAN_MLKEM1024_CLEAN_poly_add(r, r, &t);
163
+ }
164
+
165
+ PQCLEAN_MLKEM1024_CLEAN_poly_reduce(r);
166
+ }
167
+
168
+ /*************************************************
169
+ * Name: PQCLEAN_MLKEM1024_CLEAN_polyvec_reduce
170
+ *
171
+ * Description: Applies Barrett reduction to each coefficient
172
+ * of each element of a vector of polynomials;
173
+ * for details of the Barrett reduction see comments in reduce.c
174
+ *
175
+ * Arguments: - polyvec *r: pointer to input/output polynomial
176
+ **************************************************/
177
+ void PQCLEAN_MLKEM1024_CLEAN_polyvec_reduce(polyvec *r) {
178
+ unsigned int i;
179
+ for (i = 0; i < KYBER_K; i++) {
180
+ PQCLEAN_MLKEM1024_CLEAN_poly_reduce(&r->vec[i]);
181
+ }
182
+ }
183
+
184
+ /*************************************************
185
+ * Name: PQCLEAN_MLKEM1024_CLEAN_polyvec_add
186
+ *
187
+ * Description: Add vectors of polynomials
188
+ *
189
+ * Arguments: - polyvec *r: pointer to output vector of polynomials
190
+ * - const polyvec *a: pointer to first input vector of polynomials
191
+ * - const polyvec *b: pointer to second input vector of polynomials
192
+ **************************************************/
193
+ void PQCLEAN_MLKEM1024_CLEAN_polyvec_add(polyvec *r, const polyvec *a, const polyvec *b) {
194
+ unsigned int i;
195
+ for (i = 0; i < KYBER_K; i++) {
196
+ PQCLEAN_MLKEM1024_CLEAN_poly_add(&r->vec[i], &a->vec[i], &b->vec[i]);
197
+ }
198
+ }
@@ -0,0 +1,26 @@
1
+ #ifndef PQCLEAN_MLKEM1024_CLEAN_POLYVEC_H
2
+ #define PQCLEAN_MLKEM1024_CLEAN_POLYVEC_H
3
+ #include "params.h"
4
+ #include "poly.h"
5
+ #include <stdint.h>
6
+
7
+ typedef struct {
8
+ poly vec[KYBER_K];
9
+ } polyvec;
10
+
11
+ void PQCLEAN_MLKEM1024_CLEAN_polyvec_compress(uint8_t r[KYBER_POLYVECCOMPRESSEDBYTES], const polyvec *a);
12
+ void PQCLEAN_MLKEM1024_CLEAN_polyvec_decompress(polyvec *r, const uint8_t a[KYBER_POLYVECCOMPRESSEDBYTES]);
13
+
14
+ void PQCLEAN_MLKEM1024_CLEAN_polyvec_tobytes(uint8_t r[KYBER_POLYVECBYTES], const polyvec *a);
15
+ void PQCLEAN_MLKEM1024_CLEAN_polyvec_frombytes(polyvec *r, const uint8_t a[KYBER_POLYVECBYTES]);
16
+
17
+ void PQCLEAN_MLKEM1024_CLEAN_polyvec_ntt(polyvec *r);
18
+ void PQCLEAN_MLKEM1024_CLEAN_polyvec_invntt_tomont(polyvec *r);
19
+
20
+ void PQCLEAN_MLKEM1024_CLEAN_polyvec_basemul_acc_montgomery(poly *r, const polyvec *a, const polyvec *b);
21
+
22
+ void PQCLEAN_MLKEM1024_CLEAN_polyvec_reduce(polyvec *r);
23
+
24
+ void PQCLEAN_MLKEM1024_CLEAN_polyvec_add(polyvec *r, const polyvec *a, const polyvec *b);
25
+
26
+ #endif
@@ -0,0 +1,41 @@
1
+ #include "params.h"
2
+ #include "reduce.h"
3
+ #include <stdint.h>
4
+
5
+ /*************************************************
6
+ * Name: PQCLEAN_MLKEM1024_CLEAN_montgomery_reduce
7
+ *
8
+ * Description: Montgomery reduction; given a 32-bit integer a, computes
9
+ * 16-bit integer congruent to a * R^-1 mod q, where R=2^16
10
+ *
11
+ * Arguments: - int32_t a: input integer to be reduced;
12
+ * has to be in {-q2^15,...,q2^15-1}
13
+ *
14
+ * Returns: integer in {-q+1,...,q-1} congruent to a * R^-1 modulo q.
15
+ **************************************************/
16
+ int16_t PQCLEAN_MLKEM1024_CLEAN_montgomery_reduce(int32_t a) {
17
+ int16_t t;
18
+
19
+ t = (int16_t)a * QINV;
20
+ t = (a - (int32_t)t * KYBER_Q) >> 16;
21
+ return t;
22
+ }
23
+
24
+ /*************************************************
25
+ * Name: PQCLEAN_MLKEM1024_CLEAN_barrett_reduce
26
+ *
27
+ * Description: Barrett reduction; given a 16-bit integer a, computes
28
+ * centered representative congruent to a mod q in {-(q-1)/2,...,(q-1)/2}
29
+ *
30
+ * Arguments: - int16_t a: input integer to be reduced
31
+ *
32
+ * Returns: integer in {-(q-1)/2,...,(q-1)/2} congruent to a modulo q.
33
+ **************************************************/
34
+ int16_t PQCLEAN_MLKEM1024_CLEAN_barrett_reduce(int16_t a) {
35
+ int16_t t;
36
+ const int16_t v = ((1 << 26) + KYBER_Q / 2) / KYBER_Q;
37
+
38
+ t = ((int32_t)v * a + (1 << 25)) >> 26;
39
+ t *= KYBER_Q;
40
+ return a - t;
41
+ }
@@ -0,0 +1,13 @@
1
+ #ifndef PQCLEAN_MLKEM1024_CLEAN_REDUCE_H
2
+ #define PQCLEAN_MLKEM1024_CLEAN_REDUCE_H
3
+ #include "params.h"
4
+ #include <stdint.h>
5
+
6
+ #define MONT (-1044) // 2^16 mod q
7
+ #define QINV (-3327) // q^-1 mod 2^16
8
+
9
+ int16_t PQCLEAN_MLKEM1024_CLEAN_montgomery_reduce(int32_t a);
10
+
11
+ int16_t PQCLEAN_MLKEM1024_CLEAN_barrett_reduce(int16_t a);
12
+
13
+ #endif