kpqc 0.1.0 → 0.2.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 +4 -4
- data/CHANGELOG.md +15 -0
- data/Gemfile +4 -0
- data/README.md +9 -6
- data/THIRD_PARTY_NOTICES.md +14 -47
- data/ext/kpqc/extconf_helper.rb +6 -3
- data/ext/kpqc/secure_clear.c +8 -0
- data/kpqc.gemspec +4 -5
- data/lib/kpqc/aimer.rb +6 -6
- data/lib/kpqc/version.rb +1 -2
- data/test/kat/aimer128f.rsp +4 -4
- data/test/kat/aimer128s.rsp +4 -4
- data/test/kat/aimer192f.rsp +4 -4
- data/test/kat/aimer192s.rsp +4 -4
- data/test/kat/aimer256f.rsp +4 -4
- data/test/kat/aimer256s.rsp +4 -4
- data/test/kat/haetae2.rsp +1 -1
- data/test/kat/haetae3.rsp +1 -1
- data/test/kat/haetae5.rsp +1 -1
- data/vendor/AIMer/LICENSE +1 -1
- data/vendor/AIMer/aim3.c +227 -0
- data/vendor/AIMer/aim3.h +63 -0
- data/vendor/AIMer/field.h +12 -4
- data/vendor/AIMer/field128.c +24 -381
- data/vendor/AIMer/field192.c +24 -400
- data/vendor/AIMer/field256.c +28 -447
- data/vendor/AIMer/field_common.c +98 -0
- data/vendor/AIMer/field_internal.h +218 -0
- data/vendor/AIMer/params/params-aimer-128f.h +8 -8
- data/vendor/AIMer/params/params-aimer-128s.h +8 -8
- data/vendor/AIMer/params/params-aimer-192f.h +8 -8
- data/vendor/AIMer/params/params-aimer-192s.h +8 -8
- data/vendor/AIMer/params/params-aimer-256f.h +8 -8
- data/vendor/AIMer/params/params-aimer-256s.h +8 -8
- data/vendor/AIMer/params.h +5 -0
- data/vendor/AIMer/sign.c +246 -167
- data/vendor/AIMer/sign.h +6 -6
- data/vendor/AIMer/tree.c +10 -4
- data/vendor/AIMer/tree.h +1 -1
- data/vendor/HAETAE/include/fixpoint.h +14 -14
- data/vendor/HAETAE/include/rans_byte.h +10 -9
- data/vendor/HAETAE/src/decompose.c +8 -4
- data/vendor/HAETAE/src/encoding.c +5 -5
- data/vendor/HAETAE/src/fft.c +1 -1
- data/vendor/HAETAE/src/fips202.c +26 -14
- data/vendor/HAETAE/src/fixpoint.c +21 -18
- data/vendor/HAETAE/src/ntt.c +2 -0
- data/vendor/HAETAE/src/packing.c +15 -15
- data/vendor/HAETAE/src/poly.c +30 -3
- data/vendor/HAETAE/src/polyfix.c +2 -2
- data/vendor/HAETAE/src/polymat.c +2 -2
- data/vendor/HAETAE/src/polyvec.c +7 -5
- data/vendor/HAETAE/src/reduce.c +2 -0
- data/vendor/HAETAE/src/sampler.c +231 -47
- data/vendor/HAETAE/src/sign.c +11 -10
- data/vendor/NTRUplus/NTRU+1152/api.h +27 -8
- data/vendor/NTRUplus/NTRU+1152/fips202/fips202.c +12 -269
- data/vendor/NTRUplus/NTRU+1152/fips202/fips202.h +4 -113
- data/vendor/NTRUplus/NTRU+1152/kem.c +110 -40
- data/vendor/NTRUplus/NTRU+1152/ntt.c +50 -54
- data/vendor/NTRUplus/NTRU+1152/poly.c +21 -13
- data/vendor/NTRUplus/NTRU+1152/poly.h +3 -3
- data/vendor/NTRUplus/NTRU+1152/randombytes.h +1 -0
- data/vendor/NTRUplus/NTRU+1152/symmetric.c +3 -9
- data/vendor/NTRUplus/NTRU+1152/symmetric.h +13 -3
- data/vendor/NTRUplus/NTRU+1152/util.h +15 -0
- data/vendor/NTRUplus/NTRU+768/api.h +27 -8
- data/vendor/NTRUplus/NTRU+768/fips202/fips202.c +12 -269
- data/vendor/NTRUplus/NTRU+768/fips202/fips202.h +4 -113
- data/vendor/NTRUplus/NTRU+768/kem.c +110 -40
- data/vendor/NTRUplus/NTRU+768/ntt.c +50 -54
- data/vendor/NTRUplus/NTRU+768/poly.c +23 -13
- data/vendor/NTRUplus/NTRU+768/poly.h +3 -3
- data/vendor/NTRUplus/NTRU+768/randombytes.h +1 -0
- data/vendor/NTRUplus/NTRU+768/symmetric.c +3 -9
- data/vendor/NTRUplus/NTRU+768/symmetric.h +13 -3
- data/vendor/NTRUplus/NTRU+768/util.h +15 -0
- data/vendor/NTRUplus/NTRU+864/api.h +27 -8
- data/vendor/NTRUplus/NTRU+864/fips202/fips202.c +12 -269
- data/vendor/NTRUplus/NTRU+864/fips202/fips202.h +4 -113
- data/vendor/NTRUplus/NTRU+864/kem.c +110 -40
- data/vendor/NTRUplus/NTRU+864/ntt.c +24 -28
- data/vendor/NTRUplus/NTRU+864/poly.c +26 -12
- data/vendor/NTRUplus/NTRU+864/poly.h +3 -3
- data/vendor/NTRUplus/NTRU+864/randombytes.h +1 -0
- data/vendor/NTRUplus/NTRU+864/symmetric.c +3 -9
- data/vendor/NTRUplus/NTRU+864/symmetric.h +13 -3
- data/vendor/NTRUplus/NTRU+864/util.h +15 -0
- data/vendor/SMAUG-T/src/cbd.c +4 -4
- data/vendor/SMAUG-T/src/ciphertext.c +2 -2
- data/vendor/SMAUG-T/src/dg.c +2 -2
- data/vendor/SMAUG-T/src/hwt.c +4 -4
- data/vendor/SMAUG-T/src/indcpa.c +5 -5
- data/vendor/SMAUG-T/src/kem.c +9 -7
- data/vendor/SMAUG-T/src/key.c +2 -2
- data/vendor/SMAUG-T/src/pack.c +8 -8
- metadata +17 -42
- data/vendor/AIMer/aim2.c +0 -163
- data/vendor/AIMer/aim2.h +0 -36
- data/vendor/AIMer/aim2_constant.h +0 -74
- data/vendor/SOURCES.json +0 -130
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
#include "util.h"
|
|
2
2
|
#include <stddef.h>
|
|
3
3
|
#include <stdint.h>
|
|
4
4
|
#include "api.h"
|
|
@@ -8,6 +8,13 @@
|
|
|
8
8
|
#include "fips202/fips202.h"
|
|
9
9
|
#include "randombytes.h"
|
|
10
10
|
|
|
11
|
+
#ifdef NTRUPLUS_SUPERCOP
|
|
12
|
+
#include "crypto_declassify.h"
|
|
13
|
+
#define ntruplus_declassify crypto_declassify
|
|
14
|
+
#else
|
|
15
|
+
#define ntruplus_declassify(x, xlen) ((void)(x), (void)(xlen))
|
|
16
|
+
#endif
|
|
17
|
+
|
|
11
18
|
/*************************************************
|
|
12
19
|
* Name: verify
|
|
13
20
|
*
|
|
@@ -38,18 +45,19 @@ static inline int verify(const uint8_t *a, const uint8_t *b, size_t len)
|
|
|
38
45
|
* Arguments: - poly *f: output polynomial f (NTT domain)
|
|
39
46
|
* - poly *finv: output multiplicative inverse of f
|
|
40
47
|
* in the NTT domain
|
|
48
|
+
* - uint8_t *buf: workspace of NTRUPLUS_N/4 bytes
|
|
41
49
|
* - const uint8_t *coins: 32-byte deterministic seed
|
|
42
50
|
*
|
|
43
51
|
* Returns 0 on success; non-zero if f is not invertible in the NTT domain.
|
|
44
52
|
**************************************************/
|
|
45
|
-
static inline int genf_derand(poly *f, poly *finv,
|
|
53
|
+
static inline int genf_derand(poly *f, poly *finv,
|
|
54
|
+
uint8_t buf[NTRUPLUS_N / 4],
|
|
55
|
+
const uint8_t *coins)
|
|
46
56
|
{
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
shake256(buf, sizeof buf, coins, 32);
|
|
57
|
+
shake256(buf, NTRUPLUS_N / 4, coins, 32);
|
|
50
58
|
|
|
51
59
|
poly_cbd1(f, buf);
|
|
52
|
-
poly_triple(f
|
|
60
|
+
poly_triple(f);
|
|
53
61
|
f->coeffs[0] += 1;
|
|
54
62
|
|
|
55
63
|
poly_ntt(f);
|
|
@@ -66,18 +74,19 @@ static inline int genf_derand(poly *f, poly *finv, const uint8_t *coins)
|
|
|
66
74
|
* Arguments: - poly *g: output polynomial g (NTT domain)
|
|
67
75
|
* - poly *ginv: output multiplicative inverse of g
|
|
68
76
|
* in the NTT domain
|
|
77
|
+
* - uint8_t *buf: workspace of NTRUPLUS_N/4 bytes
|
|
69
78
|
* - const uint8_t *coins: 32-byte deterministic seed
|
|
70
79
|
*
|
|
71
80
|
* Returns 0 on success; non-zero if g is not invertible in the NTT domain.
|
|
72
81
|
**************************************************/
|
|
73
|
-
static inline int geng_derand(poly *g, poly *ginv,
|
|
82
|
+
static inline int geng_derand(poly *g, poly *ginv,
|
|
83
|
+
uint8_t buf[NTRUPLUS_N / 4],
|
|
84
|
+
const uint8_t *coins)
|
|
74
85
|
{
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
shake256(buf, sizeof buf, coins, 32);
|
|
86
|
+
shake256(buf, NTRUPLUS_N / 4, coins, 32);
|
|
78
87
|
|
|
79
88
|
poly_cbd1(g, buf);
|
|
80
|
-
poly_triple(g
|
|
89
|
+
poly_triple(g);
|
|
81
90
|
|
|
82
91
|
poly_ntt(g);
|
|
83
92
|
|
|
@@ -113,6 +122,9 @@ static inline void crypto_kem_keypair_derand(uint8_t *pk, uint8_t *sk,
|
|
|
113
122
|
poly_tobytes(sk, f);
|
|
114
123
|
poly_tobytes(sk + NTRUPLUS_POLYBYTES, &hinv);
|
|
115
124
|
hash_f(sk + 2 * NTRUPLUS_POLYBYTES, pk);
|
|
125
|
+
|
|
126
|
+
secure_clear(&h, sizeof h);
|
|
127
|
+
secure_clear(&hinv, sizeof hinv);
|
|
116
128
|
}
|
|
117
129
|
|
|
118
130
|
/*************************************************
|
|
@@ -130,23 +142,39 @@ static inline void crypto_kem_keypair_derand(uint8_t *pk, uint8_t *sk,
|
|
|
130
142
|
*
|
|
131
143
|
* Returns 0 on success.
|
|
132
144
|
**************************************************/
|
|
133
|
-
int crypto_kem_keypair(
|
|
145
|
+
int crypto_kem_keypair(unsigned char *pk, unsigned char *sk)
|
|
134
146
|
{
|
|
135
147
|
uint8_t coins[NTRUPLUS_SYMBYTES];
|
|
148
|
+
uint8_t buf[NTRUPLUS_N / 4];
|
|
149
|
+
int r;
|
|
150
|
+
int status = -1;
|
|
136
151
|
|
|
137
152
|
poly f, finv;
|
|
138
153
|
poly g, ginv;
|
|
139
154
|
|
|
140
155
|
do {
|
|
141
|
-
if (randombytes(coins, sizeof coins) != 0)
|
|
142
|
-
|
|
156
|
+
if (randombytes(coins, sizeof coins) != 0) goto cleanup;
|
|
157
|
+
r = genf_derand(&f, &finv, buf, coins);
|
|
158
|
+
ntruplus_declassify(&r, sizeof r);
|
|
159
|
+
} while (r);
|
|
143
160
|
|
|
144
161
|
do {
|
|
145
|
-
if (randombytes(coins, sizeof coins) != 0)
|
|
146
|
-
|
|
162
|
+
if (randombytes(coins, sizeof coins) != 0) goto cleanup;
|
|
163
|
+
r = geng_derand(&g, &ginv, buf, coins);
|
|
164
|
+
ntruplus_declassify(&r, sizeof r);
|
|
165
|
+
} while (r);
|
|
147
166
|
|
|
148
167
|
crypto_kem_keypair_derand(pk, sk, &f, &finv, &g, &ginv);
|
|
149
|
-
|
|
168
|
+
status = 0;
|
|
169
|
+
|
|
170
|
+
cleanup:
|
|
171
|
+
secure_clear(coins, sizeof coins);
|
|
172
|
+
secure_clear(buf, sizeof buf);
|
|
173
|
+
secure_clear(&f, sizeof f);
|
|
174
|
+
secure_clear(&finv, sizeof finv);
|
|
175
|
+
secure_clear(&g, sizeof g);
|
|
176
|
+
secure_clear(&ginv, sizeof ginv);
|
|
177
|
+
return status;
|
|
150
178
|
}
|
|
151
179
|
|
|
152
180
|
/*************************************************
|
|
@@ -162,17 +190,27 @@ int crypto_kem_keypair(uint8_t *pk, uint8_t *sk)
|
|
|
162
190
|
* - const uint8_t *coins: input randomness for
|
|
163
191
|
* deterministic encapsulation
|
|
164
192
|
*
|
|
165
|
-
* Returns 0 on success.
|
|
193
|
+
* Returns 0 on success. If pk contains a non-canonical coefficient, ct and ss
|
|
194
|
+
* are set to all zero bytes and 1 is returned.
|
|
166
195
|
**************************************************/
|
|
167
196
|
static inline int crypto_kem_enc_derand(uint8_t *ct, uint8_t *ss,
|
|
168
197
|
const uint8_t *pk,
|
|
169
198
|
const uint8_t *coins)
|
|
170
199
|
{
|
|
171
|
-
uint8_t msg[
|
|
172
|
-
uint8_t buf1[
|
|
173
|
-
uint8_t buf2[
|
|
200
|
+
uint8_t msg[HASH_H_INBYTES];
|
|
201
|
+
uint8_t buf1[HASH_H_OUTBYTES];
|
|
202
|
+
uint8_t buf2[HASH_G_INBYTES];
|
|
174
203
|
|
|
175
204
|
poly c, h, r, m;
|
|
205
|
+
|
|
206
|
+
if(poly_frombytes(&h, pk))
|
|
207
|
+
{
|
|
208
|
+
for (size_t i = 0; i < NTRUPLUS_CIPHERTEXTBYTES; i++)
|
|
209
|
+
ct[i] = 0;
|
|
210
|
+
secure_clear(ss, NTRUPLUS_SSBYTES);
|
|
211
|
+
|
|
212
|
+
return 1;
|
|
213
|
+
}
|
|
176
214
|
|
|
177
215
|
for (size_t i = 0; i < NTRUPLUS_N / 8; i++)
|
|
178
216
|
msg[i] = coins[i];
|
|
@@ -188,12 +226,17 @@ static inline int crypto_kem_enc_derand(uint8_t *ct, uint8_t *ss,
|
|
|
188
226
|
poly_sotp_encode(&m, msg, buf2);
|
|
189
227
|
poly_ntt(&m);
|
|
190
228
|
|
|
191
|
-
poly_frombytes(&h, pk);
|
|
192
229
|
poly_basemul_add(&c, &h, &r, &m);
|
|
193
230
|
poly_tobytes(ct, &c);
|
|
194
231
|
|
|
195
232
|
for (size_t i = 0; i < NTRUPLUS_SSBYTES; i++)
|
|
196
233
|
ss[i] = buf1[i];
|
|
234
|
+
|
|
235
|
+
secure_clear(msg, sizeof msg);
|
|
236
|
+
secure_clear(buf1, sizeof buf1);
|
|
237
|
+
secure_clear(buf2, sizeof buf2);
|
|
238
|
+
secure_clear(&r, sizeof r);
|
|
239
|
+
secure_clear(&m, sizeof m);
|
|
197
240
|
|
|
198
241
|
return 0;
|
|
199
242
|
}
|
|
@@ -212,14 +255,22 @@ static inline int crypto_kem_enc_derand(uint8_t *ct, uint8_t *ss,
|
|
|
212
255
|
* - const uint8_t *pk: input public key
|
|
213
256
|
* (array of CRYPTO_PUBLICKEYBYTES bytes)
|
|
214
257
|
*
|
|
215
|
-
* Returns 0 on success.
|
|
258
|
+
* Returns 0 on success. If pk contains a non-canonical coefficient, ct and ss
|
|
259
|
+
* are set to all zero bytes and 1 is returned.
|
|
216
260
|
**************************************************/
|
|
217
|
-
int crypto_kem_enc(
|
|
261
|
+
int crypto_kem_enc(unsigned char *ct, unsigned char *ss,
|
|
262
|
+
const unsigned char *pk)
|
|
218
263
|
{
|
|
219
264
|
uint8_t coins[NTRUPLUS_N / 8];
|
|
265
|
+
int ret;
|
|
220
266
|
|
|
221
|
-
if (randombytes(coins, sizeof coins) != 0)
|
|
222
|
-
|
|
267
|
+
if (randombytes(coins, sizeof coins) != 0) {
|
|
268
|
+
secure_clear(coins, sizeof coins);
|
|
269
|
+
return -1;
|
|
270
|
+
}
|
|
271
|
+
ret = crypto_kem_enc_derand(ct, ss, pk, coins);
|
|
272
|
+
secure_clear(coins, sizeof coins);
|
|
273
|
+
return ret;
|
|
223
274
|
}
|
|
224
275
|
|
|
225
276
|
/*************************************************
|
|
@@ -238,26 +289,32 @@ int crypto_kem_enc(uint8_t *ct, uint8_t *ss, const uint8_t *pk)
|
|
|
238
289
|
*
|
|
239
290
|
* Returns 0 on success, 1 on failure.
|
|
240
291
|
**************************************************/
|
|
241
|
-
int crypto_kem_dec(
|
|
292
|
+
int crypto_kem_dec(unsigned char *ss, const unsigned char *ct,
|
|
293
|
+
const unsigned char *sk)
|
|
242
294
|
{
|
|
243
|
-
uint8_t msg[
|
|
244
|
-
uint8_t buf1[
|
|
245
|
-
uint8_t buf2[
|
|
246
|
-
uint8_t buf3[
|
|
247
|
-
|
|
248
|
-
int8_t fail;
|
|
295
|
+
uint8_t msg[HASH_H_INBYTES];
|
|
296
|
+
uint8_t buf1[HASH_G_INBYTES];
|
|
297
|
+
uint8_t buf2[HASH_G_INBYTES];
|
|
298
|
+
uint8_t buf3[HASH_H_OUTBYTES];
|
|
299
|
+
|
|
300
|
+
int8_t fail = 1;
|
|
249
301
|
|
|
250
302
|
poly c, f, hinv;
|
|
251
303
|
poly r1, r2;
|
|
252
304
|
poly m1, m2;
|
|
253
|
-
|
|
254
|
-
poly_frombytes(&c, ct)
|
|
255
|
-
|
|
256
|
-
|
|
305
|
+
|
|
306
|
+
if(poly_frombytes(&c, ct) ||
|
|
307
|
+
poly_frombytes(&f, sk) ||
|
|
308
|
+
poly_frombytes(&hinv, sk + NTRUPLUS_POLYBYTES))
|
|
309
|
+
{
|
|
310
|
+
secure_clear(ss, NTRUPLUS_SSBYTES);
|
|
311
|
+
|
|
312
|
+
goto cleanup;
|
|
313
|
+
}
|
|
257
314
|
|
|
258
315
|
poly_basemul(&m1, &c, &f);
|
|
259
316
|
poly_invntt(&m1);
|
|
260
|
-
poly_crepmod3(&m1
|
|
317
|
+
poly_crepmod3(&m1);
|
|
261
318
|
|
|
262
319
|
m2 = m1;
|
|
263
320
|
poly_ntt(&m2);
|
|
@@ -268,7 +325,7 @@ int crypto_kem_dec(uint8_t *ss, const uint8_t *ct, const uint8_t *sk)
|
|
|
268
325
|
hash_g(buf2, buf1);
|
|
269
326
|
fail = poly_sotp_decode(msg, &m1, buf2);
|
|
270
327
|
|
|
271
|
-
for (size_t i = 0; i <
|
|
328
|
+
for (size_t i = 0; i < HASH_F_OUTBYTES; i++)
|
|
272
329
|
msg[i + NTRUPLUS_N / 8] = sk[i + 2 * NTRUPLUS_POLYBYTES];
|
|
273
330
|
|
|
274
331
|
hash_h(buf3, msg);
|
|
@@ -281,6 +338,19 @@ int crypto_kem_dec(uint8_t *ss, const uint8_t *ct, const uint8_t *sk)
|
|
|
281
338
|
|
|
282
339
|
for (size_t i = 0; i < NTRUPLUS_SSBYTES; i++)
|
|
283
340
|
ss[i] = buf3[i] & ~(-fail);
|
|
284
|
-
|
|
341
|
+
|
|
342
|
+
cleanup:
|
|
343
|
+
secure_clear(msg, sizeof msg);
|
|
344
|
+
secure_clear(buf1, sizeof buf1);
|
|
345
|
+
secure_clear(buf2, sizeof buf2);
|
|
346
|
+
secure_clear(buf3, sizeof buf3);
|
|
347
|
+
secure_clear(&c, sizeof c);
|
|
348
|
+
secure_clear(&f, sizeof f);
|
|
349
|
+
secure_clear(&hinv, sizeof hinv);
|
|
350
|
+
secure_clear(&r1, sizeof r1);
|
|
351
|
+
secure_clear(&r2, sizeof r2);
|
|
352
|
+
secure_clear(&m1, sizeof m1);
|
|
353
|
+
secure_clear(&m2, sizeof m2);
|
|
354
|
+
|
|
285
355
|
return fail;
|
|
286
356
|
}
|
|
@@ -115,8 +115,9 @@ static inline int16_t fqmul(int16_t a, int16_t b)
|
|
|
115
115
|
/*************************************************
|
|
116
116
|
* Name: fqinv
|
|
117
117
|
*
|
|
118
|
-
* Description: Computes the multiplicative inverse
|
|
119
|
-
*
|
|
118
|
+
* Description: Computes the multiplicative inverse in Z_q using Fermat's
|
|
119
|
+
* little theorem. The exponent q-2 = 3455 is evaluated using
|
|
120
|
+
* a shortest addition chain of length 15 (OEIS A003313).
|
|
120
121
|
*
|
|
121
122
|
* Arguments: - int16_t a: input value a mod q
|
|
122
123
|
*
|
|
@@ -124,32 +125,27 @@ static inline int16_t fqmul(int16_t a, int16_t b)
|
|
|
124
125
|
**************************************************/
|
|
125
126
|
static inline int16_t fqinv(int16_t a)
|
|
126
127
|
{
|
|
127
|
-
int16_t
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
t2 = fqmul(t2, t1); // 110101111111
|
|
149
|
-
|
|
150
|
-
t2 = fqmul(NTRUPLUS_RINV, t2);
|
|
151
|
-
|
|
152
|
-
return t2;
|
|
128
|
+
int16_t t0, t1;
|
|
129
|
+
|
|
130
|
+
t0 = fqmul(a, a); // 10
|
|
131
|
+
t0 = fqmul(t0, t0); // 100
|
|
132
|
+
t0 = fqmul(t0, t0); // 1000
|
|
133
|
+
t0 = fqmul(t0, t0); // 10000
|
|
134
|
+
t1 = fqmul(t0, a); // 10001
|
|
135
|
+
|
|
136
|
+
t0 = fqmul(t0, t0); // 100000
|
|
137
|
+
t0 = fqmul(t0, t0); // 1000000
|
|
138
|
+
t0 = fqmul(t0, t0); // 10000000
|
|
139
|
+
t1 = fqmul(t0, t1); // 10010001
|
|
140
|
+
|
|
141
|
+
t0 = fqmul(t1, t0); // 100010001
|
|
142
|
+
t1 = fqmul(t0, t1); // 110100010
|
|
143
|
+
t1 = fqmul(t1, t0); // 1010110011
|
|
144
|
+
t0 = fqmul(t1, t1); // 10101100110
|
|
145
|
+
t0 = fqmul(t0, t0); // 101011001100
|
|
146
|
+
t0 = fqmul(t0, t1); // 110101111111
|
|
147
|
+
|
|
148
|
+
return fqmul(NTRUPLUS_RINV, t0);
|
|
153
149
|
}
|
|
154
150
|
|
|
155
151
|
/*************************************************
|
|
@@ -42,7 +42,6 @@ void poly_tobytes(uint8_t r[NTRUPLUS_POLYBYTES], const poly *a)
|
|
|
42
42
|
{
|
|
43
43
|
int16_t t[2];
|
|
44
44
|
|
|
45
|
-
#pragma GCC unroll 2
|
|
46
45
|
for(size_t i = 0; i < NTRUPLUS_N/2; i++)
|
|
47
46
|
{
|
|
48
47
|
t[0] = a->coeffs[2*i];
|
|
@@ -65,14 +64,25 @@ void poly_tobytes(uint8_t r[NTRUPLUS_POLYBYTES], const poly *a)
|
|
|
65
64
|
* Arguments: - poly *r: pointer to output polynomial
|
|
66
65
|
* - const uint8_t *a: pointer to input byte array
|
|
67
66
|
* (of NTRUPLUS_POLYBYTES bytes)
|
|
67
|
+
*
|
|
68
|
+
* Returns 0 on success, 1 if any coefficient is greater than or equal to q.
|
|
68
69
|
**************************************************/
|
|
69
|
-
|
|
70
|
+
int poly_frombytes(poly *r, const uint8_t a[NTRUPLUS_POLYBYTES])
|
|
70
71
|
{
|
|
72
|
+
uint32_t fail = 0;
|
|
73
|
+
|
|
71
74
|
for(size_t i = 0; i < NTRUPLUS_N/2; i++)
|
|
72
75
|
{
|
|
73
|
-
|
|
74
|
-
|
|
76
|
+
const uint16_t t0 = ((a[3*i+0] >> 0) | ((uint16_t)a[3*i+1] << 8)) & 0xFFF;
|
|
77
|
+
const uint16_t t1 = ((a[3*i+1] >> 4) | ((uint16_t)a[3*i+2] << 4)) & 0xFFF;
|
|
78
|
+
|
|
79
|
+
r->coeffs[2*i] = t0;
|
|
80
|
+
r->coeffs[2*i+1] = t1;
|
|
81
|
+
fail |= (uint32_t)(NTRUPLUS_Q - 1) - t0;
|
|
82
|
+
fail |= (uint32_t)(NTRUPLUS_Q - 1) - t1;
|
|
75
83
|
}
|
|
84
|
+
|
|
85
|
+
return fail >> 31;
|
|
76
86
|
}
|
|
77
87
|
|
|
78
88
|
/*************************************************
|
|
@@ -147,6 +157,7 @@ int poly_sotp_decode(uint8_t msg[NTRUPLUS_N/8], const poly *a, const uint8_t buf
|
|
|
147
157
|
uint8_t t1, t2, t3;
|
|
148
158
|
uint16_t t4;
|
|
149
159
|
uint32_t r = 0;
|
|
160
|
+
volatile uint8_t mask;
|
|
150
161
|
|
|
151
162
|
for(size_t i = 0; i < NTRUPLUS_N / 8; i++)
|
|
152
163
|
{
|
|
@@ -172,6 +183,11 @@ int poly_sotp_decode(uint8_t msg[NTRUPLUS_N/8], const poly *a, const uint8_t buf
|
|
|
172
183
|
r = r >> 1;
|
|
173
184
|
r = (-(uint32_t)r) >> 31;
|
|
174
185
|
|
|
186
|
+
mask = (uint8_t)(r - 1);
|
|
187
|
+
|
|
188
|
+
for (size_t i = 0; i < NTRUPLUS_N / 8; i++)
|
|
189
|
+
msg[i] &= mask;
|
|
190
|
+
|
|
175
191
|
return r;
|
|
176
192
|
}
|
|
177
193
|
|
|
@@ -290,13 +306,12 @@ void poly_sub(poly *r, const poly *a, const poly *b)
|
|
|
290
306
|
*
|
|
291
307
|
* Description: Multiply polynomial by 3; no modular reduction is performed
|
|
292
308
|
*
|
|
293
|
-
* Arguments: - poly *r: pointer to output polynomial
|
|
294
|
-
* - const poly *a: pointer to input polynomial
|
|
309
|
+
* Arguments: - poly *r: pointer to input/output polynomial
|
|
295
310
|
**************************************************/
|
|
296
|
-
void poly_triple(poly *r
|
|
311
|
+
void poly_triple(poly *r)
|
|
297
312
|
{
|
|
298
313
|
for(int i = 0; i < NTRUPLUS_N; ++i)
|
|
299
|
-
r->coeffs[i]
|
|
314
|
+
r->coeffs[i] *= 3;
|
|
300
315
|
}
|
|
301
316
|
|
|
302
317
|
/*************************************************
|
|
@@ -304,11 +319,10 @@ void poly_triple(poly *r, const poly *a)
|
|
|
304
319
|
*
|
|
305
320
|
* Description: Compute modulus 3 operation to polynomial
|
|
306
321
|
*
|
|
307
|
-
* Arguments: - poly *r: pointer to output polynomial
|
|
308
|
-
* - const poly *a: pointer to input polynomial
|
|
322
|
+
* Arguments: - poly *r: pointer to input/output polynomial
|
|
309
323
|
**************************************************/
|
|
310
|
-
void poly_crepmod3(poly *r
|
|
324
|
+
void poly_crepmod3(poly *r)
|
|
311
325
|
{
|
|
312
326
|
for(int i = 0; i < NTRUPLUS_N; i++)
|
|
313
|
-
r->coeffs[i] = crepmod3(
|
|
327
|
+
r->coeffs[i] = crepmod3(r->coeffs[i]);
|
|
314
328
|
}
|
|
@@ -13,7 +13,7 @@ typedef struct{
|
|
|
13
13
|
} poly;
|
|
14
14
|
|
|
15
15
|
void poly_tobytes(uint8_t r[NTRUPLUS_POLYBYTES], const poly *a);
|
|
16
|
-
|
|
16
|
+
int poly_frombytes(poly *r, const uint8_t a[NTRUPLUS_POLYBYTES]);
|
|
17
17
|
|
|
18
18
|
void poly_cbd1(poly *r, const uint8_t buf[NTRUPLUS_N/4]);
|
|
19
19
|
void poly_sotp_encode(poly *r, const uint8_t msg[NTRUPLUS_N/8], const uint8_t buf[NTRUPLUS_N/4]);
|
|
@@ -25,7 +25,7 @@ int poly_baseinv(poly *r, const poly *a);
|
|
|
25
25
|
void poly_basemul(poly *r, const poly *a, const poly *b);
|
|
26
26
|
void poly_basemul_add(poly *r, const poly *a, const poly *b, const poly *c);
|
|
27
27
|
void poly_sub(poly *r, const poly *a, const poly *b);
|
|
28
|
-
void poly_triple(poly *r
|
|
29
|
-
void poly_crepmod3(poly *r
|
|
28
|
+
void poly_triple(poly *r);
|
|
29
|
+
void poly_crepmod3(poly *r);
|
|
30
30
|
|
|
31
31
|
#endif
|
|
@@ -1,16 +1,8 @@
|
|
|
1
|
+
#include "util.h"
|
|
1
2
|
#include <string.h>
|
|
2
3
|
#include "symmetric.h"
|
|
3
4
|
#include "fips202/fips202.h"
|
|
4
5
|
|
|
5
|
-
#define HASH_F_INBYTES (NTRUPLUS_POLYBYTES)
|
|
6
|
-
#define HASH_F_OUTBYTES (32)
|
|
7
|
-
|
|
8
|
-
#define HASH_G_INBYTES (NTRUPLUS_POLYBYTES)
|
|
9
|
-
#define HASH_G_OUTBYTES (NTRUPLUS_N / 4)
|
|
10
|
-
|
|
11
|
-
#define HASH_H_INBYTES (NTRUPLUS_N / 8 + NTRUPLUS_SYMBYTES)
|
|
12
|
-
#define HASH_H_OUTBYTES (NTRUPLUS_SSBYTES + NTRUPLUS_N / 4)
|
|
13
|
-
|
|
14
6
|
void hash_f(uint8_t *buf, const uint8_t *msg)
|
|
15
7
|
{
|
|
16
8
|
uint8_t data[1 + HASH_F_INBYTES];
|
|
@@ -27,6 +19,7 @@ void hash_g(uint8_t *buf, const uint8_t *msg)
|
|
|
27
19
|
data[0] = 0x01;
|
|
28
20
|
memcpy(data + 1, msg, HASH_G_INBYTES);
|
|
29
21
|
shake256(buf, HASH_G_OUTBYTES, data, HASH_G_INBYTES + 1);
|
|
22
|
+
secure_clear(data, sizeof data);
|
|
30
23
|
}
|
|
31
24
|
|
|
32
25
|
void hash_h(uint8_t *buf, const uint8_t *msg)
|
|
@@ -36,4 +29,5 @@ void hash_h(uint8_t *buf, const uint8_t *msg)
|
|
|
36
29
|
data[0] = 0x02;
|
|
37
30
|
memcpy(data + 1, msg, HASH_H_INBYTES);
|
|
38
31
|
shake256(buf, HASH_H_OUTBYTES, data, HASH_H_INBYTES + 1);
|
|
32
|
+
secure_clear(data, sizeof data);
|
|
39
33
|
}
|
|
@@ -3,10 +3,20 @@
|
|
|
3
3
|
|
|
4
4
|
#include <stddef.h>
|
|
5
5
|
#include <stdint.h>
|
|
6
|
+
#include "api.h"
|
|
6
7
|
#include "params.h"
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
#define HASH_F_INBYTES (NTRUPLUS_POLYBYTES)
|
|
10
|
+
#define HASH_F_OUTBYTES (NTRUPLUS_SYMBYTES)
|
|
11
|
+
|
|
12
|
+
#define HASH_G_INBYTES (NTRUPLUS_POLYBYTES)
|
|
13
|
+
#define HASH_G_OUTBYTES (NTRUPLUS_N / 4)
|
|
14
|
+
|
|
15
|
+
#define HASH_H_INBYTES (NTRUPLUS_N / 8 + NTRUPLUS_SYMBYTES)
|
|
16
|
+
#define HASH_H_OUTBYTES (NTRUPLUS_SSBYTES + NTRUPLUS_N / 4)
|
|
17
|
+
|
|
18
|
+
NTRUPLUS_INTERNAL void hash_f(uint8_t *buf, const uint8_t *msg);
|
|
19
|
+
NTRUPLUS_INTERNAL void hash_g(uint8_t *buf, const uint8_t *msg);
|
|
20
|
+
NTRUPLUS_INTERNAL void hash_h(uint8_t *buf, const uint8_t *msg);
|
|
11
21
|
|
|
12
22
|
#endif /* SYMMETRIC_H */
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#ifndef NTRUPLUS_UTIL_H
|
|
2
|
+
#define NTRUPLUS_UTIL_H
|
|
3
|
+
|
|
4
|
+
#include <stddef.h>
|
|
5
|
+
#include <stdint.h>
|
|
6
|
+
|
|
7
|
+
static inline void secure_clear(void *v, size_t len)
|
|
8
|
+
{
|
|
9
|
+
volatile uint8_t *p = v;
|
|
10
|
+
|
|
11
|
+
while (len-- > 0)
|
|
12
|
+
*p++ = 0;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
#endif /* NTRUPLUS_UTIL_H */
|
data/vendor/SMAUG-T/src/cbd.c
CHANGED
|
@@ -24,7 +24,7 @@ static uint32_t load24_littleendian(const uint8_t x[3]) {
|
|
|
24
24
|
* - const uint8_t buf[SMAUGT_CBDSEED_BYTES]: pointer to input byte
|
|
25
25
|
* array
|
|
26
26
|
*
|
|
27
|
-
* Specification: Implements Algorithm 7, spCBD1
|
|
27
|
+
* Specification: Implements @[KS X 123456, Algorithm 7, spCBD1]
|
|
28
28
|
**************************************************/
|
|
29
29
|
#define sp_cbd1 SMAUGT_NAMESPACE(sp_cbd1)
|
|
30
30
|
static void sp_cbd1(poly *r, const uint8_t buf[SMAUGT_CBDSEED_BYTES]) {
|
|
@@ -81,7 +81,7 @@ static uint32_t load32_littleendian(const uint8_t x[4]) {
|
|
|
81
81
|
* - const uint8_t buf[SMAUGT_CBDSEED_BYTES]: pointer to input byte
|
|
82
82
|
* array
|
|
83
83
|
*
|
|
84
|
-
* Specification: Implements Algorithm 9, CBD
|
|
84
|
+
* Specification: Implements @[KS X 123456, Algorithm 9, CBD]
|
|
85
85
|
**************************************************/
|
|
86
86
|
#define cbd SMAUGT_NAMESPACE(cbd)
|
|
87
87
|
static void cbd(poly *r, const uint8_t buf[SMAUGT_CBDSEED_BYTES]) {
|
|
@@ -113,7 +113,7 @@ static void cbd(poly *r, const uint8_t buf[SMAUGT_CBDSEED_BYTES]) {
|
|
|
113
113
|
* - const uint8_t buf[SMAUGT_CBDSEED_BYTES]: pointer to input byte
|
|
114
114
|
* array
|
|
115
115
|
*
|
|
116
|
-
* Specification: Implements Algorithm 8, spCBD2
|
|
116
|
+
* Specification: Implements @[KS X 123456, Algorithm 8, spCBD2]
|
|
117
117
|
**************************************************/
|
|
118
118
|
#define sp_cbd2 SMAUGT_NAMESPACE(sp_cbd2)
|
|
119
119
|
static void sp_cbd2(poly *r, const uint8_t buf[SMAUGT_CBDSEED_BYTES]) {
|
|
@@ -146,7 +146,7 @@ static void sp_cbd2(poly *r, const uint8_t buf[SMAUGT_CBDSEED_BYTES]) {
|
|
|
146
146
|
* - const uint8_t buf[SMAUGT_CBDSEED_BYTES]: pointer to input byte
|
|
147
147
|
* array
|
|
148
148
|
*
|
|
149
|
-
* Specification: Implements Algorithm 6, spCBD
|
|
149
|
+
* Specification: Implements @[KS X 123456, Algorithm 6, spCBD]
|
|
150
150
|
**************************************************/
|
|
151
151
|
void sp_cbd(poly *r, const uint8_t buf[SMAUGT_CBDSEED_BYTES]) {
|
|
152
152
|
#if SMAUGT_MODE == SMAUGT_MODE1 || SMAUGT_MODE == SMAUGT_MODET
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* Arguments: - polyvec *a: pointer to inout vector a. This should be
|
|
11
11
|
* already initialized.
|
|
12
12
|
*
|
|
13
|
-
* Specification: Implements Algorithm 12, Round1
|
|
13
|
+
* Specification: Implements @[KS X 123456, Algorithm 12, Round1]
|
|
14
14
|
**************************************************/
|
|
15
15
|
#define round1 SMAUGT_NAMESPACE(round1)
|
|
16
16
|
static inline void round1(polyvec *a) {
|
|
@@ -50,7 +50,7 @@ void computeC1(polyvec *c1, const polyvec A[SMAUGT_K], const polyvec *r) {
|
|
|
50
50
|
* Arguments: - poly *a: pointer to an input/output vector a. This should be
|
|
51
51
|
* already initialized.
|
|
52
52
|
*
|
|
53
|
-
* Specification: Implements Algorithm 13, Round2
|
|
53
|
+
* Specification: Implements @[KS X 123456, Algorithm 13, Round2]
|
|
54
54
|
**************************************************/
|
|
55
55
|
#define round2 SMAUGT_NAMESPACE(round2)
|
|
56
56
|
static inline void round2(poly *a) {
|
data/vendor/SMAUG-T/src/dg.c
CHANGED
|
@@ -53,7 +53,7 @@ static void load64_littleendian(uint64_t *out, size_t outlen,
|
|
|
53
53
|
* - const uint8_t *seed: pointer to input seed (of length
|
|
54
54
|
* SMAUGT_CRYPTO_BYTES+1)
|
|
55
55
|
*
|
|
56
|
-
* Specification: Implements Algorithm 11, dGaussianPoly
|
|
56
|
+
* Specification: Implements @[KS X 123456, Algorithm 11, dGaussianPoly]
|
|
57
57
|
**************************************************/
|
|
58
58
|
int d_gaussian_poly(poly *op, const uint8_t *seed) {
|
|
59
59
|
unsigned int i = 0, j = 0, k = 0;
|
|
@@ -99,7 +99,7 @@ int d_gaussian_poly(poly *op, const uint8_t *seed) {
|
|
|
99
99
|
* - const uint8_t seed[SMAUGT_CRYPTO_BYTES]: pointer to input byte
|
|
100
100
|
* array
|
|
101
101
|
*
|
|
102
|
-
* Specification: Implements Algorithm 10, dGaussian
|
|
102
|
+
* Specification: Implements @[KS X 123456, Algorithm 10, dGaussian]
|
|
103
103
|
**************************************************/
|
|
104
104
|
void d_gaussian(polyvec *op, const uint8_t seed[SMAUGT_CRYPTO_BYTES]) {
|
|
105
105
|
unsigned int i;
|
data/vendor/SMAUG-T/src/hwt.c
CHANGED
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
#define load16_littleendian SMAUGT_NAMESPACE(load16_littleendian)
|
|
17
17
|
static void load16_littleendian(uint16_t *out, size_t outlen,
|
|
18
18
|
const uint8_t *in) {
|
|
19
|
-
|
|
20
|
-
for (
|
|
19
|
+
int pos = 0;
|
|
20
|
+
for (int i = 0; i < outlen; ++i) {
|
|
21
21
|
out[i] = ((uint16_t)(in[pos])) | ((uint16_t)(in[pos + 1]) << 8);
|
|
22
22
|
pos += 2;
|
|
23
23
|
}
|
|
@@ -39,7 +39,7 @@ static void load16_littleendian(uint16_t *out, size_t outlen,
|
|
|
39
39
|
* - const uint16_t *seed: pointer to input seed (of length
|
|
40
40
|
* SMAUGT_HWTSEEDBYTES/2)
|
|
41
41
|
*
|
|
42
|
-
* Specification: Implements Algorithm 4, RejSampleMod
|
|
42
|
+
* Specification: Implements @[KS X 123456, Algorithm 4, RejSampleMod]
|
|
43
43
|
**************************************************/
|
|
44
44
|
#define rej_sample_mod SMAUGT_NAMESPACE(rej_sample_mod)
|
|
45
45
|
static int rej_sample_mod(int16_t si[SMAUGT_N], const uint16_t *rand) {
|
|
@@ -79,7 +79,7 @@ static int rej_sample_mod(int16_t si[SMAUGT_N], const uint16_t *rand) {
|
|
|
79
79
|
* - const uint8_t *seed: pointer to input seed (of length
|
|
80
80
|
* SMAUGT_CRYPTO_BYTES + 2)
|
|
81
81
|
*
|
|
82
|
-
* Specification: Implements Algorithm 3, HWT
|
|
82
|
+
* Specification: Implements @[KS X 123456, Algorithm 3, HWT]
|
|
83
83
|
**************************************************/
|
|
84
84
|
int hwt(int16_t *res, const uint8_t *seed) {
|
|
85
85
|
unsigned int i;
|