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
|
}
|
|
@@ -104,8 +104,9 @@ static inline int16_t fqmul(int16_t a, int16_t b)
|
|
|
104
104
|
/*************************************************
|
|
105
105
|
* Name: fqinv
|
|
106
106
|
*
|
|
107
|
-
* Description: Computes the multiplicative inverse
|
|
108
|
-
*
|
|
107
|
+
* Description: Computes the multiplicative inverse in Z_q using Fermat's
|
|
108
|
+
* little theorem. The exponent q-2 = 3455 is evaluated using
|
|
109
|
+
* a shortest addition chain of length 15 (OEIS A003313).
|
|
109
110
|
*
|
|
110
111
|
* Arguments: - int16_t a: input value a mod q
|
|
111
112
|
*
|
|
@@ -113,32 +114,27 @@ static inline int16_t fqmul(int16_t a, int16_t b)
|
|
|
113
114
|
**************************************************/
|
|
114
115
|
static inline int16_t fqinv(int16_t a)
|
|
115
116
|
{
|
|
116
|
-
int16_t
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
t2 = fqmul(t2, t1); // 110101111111
|
|
138
|
-
|
|
139
|
-
t2 = fqmul(NTRUPLUS_RINV, t2);
|
|
140
|
-
|
|
141
|
-
return t2;
|
|
117
|
+
int16_t t0, t1;
|
|
118
|
+
|
|
119
|
+
t0 = fqmul(a, a); // 10
|
|
120
|
+
t0 = fqmul(t0, t0); // 100
|
|
121
|
+
t0 = fqmul(t0, t0); // 1000
|
|
122
|
+
t0 = fqmul(t0, t0); // 10000
|
|
123
|
+
t1 = fqmul(t0, a); // 10001
|
|
124
|
+
|
|
125
|
+
t0 = fqmul(t0, t0); // 100000
|
|
126
|
+
t0 = fqmul(t0, t0); // 1000000
|
|
127
|
+
t0 = fqmul(t0, t0); // 10000000
|
|
128
|
+
t1 = fqmul(t0, t1); // 10010001
|
|
129
|
+
|
|
130
|
+
t0 = fqmul(t1, t0); // 100010001
|
|
131
|
+
t1 = fqmul(t0, t1); // 110100010
|
|
132
|
+
t1 = fqmul(t1, t0); // 1010110011
|
|
133
|
+
t0 = fqmul(t1, t1); // 10101100110
|
|
134
|
+
t0 = fqmul(t0, t0); // 101011001100
|
|
135
|
+
t0 = fqmul(t0, t1); // 110101111111
|
|
136
|
+
|
|
137
|
+
return fqmul(NTRUPLUS_RINV, t0);
|
|
142
138
|
}
|
|
143
139
|
|
|
144
140
|
/*************************************************
|
|
@@ -331,19 +327,19 @@ int baseinv(int16_t r[4], const int16_t a[4], const int16_t zeta)
|
|
|
331
327
|
**************************************************/
|
|
332
328
|
void basemul(int16_t r[4], const int16_t a[4], const int16_t b[4], const int16_t zeta)
|
|
333
329
|
{
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
r[0] = montgomery_reduce(
|
|
344
|
-
r[1] = montgomery_reduce(
|
|
345
|
-
r[2] = montgomery_reduce(
|
|
346
|
-
r[3] = montgomery_reduce(
|
|
330
|
+
int16_t t0 = montgomery_reduce(a[1]*b[3]+a[2]*b[2]+a[3]*b[1]); // R^-1
|
|
331
|
+
int16_t t1 = montgomery_reduce(a[2]*b[3]+a[3]*b[2]); // R^-1
|
|
332
|
+
int16_t t2 = montgomery_reduce(a[3]*b[3]); // R^-1
|
|
333
|
+
|
|
334
|
+
int16_t c0 = montgomery_reduce(t0*zeta+a[0]*b[0]); // R^-1
|
|
335
|
+
int16_t c1 = montgomery_reduce(t1*zeta+a[0]*b[1]+a[1]*b[0]); // R^-1
|
|
336
|
+
int16_t c2 = montgomery_reduce(t2*zeta+a[0]*b[2]+a[1]*b[1]+a[2]*b[0]); // R^-1
|
|
337
|
+
int16_t c3 = montgomery_reduce(a[0]*b[3]+a[1]*b[2]+a[2]*b[1]+a[3]*b[0]); // R^-1
|
|
338
|
+
|
|
339
|
+
r[0] = montgomery_reduce(c0*NTRUPLUS_RSQ); // R^0
|
|
340
|
+
r[1] = montgomery_reduce(c1*NTRUPLUS_RSQ); // R^0
|
|
341
|
+
r[2] = montgomery_reduce(c2*NTRUPLUS_RSQ); // R^0
|
|
342
|
+
r[3] = montgomery_reduce(c3*NTRUPLUS_RSQ); // R^0
|
|
347
343
|
}
|
|
348
344
|
|
|
349
345
|
/*************************************************
|
|
@@ -363,17 +359,17 @@ void basemul(int16_t r[4], const int16_t a[4], const int16_t b[4], const int16_t
|
|
|
363
359
|
**************************************************/
|
|
364
360
|
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)
|
|
365
361
|
{
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
r[0] = montgomery_reduce(c[0]*NTRUPLUS_R +
|
|
376
|
-
r[1] = montgomery_reduce(c[1]*NTRUPLUS_R +
|
|
377
|
-
r[2] = montgomery_reduce(c[2]*NTRUPLUS_R +
|
|
378
|
-
r[3] = montgomery_reduce(c[3]*NTRUPLUS_R +
|
|
362
|
+
int16_t t0 = montgomery_reduce(a[1]*b[3]+a[2]*b[2]+a[3]*b[1]); // R^-1
|
|
363
|
+
int16_t t1 = montgomery_reduce(a[2]*b[3]+a[3]*b[2]); // R^-1
|
|
364
|
+
int16_t t2 = montgomery_reduce(a[3]*b[3]); // R^-1
|
|
365
|
+
|
|
366
|
+
int16_t c0 = montgomery_reduce(t0*zeta+a[0]*b[0]); // R^-1
|
|
367
|
+
int16_t c1 = montgomery_reduce(t1*zeta+a[0]*b[1]+a[1]*b[0]); // R^-1
|
|
368
|
+
int16_t c2 = montgomery_reduce(t2*zeta+a[0]*b[2]+a[1]*b[1]+a[2]*b[0]); // R^-1
|
|
369
|
+
int16_t c3 = montgomery_reduce(a[0]*b[3]+a[1]*b[2]+a[2]*b[1]+a[3]*b[0]); // R^-1
|
|
370
|
+
|
|
371
|
+
r[0] = montgomery_reduce(c[0]*NTRUPLUS_R + c0*NTRUPLUS_RSQ); // R^0
|
|
372
|
+
r[1] = montgomery_reduce(c[1]*NTRUPLUS_R + c1*NTRUPLUS_RSQ); // R^0
|
|
373
|
+
r[2] = montgomery_reduce(c[2]*NTRUPLUS_R + c2*NTRUPLUS_RSQ); // R^0
|
|
374
|
+
r[3] = montgomery_reduce(c[3]*NTRUPLUS_R + c3*NTRUPLUS_RSQ); // R^0
|
|
379
375
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#include "util.h"
|
|
1
2
|
#include <stdint.h>
|
|
2
3
|
#include <string.h>
|
|
3
4
|
#include "params.h"
|
|
@@ -42,7 +43,6 @@ void poly_tobytes(uint8_t r[NTRUPLUS_POLYBYTES], const poly *a)
|
|
|
42
43
|
{
|
|
43
44
|
int16_t t[2];
|
|
44
45
|
|
|
45
|
-
#pragma GCC unroll 2
|
|
46
46
|
for(size_t i = 0; i < NTRUPLUS_N/2; i++)
|
|
47
47
|
{
|
|
48
48
|
t[0] = a->coeffs[2*i];
|
|
@@ -65,14 +65,25 @@ void poly_tobytes(uint8_t r[NTRUPLUS_POLYBYTES], const poly *a)
|
|
|
65
65
|
* Arguments: - poly *r: pointer to output polynomial
|
|
66
66
|
* - const uint8_t *a: pointer to input byte array
|
|
67
67
|
* (of NTRUPLUS_POLYBYTES bytes)
|
|
68
|
+
*
|
|
69
|
+
* Returns 0 on success, 1 if any coefficient is greater than or equal to q.
|
|
68
70
|
**************************************************/
|
|
69
|
-
|
|
71
|
+
int poly_frombytes(poly *r, const uint8_t a[NTRUPLUS_POLYBYTES])
|
|
70
72
|
{
|
|
73
|
+
uint32_t fail = 0;
|
|
74
|
+
|
|
71
75
|
for(size_t i = 0; i < NTRUPLUS_N/2; i++)
|
|
72
76
|
{
|
|
73
|
-
|
|
74
|
-
|
|
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;
|
|
75
84
|
}
|
|
85
|
+
|
|
86
|
+
return fail >> 31;
|
|
76
87
|
}
|
|
77
88
|
|
|
78
89
|
/*************************************************
|
|
@@ -129,6 +140,7 @@ void poly_sotp_encode(poly *r, const uint8_t msg[NTRUPLUS_N/8], const uint8_t bu
|
|
|
129
140
|
}
|
|
130
141
|
|
|
131
142
|
poly_cbd1(r, tmp);
|
|
143
|
+
secure_clear(tmp, sizeof tmp);
|
|
132
144
|
}
|
|
133
145
|
|
|
134
146
|
/*************************************************
|
|
@@ -147,7 +159,7 @@ int poly_sotp_decode(uint8_t msg[NTRUPLUS_N/8], const poly *a, const uint8_t buf
|
|
|
147
159
|
uint8_t t1, t2, t3;
|
|
148
160
|
uint16_t t4;
|
|
149
161
|
uint32_t r = 0;
|
|
150
|
-
uint8_t mask;
|
|
162
|
+
volatile uint8_t mask;
|
|
151
163
|
|
|
152
164
|
for(size_t i = 0; i < NTRUPLUS_N / 8; i++)
|
|
153
165
|
{
|
|
@@ -296,13 +308,12 @@ void poly_sub(poly *r, const poly *a, const poly *b)
|
|
|
296
308
|
*
|
|
297
309
|
* Description: Multiply polynomial by 3; no modular reduction is performed
|
|
298
310
|
*
|
|
299
|
-
* Arguments: - poly *r: pointer to output polynomial
|
|
300
|
-
* - const poly *a: pointer to input polynomial
|
|
311
|
+
* Arguments: - poly *r: pointer to input/output polynomial
|
|
301
312
|
**************************************************/
|
|
302
|
-
void poly_triple(poly *r
|
|
313
|
+
void poly_triple(poly *r)
|
|
303
314
|
{
|
|
304
315
|
for(int i = 0; i < NTRUPLUS_N; ++i)
|
|
305
|
-
r->coeffs[i]
|
|
316
|
+
r->coeffs[i] *= 3;
|
|
306
317
|
}
|
|
307
318
|
|
|
308
319
|
/*************************************************
|
|
@@ -310,11 +321,10 @@ void poly_triple(poly *r, const poly *a)
|
|
|
310
321
|
*
|
|
311
322
|
* Description: Compute modulus 3 operation to polynomial
|
|
312
323
|
*
|
|
313
|
-
* Arguments: - poly *r: pointer to output polynomial
|
|
314
|
-
* - const poly *a: pointer to input polynomial
|
|
324
|
+
* Arguments: - poly *r: pointer to input/output polynomial
|
|
315
325
|
**************************************************/
|
|
316
|
-
void poly_crepmod3(poly *r
|
|
326
|
+
void poly_crepmod3(poly *r)
|
|
317
327
|
{
|
|
318
328
|
for(int i = 0; i < NTRUPLUS_N; i++)
|
|
319
|
-
|
|
329
|
+
r->coeffs[i] = crepmod3(r->coeffs[i]);
|
|
320
330
|
}
|
|
@@ -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
|