pq_crypto 0.1.0
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.
- checksums.yaml +7 -0
- data/.github/workflows/ci.yml +37 -0
- data/CHANGELOG.md +29 -0
- data/GET_STARTED.md +65 -0
- data/LICENSE.txt +21 -0
- data/README.md +135 -0
- data/SECURITY.md +57 -0
- data/ext/pqcrypto/extconf.rb +157 -0
- data/ext/pqcrypto/mldsa_api.h +51 -0
- data/ext/pqcrypto/mlkem_api.h +21 -0
- data/ext/pqcrypto/pqcrypto_ruby_secure.c +889 -0
- data/ext/pqcrypto/pqcrypto_secure.c +1178 -0
- data/ext/pqcrypto/pqcrypto_secure.h +135 -0
- data/ext/pqcrypto/vendor/.vendored +5 -0
- data/ext/pqcrypto/vendor/pqclean/common/aes.c +639 -0
- data/ext/pqcrypto/vendor/pqclean/common/aes.h +64 -0
- data/ext/pqcrypto/vendor/pqclean/common/compat.h +73 -0
- data/ext/pqcrypto/vendor/pqclean/common/crypto_declassify.h +7 -0
- data/ext/pqcrypto/vendor/pqclean/common/fips202.c +928 -0
- data/ext/pqcrypto/vendor/pqclean/common/fips202.h +166 -0
- data/ext/pqcrypto/vendor/pqclean/common/keccak2x/feat.S +168 -0
- data/ext/pqcrypto/vendor/pqclean/common/keccak2x/fips202x2.c +684 -0
- data/ext/pqcrypto/vendor/pqclean/common/keccak2x/fips202x2.h +60 -0
- data/ext/pqcrypto/vendor/pqclean/common/keccak4x/KeccakP-1600-times4-SIMD256.c +1028 -0
- data/ext/pqcrypto/vendor/pqclean/common/keccak4x/KeccakP-1600-times4-SnP.h +50 -0
- data/ext/pqcrypto/vendor/pqclean/common/keccak4x/KeccakP-1600-unrolling.macros +198 -0
- data/ext/pqcrypto/vendor/pqclean/common/keccak4x/Makefile +8 -0
- data/ext/pqcrypto/vendor/pqclean/common/keccak4x/Makefile.Microsoft_nmake +8 -0
- data/ext/pqcrypto/vendor/pqclean/common/keccak4x/SIMD256-config.h +3 -0
- data/ext/pqcrypto/vendor/pqclean/common/keccak4x/align.h +34 -0
- data/ext/pqcrypto/vendor/pqclean/common/keccak4x/brg_endian.h +142 -0
- data/ext/pqcrypto/vendor/pqclean/common/nistseedexpander.c +101 -0
- data/ext/pqcrypto/vendor/pqclean/common/nistseedexpander.h +39 -0
- data/ext/pqcrypto/vendor/pqclean/common/randombytes.c +355 -0
- data/ext/pqcrypto/vendor/pqclean/common/randombytes.h +27 -0
- data/ext/pqcrypto/vendor/pqclean/common/sha2.c +769 -0
- data/ext/pqcrypto/vendor/pqclean/common/sha2.h +173 -0
- data/ext/pqcrypto/vendor/pqclean/common/sp800-185.c +156 -0
- data/ext/pqcrypto/vendor/pqclean/common/sp800-185.h +27 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/LICENSE +5 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/Makefile +19 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/Makefile.Microsoft_nmake +23 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/api.h +18 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/cbd.c +83 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/cbd.h +11 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/indcpa.c +327 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/indcpa.h +22 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/kem.c +164 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/kem.h +23 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/ntt.c +146 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/ntt.h +14 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/params.h +36 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/poly.c +299 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/poly.h +37 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/polyvec.c +188 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/polyvec.h +26 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/reduce.c +41 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/reduce.h +13 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/symmetric-shake.c +71 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/symmetric.h +30 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/verify.c +67 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/verify.h +13 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/LICENSE +5 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/Makefile +19 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/Makefile.Microsoft_nmake +23 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/api.h +50 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/ntt.c +98 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/ntt.h +10 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/packing.c +261 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/packing.h +31 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/params.h +44 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/poly.c +799 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/poly.h +52 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/polyvec.c +415 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/polyvec.h +65 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/reduce.c +69 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/reduce.h +17 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/rounding.c +92 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/rounding.h +14 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/sign.c +407 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/sign.h +47 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/symmetric-shake.c +26 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/symmetric.h +34 -0
- data/lib/pq_crypto/errors.rb +10 -0
- data/lib/pq_crypto/hybrid_kem.rb +106 -0
- data/lib/pq_crypto/kem.rb +199 -0
- data/lib/pq_crypto/serialization.rb +102 -0
- data/lib/pq_crypto/signature.rb +198 -0
- data/lib/pq_crypto/version.rb +5 -0
- data/lib/pq_crypto.rb +177 -0
- data/lib/pqcrypto.rb +3 -0
- data/script/vendor_libs.rb +199 -0
- metadata +195 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#ifndef PQCLEAN_MLKEM768_CLEAN_NTT_H
|
|
2
|
+
#define PQCLEAN_MLKEM768_CLEAN_NTT_H
|
|
3
|
+
#include "params.h"
|
|
4
|
+
#include <stdint.h>
|
|
5
|
+
|
|
6
|
+
extern const int16_t PQCLEAN_MLKEM768_CLEAN_zetas[128];
|
|
7
|
+
|
|
8
|
+
void PQCLEAN_MLKEM768_CLEAN_ntt(int16_t r[256]);
|
|
9
|
+
|
|
10
|
+
void PQCLEAN_MLKEM768_CLEAN_invntt(int16_t r[256]);
|
|
11
|
+
|
|
12
|
+
void PQCLEAN_MLKEM768_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_MLKEM768_CLEAN_PARAMS_H
|
|
2
|
+
#define PQCLEAN_MLKEM768_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 3
|
|
20
|
+
#define KYBER_ETA1 2
|
|
21
|
+
#define KYBER_POLYCOMPRESSEDBYTES 128
|
|
22
|
+
#define KYBER_POLYVECCOMPRESSEDBYTES (KYBER_K * 320)
|
|
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,299 @@
|
|
|
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_MLKEM768_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_MLKEM768_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
|
+
|
|
26
|
+
for (i = 0; i < KYBER_N / 8; i++) {
|
|
27
|
+
for (j = 0; j < 8; j++) {
|
|
28
|
+
// map to positive standard representatives
|
|
29
|
+
u = a->coeffs[8 * i + j];
|
|
30
|
+
u += (u >> 15) & KYBER_Q;
|
|
31
|
+
/* t[j] = ((((uint16_t)u << 4) + KYBER_Q/2)/KYBER_Q) & 15; */
|
|
32
|
+
d0 = u << 4;
|
|
33
|
+
d0 += 1665;
|
|
34
|
+
d0 *= 80635;
|
|
35
|
+
d0 >>= 28;
|
|
36
|
+
t[j] = d0 & 0xf;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
r[0] = t[0] | (t[1] << 4);
|
|
40
|
+
r[1] = t[2] | (t[3] << 4);
|
|
41
|
+
r[2] = t[4] | (t[5] << 4);
|
|
42
|
+
r[3] = t[6] | (t[7] << 4);
|
|
43
|
+
r += 4;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/*************************************************
|
|
48
|
+
* Name: PQCLEAN_MLKEM768_CLEAN_poly_decompress
|
|
49
|
+
*
|
|
50
|
+
* Description: De-serialization and subsequent decompression of a polynomial;
|
|
51
|
+
* approximate inverse of PQCLEAN_MLKEM768_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_MLKEM768_CLEAN_poly_decompress(poly *r, const uint8_t a[KYBER_POLYCOMPRESSEDBYTES]) {
|
|
58
|
+
size_t i;
|
|
59
|
+
|
|
60
|
+
for (i = 0; i < KYBER_N / 2; i++) {
|
|
61
|
+
r->coeffs[2 * i + 0] = (((uint16_t)(a[0] & 15) * KYBER_Q) + 8) >> 4;
|
|
62
|
+
r->coeffs[2 * i + 1] = (((uint16_t)(a[0] >> 4) * KYBER_Q) + 8) >> 4;
|
|
63
|
+
a += 1;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/*************************************************
|
|
68
|
+
* Name: PQCLEAN_MLKEM768_CLEAN_poly_tobytes
|
|
69
|
+
*
|
|
70
|
+
* Description: Serialization of a polynomial
|
|
71
|
+
*
|
|
72
|
+
* Arguments: - uint8_t *r: pointer to output byte array
|
|
73
|
+
* (needs space for KYBER_POLYBYTES bytes)
|
|
74
|
+
* - const poly *a: pointer to input polynomial
|
|
75
|
+
**************************************************/
|
|
76
|
+
void PQCLEAN_MLKEM768_CLEAN_poly_tobytes(uint8_t r[KYBER_POLYBYTES], const poly *a) {
|
|
77
|
+
size_t i;
|
|
78
|
+
uint16_t t0, t1;
|
|
79
|
+
|
|
80
|
+
for (i = 0; i < KYBER_N / 2; i++) {
|
|
81
|
+
// map to positive standard representatives
|
|
82
|
+
t0 = a->coeffs[2 * i];
|
|
83
|
+
t0 += ((int16_t)t0 >> 15) & KYBER_Q;
|
|
84
|
+
t1 = a->coeffs[2 * i + 1];
|
|
85
|
+
t1 += ((int16_t)t1 >> 15) & KYBER_Q;
|
|
86
|
+
r[3 * i + 0] = (uint8_t)(t0 >> 0);
|
|
87
|
+
r[3 * i + 1] = (uint8_t)((t0 >> 8) | (t1 << 4));
|
|
88
|
+
r[3 * i + 2] = (uint8_t)(t1 >> 4);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/*************************************************
|
|
93
|
+
* Name: PQCLEAN_MLKEM768_CLEAN_poly_frombytes
|
|
94
|
+
*
|
|
95
|
+
* Description: De-serialization of a polynomial;
|
|
96
|
+
* inverse of PQCLEAN_MLKEM768_CLEAN_poly_tobytes
|
|
97
|
+
*
|
|
98
|
+
* Arguments: - poly *r: pointer to output polynomial
|
|
99
|
+
* - const uint8_t *a: pointer to input byte array
|
|
100
|
+
* (of KYBER_POLYBYTES bytes)
|
|
101
|
+
**************************************************/
|
|
102
|
+
void PQCLEAN_MLKEM768_CLEAN_poly_frombytes(poly *r, const uint8_t a[KYBER_POLYBYTES]) {
|
|
103
|
+
size_t i;
|
|
104
|
+
for (i = 0; i < KYBER_N / 2; i++) {
|
|
105
|
+
r->coeffs[2 * i] = ((a[3 * i + 0] >> 0) | ((uint16_t)a[3 * i + 1] << 8)) & 0xFFF;
|
|
106
|
+
r->coeffs[2 * i + 1] = ((a[3 * i + 1] >> 4) | ((uint16_t)a[3 * i + 2] << 4)) & 0xFFF;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/*************************************************
|
|
111
|
+
* Name: PQCLEAN_MLKEM768_CLEAN_poly_frommsg
|
|
112
|
+
*
|
|
113
|
+
* Description: Convert 32-byte message to polynomial
|
|
114
|
+
*
|
|
115
|
+
* Arguments: - poly *r: pointer to output polynomial
|
|
116
|
+
* - const uint8_t *msg: pointer to input message
|
|
117
|
+
**************************************************/
|
|
118
|
+
void PQCLEAN_MLKEM768_CLEAN_poly_frommsg(poly *r, const uint8_t msg[KYBER_INDCPA_MSGBYTES]) {
|
|
119
|
+
size_t i, j;
|
|
120
|
+
|
|
121
|
+
for (i = 0; i < KYBER_N / 8; i++) {
|
|
122
|
+
for (j = 0; j < 8; j++) {
|
|
123
|
+
r->coeffs[8 * i + j] = 0;
|
|
124
|
+
PQCLEAN_MLKEM768_CLEAN_cmov_int16(r->coeffs + 8 * i + j, ((KYBER_Q + 1) / 2), (msg[i] >> j) & 1);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/*************************************************
|
|
130
|
+
* Name: PQCLEAN_MLKEM768_CLEAN_poly_tomsg
|
|
131
|
+
*
|
|
132
|
+
* Description: Convert polynomial to 32-byte message
|
|
133
|
+
*
|
|
134
|
+
* Arguments: - uint8_t *msg: pointer to output message
|
|
135
|
+
* - const poly *a: pointer to input polynomial
|
|
136
|
+
**************************************************/
|
|
137
|
+
void PQCLEAN_MLKEM768_CLEAN_poly_tomsg(uint8_t msg[KYBER_INDCPA_MSGBYTES], const poly *a) {
|
|
138
|
+
unsigned int i, j;
|
|
139
|
+
uint32_t t;
|
|
140
|
+
|
|
141
|
+
for (i = 0; i < KYBER_N / 8; i++) {
|
|
142
|
+
msg[i] = 0;
|
|
143
|
+
for (j = 0; j < 8; j++) {
|
|
144
|
+
t = a->coeffs[8 * i + j];
|
|
145
|
+
// t += ((int16_t)t >> 15) & KYBER_Q;
|
|
146
|
+
// t = (((t << 1) + KYBER_Q/2)/KYBER_Q) & 1;
|
|
147
|
+
t <<= 1;
|
|
148
|
+
t += 1665;
|
|
149
|
+
t *= 80635;
|
|
150
|
+
t >>= 28;
|
|
151
|
+
t &= 1;
|
|
152
|
+
msg[i] |= t << j;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/*************************************************
|
|
158
|
+
* Name: PQCLEAN_MLKEM768_CLEAN_poly_getnoise_eta1
|
|
159
|
+
*
|
|
160
|
+
* Description: Sample a polynomial deterministically from a seed and a nonce,
|
|
161
|
+
* with output polynomial close to centered binomial distribution
|
|
162
|
+
* with parameter KYBER_ETA1
|
|
163
|
+
*
|
|
164
|
+
* Arguments: - poly *r: pointer to output polynomial
|
|
165
|
+
* - const uint8_t *seed: pointer to input seed
|
|
166
|
+
* (of length KYBER_SYMBYTES bytes)
|
|
167
|
+
* - uint8_t nonce: one-byte input nonce
|
|
168
|
+
**************************************************/
|
|
169
|
+
void PQCLEAN_MLKEM768_CLEAN_poly_getnoise_eta1(poly *r, const uint8_t seed[KYBER_SYMBYTES], uint8_t nonce) {
|
|
170
|
+
uint8_t buf[KYBER_ETA1 * KYBER_N / 4];
|
|
171
|
+
prf(buf, sizeof(buf), seed, nonce);
|
|
172
|
+
PQCLEAN_MLKEM768_CLEAN_poly_cbd_eta1(r, buf);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/*************************************************
|
|
176
|
+
* Name: PQCLEAN_MLKEM768_CLEAN_poly_getnoise_eta2
|
|
177
|
+
*
|
|
178
|
+
* Description: Sample a polynomial deterministically from a seed and a nonce,
|
|
179
|
+
* with output polynomial close to centered binomial distribution
|
|
180
|
+
* with parameter KYBER_ETA2
|
|
181
|
+
*
|
|
182
|
+
* Arguments: - poly *r: pointer to output polynomial
|
|
183
|
+
* - const uint8_t *seed: pointer to input seed
|
|
184
|
+
* (of length KYBER_SYMBYTES bytes)
|
|
185
|
+
* - uint8_t nonce: one-byte input nonce
|
|
186
|
+
**************************************************/
|
|
187
|
+
void PQCLEAN_MLKEM768_CLEAN_poly_getnoise_eta2(poly *r, const uint8_t seed[KYBER_SYMBYTES], uint8_t nonce) {
|
|
188
|
+
uint8_t buf[KYBER_ETA2 * KYBER_N / 4];
|
|
189
|
+
prf(buf, sizeof(buf), seed, nonce);
|
|
190
|
+
PQCLEAN_MLKEM768_CLEAN_poly_cbd_eta2(r, buf);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
/*************************************************
|
|
195
|
+
* Name: PQCLEAN_MLKEM768_CLEAN_poly_ntt
|
|
196
|
+
*
|
|
197
|
+
* Description: Computes negacyclic number-theoretic transform (NTT) of
|
|
198
|
+
* a polynomial in place;
|
|
199
|
+
* inputs assumed to be in normal order, output in bitreversed order
|
|
200
|
+
*
|
|
201
|
+
* Arguments: - uint16_t *r: pointer to in/output polynomial
|
|
202
|
+
**************************************************/
|
|
203
|
+
void PQCLEAN_MLKEM768_CLEAN_poly_ntt(poly *r) {
|
|
204
|
+
PQCLEAN_MLKEM768_CLEAN_ntt(r->coeffs);
|
|
205
|
+
PQCLEAN_MLKEM768_CLEAN_poly_reduce(r);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/*************************************************
|
|
209
|
+
* Name: PQCLEAN_MLKEM768_CLEAN_poly_invntt_tomont
|
|
210
|
+
*
|
|
211
|
+
* Description: Computes inverse of negacyclic number-theoretic transform (NTT)
|
|
212
|
+
* of a polynomial in place;
|
|
213
|
+
* inputs assumed to be in bitreversed order, output in normal order
|
|
214
|
+
*
|
|
215
|
+
* Arguments: - uint16_t *a: pointer to in/output polynomial
|
|
216
|
+
**************************************************/
|
|
217
|
+
void PQCLEAN_MLKEM768_CLEAN_poly_invntt_tomont(poly *r) {
|
|
218
|
+
PQCLEAN_MLKEM768_CLEAN_invntt(r->coeffs);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/*************************************************
|
|
222
|
+
* Name: PQCLEAN_MLKEM768_CLEAN_poly_basemul_montgomery
|
|
223
|
+
*
|
|
224
|
+
* Description: Multiplication of two polynomials in NTT domain
|
|
225
|
+
*
|
|
226
|
+
* Arguments: - poly *r: pointer to output polynomial
|
|
227
|
+
* - const poly *a: pointer to first input polynomial
|
|
228
|
+
* - const poly *b: pointer to second input polynomial
|
|
229
|
+
**************************************************/
|
|
230
|
+
void PQCLEAN_MLKEM768_CLEAN_poly_basemul_montgomery(poly *r, const poly *a, const poly *b) {
|
|
231
|
+
size_t i;
|
|
232
|
+
for (i = 0; i < KYBER_N / 4; i++) {
|
|
233
|
+
PQCLEAN_MLKEM768_CLEAN_basemul(&r->coeffs[4 * i], &a->coeffs[4 * i], &b->coeffs[4 * i], PQCLEAN_MLKEM768_CLEAN_zetas[64 + i]);
|
|
234
|
+
PQCLEAN_MLKEM768_CLEAN_basemul(&r->coeffs[4 * i + 2], &a->coeffs[4 * i + 2], &b->coeffs[4 * i + 2], -PQCLEAN_MLKEM768_CLEAN_zetas[64 + i]);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/*************************************************
|
|
239
|
+
* Name: PQCLEAN_MLKEM768_CLEAN_poly_tomont
|
|
240
|
+
*
|
|
241
|
+
* Description: Inplace conversion of all coefficients of a polynomial
|
|
242
|
+
* from normal domain to Montgomery domain
|
|
243
|
+
*
|
|
244
|
+
* Arguments: - poly *r: pointer to input/output polynomial
|
|
245
|
+
**************************************************/
|
|
246
|
+
void PQCLEAN_MLKEM768_CLEAN_poly_tomont(poly *r) {
|
|
247
|
+
size_t i;
|
|
248
|
+
const int16_t f = (1ULL << 32) % KYBER_Q;
|
|
249
|
+
for (i = 0; i < KYBER_N; i++) {
|
|
250
|
+
r->coeffs[i] = PQCLEAN_MLKEM768_CLEAN_montgomery_reduce((int32_t)r->coeffs[i] * f);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/*************************************************
|
|
255
|
+
* Name: PQCLEAN_MLKEM768_CLEAN_poly_reduce
|
|
256
|
+
*
|
|
257
|
+
* Description: Applies Barrett reduction to all coefficients of a polynomial
|
|
258
|
+
* for details of the Barrett reduction see comments in reduce.c
|
|
259
|
+
*
|
|
260
|
+
* Arguments: - poly *r: pointer to input/output polynomial
|
|
261
|
+
**************************************************/
|
|
262
|
+
void PQCLEAN_MLKEM768_CLEAN_poly_reduce(poly *r) {
|
|
263
|
+
size_t i;
|
|
264
|
+
for (i = 0; i < KYBER_N; i++) {
|
|
265
|
+
r->coeffs[i] = PQCLEAN_MLKEM768_CLEAN_barrett_reduce(r->coeffs[i]);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/*************************************************
|
|
270
|
+
* Name: PQCLEAN_MLKEM768_CLEAN_poly_add
|
|
271
|
+
*
|
|
272
|
+
* Description: Add two polynomials; no modular reduction is performed
|
|
273
|
+
*
|
|
274
|
+
* Arguments: - poly *r: pointer to output polynomial
|
|
275
|
+
* - const poly *a: pointer to first input polynomial
|
|
276
|
+
* - const poly *b: pointer to second input polynomial
|
|
277
|
+
**************************************************/
|
|
278
|
+
void PQCLEAN_MLKEM768_CLEAN_poly_add(poly *r, const poly *a, const poly *b) {
|
|
279
|
+
size_t i;
|
|
280
|
+
for (i = 0; i < KYBER_N; i++) {
|
|
281
|
+
r->coeffs[i] = a->coeffs[i] + b->coeffs[i];
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/*************************************************
|
|
286
|
+
* Name: PQCLEAN_MLKEM768_CLEAN_poly_sub
|
|
287
|
+
*
|
|
288
|
+
* Description: Subtract two polynomials; no modular reduction is performed
|
|
289
|
+
*
|
|
290
|
+
* Arguments: - poly *r: pointer to output polynomial
|
|
291
|
+
* - const poly *a: pointer to first input polynomial
|
|
292
|
+
* - const poly *b: pointer to second input polynomial
|
|
293
|
+
**************************************************/
|
|
294
|
+
void PQCLEAN_MLKEM768_CLEAN_poly_sub(poly *r, const poly *a, const poly *b) {
|
|
295
|
+
size_t i;
|
|
296
|
+
for (i = 0; i < KYBER_N; i++) {
|
|
297
|
+
r->coeffs[i] = a->coeffs[i] - b->coeffs[i];
|
|
298
|
+
}
|
|
299
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#ifndef PQCLEAN_MLKEM768_CLEAN_POLY_H
|
|
2
|
+
#define PQCLEAN_MLKEM768_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_MLKEM768_CLEAN_poly_compress(uint8_t r[KYBER_POLYCOMPRESSEDBYTES], const poly *a);
|
|
15
|
+
void PQCLEAN_MLKEM768_CLEAN_poly_decompress(poly *r, const uint8_t a[KYBER_POLYCOMPRESSEDBYTES]);
|
|
16
|
+
|
|
17
|
+
void PQCLEAN_MLKEM768_CLEAN_poly_tobytes(uint8_t r[KYBER_POLYBYTES], const poly *a);
|
|
18
|
+
void PQCLEAN_MLKEM768_CLEAN_poly_frombytes(poly *r, const uint8_t a[KYBER_POLYBYTES]);
|
|
19
|
+
|
|
20
|
+
void PQCLEAN_MLKEM768_CLEAN_poly_frommsg(poly *r, const uint8_t msg[KYBER_INDCPA_MSGBYTES]);
|
|
21
|
+
void PQCLEAN_MLKEM768_CLEAN_poly_tomsg(uint8_t msg[KYBER_INDCPA_MSGBYTES], const poly *a);
|
|
22
|
+
|
|
23
|
+
void PQCLEAN_MLKEM768_CLEAN_poly_getnoise_eta1(poly *r, const uint8_t seed[KYBER_SYMBYTES], uint8_t nonce);
|
|
24
|
+
|
|
25
|
+
void PQCLEAN_MLKEM768_CLEAN_poly_getnoise_eta2(poly *r, const uint8_t seed[KYBER_SYMBYTES], uint8_t nonce);
|
|
26
|
+
|
|
27
|
+
void PQCLEAN_MLKEM768_CLEAN_poly_ntt(poly *r);
|
|
28
|
+
void PQCLEAN_MLKEM768_CLEAN_poly_invntt_tomont(poly *r);
|
|
29
|
+
void PQCLEAN_MLKEM768_CLEAN_poly_basemul_montgomery(poly *r, const poly *a, const poly *b);
|
|
30
|
+
void PQCLEAN_MLKEM768_CLEAN_poly_tomont(poly *r);
|
|
31
|
+
|
|
32
|
+
void PQCLEAN_MLKEM768_CLEAN_poly_reduce(poly *r);
|
|
33
|
+
|
|
34
|
+
void PQCLEAN_MLKEM768_CLEAN_poly_add(poly *r, const poly *a, const poly *b);
|
|
35
|
+
void PQCLEAN_MLKEM768_CLEAN_poly_sub(poly *r, const poly *a, const poly *b);
|
|
36
|
+
|
|
37
|
+
#endif
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
#include "params.h"
|
|
2
|
+
#include "poly.h"
|
|
3
|
+
#include "polyvec.h"
|
|
4
|
+
#include <stdint.h>
|
|
5
|
+
|
|
6
|
+
/*************************************************
|
|
7
|
+
* Name: PQCLEAN_MLKEM768_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_MLKEM768_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[4];
|
|
20
|
+
for (i = 0; i < KYBER_K; i++) {
|
|
21
|
+
for (j = 0; j < KYBER_N / 4; j++) {
|
|
22
|
+
for (k = 0; k < 4; k++) {
|
|
23
|
+
t[k] = a->vec[i].coeffs[4 * j + k];
|
|
24
|
+
t[k] += ((int16_t)t[k] >> 15) & KYBER_Q;
|
|
25
|
+
/* t[k] = ((((uint32_t)t[k] << 10) + KYBER_Q/2)/ KYBER_Q) & 0x3ff; */
|
|
26
|
+
d0 = t[k];
|
|
27
|
+
d0 <<= 10;
|
|
28
|
+
d0 += 1665;
|
|
29
|
+
d0 *= 1290167;
|
|
30
|
+
d0 >>= 32;
|
|
31
|
+
t[k] = d0 & 0x3ff;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
r[0] = (uint8_t)(t[0] >> 0);
|
|
35
|
+
r[1] = (uint8_t)((t[0] >> 8) | (t[1] << 2));
|
|
36
|
+
r[2] = (uint8_t)((t[1] >> 6) | (t[2] << 4));
|
|
37
|
+
r[3] = (uint8_t)((t[2] >> 4) | (t[3] << 6));
|
|
38
|
+
r[4] = (uint8_t)(t[3] >> 2);
|
|
39
|
+
r += 5;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/*************************************************
|
|
45
|
+
* Name: PQCLEAN_MLKEM768_CLEAN_polyvec_decompress
|
|
46
|
+
*
|
|
47
|
+
* Description: De-serialize and decompress vector of polynomials;
|
|
48
|
+
* approximate inverse of PQCLEAN_MLKEM768_CLEAN_polyvec_compress
|
|
49
|
+
*
|
|
50
|
+
* Arguments: - polyvec *r: pointer to output vector of polynomials
|
|
51
|
+
* - const uint8_t *a: pointer to input byte array
|
|
52
|
+
* (of length KYBER_POLYVECCOMPRESSEDBYTES)
|
|
53
|
+
**************************************************/
|
|
54
|
+
void PQCLEAN_MLKEM768_CLEAN_polyvec_decompress(polyvec *r, const uint8_t a[KYBER_POLYVECCOMPRESSEDBYTES]) {
|
|
55
|
+
unsigned int i, j, k;
|
|
56
|
+
|
|
57
|
+
uint16_t t[4];
|
|
58
|
+
for (i = 0; i < KYBER_K; i++) {
|
|
59
|
+
for (j = 0; j < KYBER_N / 4; j++) {
|
|
60
|
+
t[0] = (a[0] >> 0) | ((uint16_t)a[1] << 8);
|
|
61
|
+
t[1] = (a[1] >> 2) | ((uint16_t)a[2] << 6);
|
|
62
|
+
t[2] = (a[2] >> 4) | ((uint16_t)a[3] << 4);
|
|
63
|
+
t[3] = (a[3] >> 6) | ((uint16_t)a[4] << 2);
|
|
64
|
+
a += 5;
|
|
65
|
+
|
|
66
|
+
for (k = 0; k < 4; k++) {
|
|
67
|
+
r->vec[i].coeffs[4 * j + k] = ((uint32_t)(t[k] & 0x3FF) * KYBER_Q + 512) >> 10;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/*************************************************
|
|
74
|
+
* Name: PQCLEAN_MLKEM768_CLEAN_polyvec_tobytes
|
|
75
|
+
*
|
|
76
|
+
* Description: Serialize vector of polynomials
|
|
77
|
+
*
|
|
78
|
+
* Arguments: - uint8_t *r: pointer to output byte array
|
|
79
|
+
* (needs space for KYBER_POLYVECBYTES)
|
|
80
|
+
* - const polyvec *a: pointer to input vector of polynomials
|
|
81
|
+
**************************************************/
|
|
82
|
+
void PQCLEAN_MLKEM768_CLEAN_polyvec_tobytes(uint8_t r[KYBER_POLYVECBYTES], const polyvec *a) {
|
|
83
|
+
unsigned int i;
|
|
84
|
+
for (i = 0; i < KYBER_K; i++) {
|
|
85
|
+
PQCLEAN_MLKEM768_CLEAN_poly_tobytes(r + i * KYBER_POLYBYTES, &a->vec[i]);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/*************************************************
|
|
90
|
+
* Name: PQCLEAN_MLKEM768_CLEAN_polyvec_frombytes
|
|
91
|
+
*
|
|
92
|
+
* Description: De-serialize vector of polynomials;
|
|
93
|
+
* inverse of PQCLEAN_MLKEM768_CLEAN_polyvec_tobytes
|
|
94
|
+
*
|
|
95
|
+
* Arguments: - uint8_t *r: pointer to output byte array
|
|
96
|
+
* - const polyvec *a: pointer to input vector of polynomials
|
|
97
|
+
* (of length KYBER_POLYVECBYTES)
|
|
98
|
+
**************************************************/
|
|
99
|
+
void PQCLEAN_MLKEM768_CLEAN_polyvec_frombytes(polyvec *r, const uint8_t a[KYBER_POLYVECBYTES]) {
|
|
100
|
+
unsigned int i;
|
|
101
|
+
for (i = 0; i < KYBER_K; i++) {
|
|
102
|
+
PQCLEAN_MLKEM768_CLEAN_poly_frombytes(&r->vec[i], a + i * KYBER_POLYBYTES);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/*************************************************
|
|
107
|
+
* Name: PQCLEAN_MLKEM768_CLEAN_polyvec_ntt
|
|
108
|
+
*
|
|
109
|
+
* Description: Apply forward NTT to all elements of a vector of polynomials
|
|
110
|
+
*
|
|
111
|
+
* Arguments: - polyvec *r: pointer to in/output vector of polynomials
|
|
112
|
+
**************************************************/
|
|
113
|
+
void PQCLEAN_MLKEM768_CLEAN_polyvec_ntt(polyvec *r) {
|
|
114
|
+
unsigned int i;
|
|
115
|
+
for (i = 0; i < KYBER_K; i++) {
|
|
116
|
+
PQCLEAN_MLKEM768_CLEAN_poly_ntt(&r->vec[i]);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/*************************************************
|
|
121
|
+
* Name: PQCLEAN_MLKEM768_CLEAN_polyvec_invntt_tomont
|
|
122
|
+
*
|
|
123
|
+
* Description: Apply inverse NTT to all elements of a vector of polynomials
|
|
124
|
+
* and multiply by Montgomery factor 2^16
|
|
125
|
+
*
|
|
126
|
+
* Arguments: - polyvec *r: pointer to in/output vector of polynomials
|
|
127
|
+
**************************************************/
|
|
128
|
+
void PQCLEAN_MLKEM768_CLEAN_polyvec_invntt_tomont(polyvec *r) {
|
|
129
|
+
unsigned int i;
|
|
130
|
+
for (i = 0; i < KYBER_K; i++) {
|
|
131
|
+
PQCLEAN_MLKEM768_CLEAN_poly_invntt_tomont(&r->vec[i]);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/*************************************************
|
|
136
|
+
* Name: PQCLEAN_MLKEM768_CLEAN_polyvec_basemul_acc_montgomery
|
|
137
|
+
*
|
|
138
|
+
* Description: Multiply elements of a and b in NTT domain, accumulate into r,
|
|
139
|
+
* and multiply by 2^-16.
|
|
140
|
+
*
|
|
141
|
+
* Arguments: - poly *r: pointer to output polynomial
|
|
142
|
+
* - const polyvec *a: pointer to first input vector of polynomials
|
|
143
|
+
* - const polyvec *b: pointer to second input vector of polynomials
|
|
144
|
+
**************************************************/
|
|
145
|
+
void PQCLEAN_MLKEM768_CLEAN_polyvec_basemul_acc_montgomery(poly *r, const polyvec *a, const polyvec *b) {
|
|
146
|
+
unsigned int i;
|
|
147
|
+
poly t;
|
|
148
|
+
|
|
149
|
+
PQCLEAN_MLKEM768_CLEAN_poly_basemul_montgomery(r, &a->vec[0], &b->vec[0]);
|
|
150
|
+
for (i = 1; i < KYBER_K; i++) {
|
|
151
|
+
PQCLEAN_MLKEM768_CLEAN_poly_basemul_montgomery(&t, &a->vec[i], &b->vec[i]);
|
|
152
|
+
PQCLEAN_MLKEM768_CLEAN_poly_add(r, r, &t);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
PQCLEAN_MLKEM768_CLEAN_poly_reduce(r);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/*************************************************
|
|
159
|
+
* Name: PQCLEAN_MLKEM768_CLEAN_polyvec_reduce
|
|
160
|
+
*
|
|
161
|
+
* Description: Applies Barrett reduction to each coefficient
|
|
162
|
+
* of each element of a vector of polynomials;
|
|
163
|
+
* for details of the Barrett reduction see comments in reduce.c
|
|
164
|
+
*
|
|
165
|
+
* Arguments: - polyvec *r: pointer to input/output polynomial
|
|
166
|
+
**************************************************/
|
|
167
|
+
void PQCLEAN_MLKEM768_CLEAN_polyvec_reduce(polyvec *r) {
|
|
168
|
+
unsigned int i;
|
|
169
|
+
for (i = 0; i < KYBER_K; i++) {
|
|
170
|
+
PQCLEAN_MLKEM768_CLEAN_poly_reduce(&r->vec[i]);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/*************************************************
|
|
175
|
+
* Name: PQCLEAN_MLKEM768_CLEAN_polyvec_add
|
|
176
|
+
*
|
|
177
|
+
* Description: Add vectors of polynomials
|
|
178
|
+
*
|
|
179
|
+
* Arguments: - polyvec *r: pointer to output vector of polynomials
|
|
180
|
+
* - const polyvec *a: pointer to first input vector of polynomials
|
|
181
|
+
* - const polyvec *b: pointer to second input vector of polynomials
|
|
182
|
+
**************************************************/
|
|
183
|
+
void PQCLEAN_MLKEM768_CLEAN_polyvec_add(polyvec *r, const polyvec *a, const polyvec *b) {
|
|
184
|
+
unsigned int i;
|
|
185
|
+
for (i = 0; i < KYBER_K; i++) {
|
|
186
|
+
PQCLEAN_MLKEM768_CLEAN_poly_add(&r->vec[i], &a->vec[i], &b->vec[i]);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#ifndef PQCLEAN_MLKEM768_CLEAN_POLYVEC_H
|
|
2
|
+
#define PQCLEAN_MLKEM768_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_MLKEM768_CLEAN_polyvec_compress(uint8_t r[KYBER_POLYVECCOMPRESSEDBYTES], const polyvec *a);
|
|
12
|
+
void PQCLEAN_MLKEM768_CLEAN_polyvec_decompress(polyvec *r, const uint8_t a[KYBER_POLYVECCOMPRESSEDBYTES]);
|
|
13
|
+
|
|
14
|
+
void PQCLEAN_MLKEM768_CLEAN_polyvec_tobytes(uint8_t r[KYBER_POLYVECBYTES], const polyvec *a);
|
|
15
|
+
void PQCLEAN_MLKEM768_CLEAN_polyvec_frombytes(polyvec *r, const uint8_t a[KYBER_POLYVECBYTES]);
|
|
16
|
+
|
|
17
|
+
void PQCLEAN_MLKEM768_CLEAN_polyvec_ntt(polyvec *r);
|
|
18
|
+
void PQCLEAN_MLKEM768_CLEAN_polyvec_invntt_tomont(polyvec *r);
|
|
19
|
+
|
|
20
|
+
void PQCLEAN_MLKEM768_CLEAN_polyvec_basemul_acc_montgomery(poly *r, const polyvec *a, const polyvec *b);
|
|
21
|
+
|
|
22
|
+
void PQCLEAN_MLKEM768_CLEAN_polyvec_reduce(polyvec *r);
|
|
23
|
+
|
|
24
|
+
void PQCLEAN_MLKEM768_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_MLKEM768_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_MLKEM768_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_MLKEM768_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_MLKEM768_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_MLKEM768_CLEAN_REDUCE_H
|
|
2
|
+
#define PQCLEAN_MLKEM768_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_MLKEM768_CLEAN_montgomery_reduce(int32_t a);
|
|
10
|
+
|
|
11
|
+
int16_t PQCLEAN_MLKEM768_CLEAN_barrett_reduce(int16_t a);
|
|
12
|
+
|
|
13
|
+
#endif
|