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
|
/*************************************************
|
|
@@ -346,19 +342,19 @@ int baseinv(int16_t r[4], const int16_t a[4], const int16_t zeta)
|
|
|
346
342
|
**************************************************/
|
|
347
343
|
void basemul(int16_t r[4], const int16_t a[4], const int16_t b[4], const int16_t zeta)
|
|
348
344
|
{
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
r[0] = montgomery_reduce(
|
|
359
|
-
r[1] = montgomery_reduce(
|
|
360
|
-
r[2] = montgomery_reduce(
|
|
361
|
-
r[3] = montgomery_reduce(
|
|
345
|
+
int16_t t0 = montgomery_reduce(a[1]*b[3]+a[2]*b[2]+a[3]*b[1]); // R^-1
|
|
346
|
+
int16_t t1 = montgomery_reduce(a[2]*b[3]+a[3]*b[2]); // R^-1
|
|
347
|
+
int16_t t2 = montgomery_reduce(a[3]*b[3]); // R^-1
|
|
348
|
+
|
|
349
|
+
int16_t c0 = montgomery_reduce(t0*zeta+a[0]*b[0]); // R^-1
|
|
350
|
+
int16_t c1 = montgomery_reduce(t1*zeta+a[0]*b[1]+a[1]*b[0]); // R^-1
|
|
351
|
+
int16_t c2 = montgomery_reduce(t2*zeta+a[0]*b[2]+a[1]*b[1]+a[2]*b[0]); // R^-1
|
|
352
|
+
int16_t c3 = montgomery_reduce(a[0]*b[3]+a[1]*b[2]+a[2]*b[1]+a[3]*b[0]); // R^-1
|
|
353
|
+
|
|
354
|
+
r[0] = montgomery_reduce(c0*NTRUPLUS_RSQ); // R^0
|
|
355
|
+
r[1] = montgomery_reduce(c1*NTRUPLUS_RSQ); // R^0
|
|
356
|
+
r[2] = montgomery_reduce(c2*NTRUPLUS_RSQ); // R^0
|
|
357
|
+
r[3] = montgomery_reduce(c3*NTRUPLUS_RSQ); // R^0
|
|
362
358
|
}
|
|
363
359
|
|
|
364
360
|
/*************************************************
|
|
@@ -378,17 +374,17 @@ void basemul(int16_t r[4], const int16_t a[4], const int16_t b[4], const int16_t
|
|
|
378
374
|
**************************************************/
|
|
379
375
|
void basemul_add(int16_t r[4], const int16_t a[4], const int16_t b[4], const int16_t c[4], const int16_t zeta)
|
|
380
376
|
{
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
r[0] = montgomery_reduce(c[0]*NTRUPLUS_R +
|
|
391
|
-
r[1] = montgomery_reduce(c[1]*NTRUPLUS_R +
|
|
392
|
-
r[2] = montgomery_reduce(c[2]*NTRUPLUS_R +
|
|
393
|
-
r[3] = montgomery_reduce(c[3]*NTRUPLUS_R +
|
|
377
|
+
int16_t t0 = montgomery_reduce(a[1]*b[3]+a[2]*b[2]+a[3]*b[1]); // R^-1
|
|
378
|
+
int16_t t1 = montgomery_reduce(a[2]*b[3]+a[3]*b[2]); // R^-1
|
|
379
|
+
int16_t t2 = montgomery_reduce(a[3]*b[3]); // R^-1
|
|
380
|
+
|
|
381
|
+
int16_t c0 = montgomery_reduce(t0*zeta+a[0]*b[0]); // R^-1
|
|
382
|
+
int16_t c1 = montgomery_reduce(t1*zeta+a[0]*b[1]+a[1]*b[0]); // R^-1
|
|
383
|
+
int16_t c2 = montgomery_reduce(t2*zeta+a[0]*b[2]+a[1]*b[1]+a[2]*b[0]); // R^-1
|
|
384
|
+
int16_t c3 = montgomery_reduce(a[0]*b[3]+a[1]*b[2]+a[2]*b[1]+a[3]*b[0]); // R^-1
|
|
385
|
+
|
|
386
|
+
r[0] = montgomery_reduce(c[0]*NTRUPLUS_R + c0*NTRUPLUS_RSQ); // R^0
|
|
387
|
+
r[1] = montgomery_reduce(c[1]*NTRUPLUS_R + c1*NTRUPLUS_RSQ); // R^0
|
|
388
|
+
r[2] = montgomery_reduce(c[2]*NTRUPLUS_R + c2*NTRUPLUS_RSQ); // R^0
|
|
389
|
+
r[3] = montgomery_reduce(c[3]*NTRUPLUS_R + c3*NTRUPLUS_RSQ); // R^0
|
|
394
390
|
}
|
|
@@ -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];
|
|
@@ -66,14 +65,25 @@ void poly_tobytes(uint8_t r[NTRUPLUS_POLYBYTES], const poly *a)
|
|
|
66
65
|
* Arguments: - poly *r: pointer to output polynomial
|
|
67
66
|
* - const uint8_t *a: pointer to input byte array
|
|
68
67
|
* (of NTRUPLUS_POLYBYTES bytes)
|
|
68
|
+
*
|
|
69
|
+
* Returns 0 on success, 1 if any coefficient is greater than or equal to q.
|
|
69
70
|
**************************************************/
|
|
70
|
-
|
|
71
|
+
int poly_frombytes(poly *r, const uint8_t a[NTRUPLUS_POLYBYTES])
|
|
71
72
|
{
|
|
73
|
+
uint32_t fail = 0;
|
|
74
|
+
|
|
72
75
|
for(size_t i = 0; i < NTRUPLUS_N/2; i++)
|
|
73
76
|
{
|
|
74
|
-
|
|
75
|
-
|
|
77
|
+
const uint16_t t0 = ((a[3*i+0] >> 0) | ((uint16_t)a[3*i+1] << 8)) & 0xFFF;
|
|
78
|
+
const uint16_t t1 = ((a[3*i+1] >> 4) | ((uint16_t)a[3*i+2] << 4)) & 0xFFF;
|
|
79
|
+
|
|
80
|
+
r->coeffs[2*i] = t0;
|
|
81
|
+
r->coeffs[2*i+1] = t1;
|
|
82
|
+
fail |= (uint32_t)(NTRUPLUS_Q - 1) - t0;
|
|
83
|
+
fail |= (uint32_t)(NTRUPLUS_Q - 1) - t1;
|
|
76
84
|
}
|
|
85
|
+
|
|
86
|
+
return fail >> 31;
|
|
77
87
|
}
|
|
78
88
|
|
|
79
89
|
/*************************************************
|
|
@@ -148,7 +158,7 @@ int poly_sotp_decode(uint8_t msg[NTRUPLUS_N/8], const poly *a, const uint8_t buf
|
|
|
148
158
|
uint8_t t1, t2, t3;
|
|
149
159
|
uint16_t t4;
|
|
150
160
|
uint32_t r = 0;
|
|
151
|
-
uint8_t mask;
|
|
161
|
+
volatile uint8_t mask;
|
|
152
162
|
|
|
153
163
|
for(size_t i = 0; i < NTRUPLUS_N / 8; i++)
|
|
154
164
|
{
|
|
@@ -294,13 +304,12 @@ void poly_sub(poly *r, const poly *a, const poly *b)
|
|
|
294
304
|
*
|
|
295
305
|
* Description: Multiply polynomial by 3; no modular reduction is performed
|
|
296
306
|
*
|
|
297
|
-
* Arguments: - poly *r: pointer to output polynomial
|
|
298
|
-
* - const poly *a: pointer to input polynomial
|
|
307
|
+
* Arguments: - poly *r: pointer to input/output polynomial
|
|
299
308
|
**************************************************/
|
|
300
|
-
void poly_triple(poly *r
|
|
309
|
+
void poly_triple(poly *r)
|
|
301
310
|
{
|
|
302
311
|
for(int i = 0; i < NTRUPLUS_N; ++i)
|
|
303
|
-
r->coeffs[i]
|
|
312
|
+
r->coeffs[i] *= 3;
|
|
304
313
|
}
|
|
305
314
|
|
|
306
315
|
/*************************************************
|
|
@@ -308,11 +317,10 @@ void poly_triple(poly *r, const poly *a)
|
|
|
308
317
|
*
|
|
309
318
|
* Description: Compute modulus 3 operation to polynomial
|
|
310
319
|
*
|
|
311
|
-
* Arguments: - poly *r: pointer to output polynomial
|
|
312
|
-
* - const poly *a: pointer to input polynomial
|
|
320
|
+
* Arguments: - poly *r: pointer to input/output polynomial
|
|
313
321
|
**************************************************/
|
|
314
|
-
void poly_crepmod3(poly *r
|
|
322
|
+
void poly_crepmod3(poly *r)
|
|
315
323
|
{
|
|
316
324
|
for(int i = 0; i < NTRUPLUS_N; i++)
|
|
317
|
-
r->coeffs[i] = crepmod3(
|
|
325
|
+
r->coeffs[i] = crepmod3(r->coeffs[i]);
|
|
318
326
|
}
|
|
@@ -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 */
|
|
@@ -3,6 +3,25 @@
|
|
|
3
3
|
|
|
4
4
|
#include "params.h"
|
|
5
5
|
|
|
6
|
+
#ifndef NTRUPLUS_ABI_H
|
|
7
|
+
#define NTRUPLUS_ABI_H
|
|
8
|
+
|
|
9
|
+
#if defined(_MSC_VER)
|
|
10
|
+
#define NTRUPLUS_INTERNAL
|
|
11
|
+
#define NTRUPLUS_EXTERNAL
|
|
12
|
+
#define NTRUPLUS_SYSV
|
|
13
|
+
#elif defined(__MINGW32__) || defined(__MINGW64__)
|
|
14
|
+
#define NTRUPLUS_INTERNAL
|
|
15
|
+
#define NTRUPLUS_EXTERNAL __declspec(dllexport)
|
|
16
|
+
#define NTRUPLUS_SYSV __attribute__((sysv_abi))
|
|
17
|
+
#else
|
|
18
|
+
#define NTRUPLUS_INTERNAL __attribute__((visibility("hidden")))
|
|
19
|
+
#define NTRUPLUS_EXTERNAL __attribute__((visibility("default")))
|
|
20
|
+
#define NTRUPLUS_SYSV
|
|
21
|
+
#endif
|
|
22
|
+
|
|
23
|
+
#endif
|
|
24
|
+
|
|
6
25
|
#define CRYPTO_SECRETKEYBYTES NTRUPLUS_SECRETKEYBYTES
|
|
7
26
|
#define CRYPTO_PUBLICKEYBYTES NTRUPLUS_PUBLICKEYBYTES
|
|
8
27
|
#define CRYPTO_CIPHERTEXTBYTES NTRUPLUS_CIPHERTEXTBYTES
|
|
@@ -10,15 +29,15 @@
|
|
|
10
29
|
|
|
11
30
|
#define CRYPTO_ALGNAME NTRUPLUS_ALGNAME
|
|
12
31
|
|
|
13
|
-
int crypto_kem_keypair(unsigned char *pk,
|
|
14
|
-
|
|
32
|
+
NTRUPLUS_EXTERNAL int crypto_kem_keypair(unsigned char *pk,
|
|
33
|
+
unsigned char *sk);
|
|
15
34
|
|
|
16
|
-
int crypto_kem_enc(unsigned char *ct,
|
|
17
|
-
|
|
18
|
-
|
|
35
|
+
NTRUPLUS_EXTERNAL int crypto_kem_enc(unsigned char *ct,
|
|
36
|
+
unsigned char *ss,
|
|
37
|
+
const unsigned char *pk);
|
|
19
38
|
|
|
20
|
-
int crypto_kem_dec(unsigned char *ss,
|
|
21
|
-
|
|
22
|
-
|
|
39
|
+
NTRUPLUS_EXTERNAL int crypto_kem_dec(unsigned char *ss,
|
|
40
|
+
const unsigned char *ct,
|
|
41
|
+
const unsigned char *sk);
|
|
23
42
|
|
|
24
43
|
#endif
|