kpqc 0.1.1 → 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.
Files changed (100) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -0
  3. data/README.md +9 -6
  4. data/THIRD_PARTY_NOTICES.md +14 -47
  5. data/ext/kpqc/extconf_helper.rb +6 -3
  6. data/ext/kpqc/secure_clear.c +8 -0
  7. data/kpqc.gemspec +4 -2
  8. data/lib/kpqc/aimer.rb +6 -6
  9. data/lib/kpqc/version.rb +1 -1
  10. data/test/kat/aimer128f.rsp +4 -4
  11. data/test/kat/aimer128s.rsp +4 -4
  12. data/test/kat/aimer192f.rsp +4 -4
  13. data/test/kat/aimer192s.rsp +4 -4
  14. data/test/kat/aimer256f.rsp +4 -4
  15. data/test/kat/aimer256s.rsp +4 -4
  16. data/test/kat/haetae2.rsp +1 -1
  17. data/test/kat/haetae3.rsp +1 -1
  18. data/test/kat/haetae5.rsp +1 -1
  19. data/vendor/AIMer/LICENSE +1 -1
  20. data/vendor/AIMer/aim3.c +227 -0
  21. data/vendor/AIMer/aim3.h +63 -0
  22. data/vendor/AIMer/field.h +12 -4
  23. data/vendor/AIMer/field128.c +24 -381
  24. data/vendor/AIMer/field192.c +24 -400
  25. data/vendor/AIMer/field256.c +28 -447
  26. data/vendor/AIMer/field_common.c +98 -0
  27. data/vendor/AIMer/field_internal.h +218 -0
  28. data/vendor/AIMer/params/params-aimer-128f.h +8 -8
  29. data/vendor/AIMer/params/params-aimer-128s.h +8 -8
  30. data/vendor/AIMer/params/params-aimer-192f.h +8 -8
  31. data/vendor/AIMer/params/params-aimer-192s.h +8 -8
  32. data/vendor/AIMer/params/params-aimer-256f.h +8 -8
  33. data/vendor/AIMer/params/params-aimer-256s.h +8 -8
  34. data/vendor/AIMer/params.h +5 -0
  35. data/vendor/AIMer/sign.c +246 -167
  36. data/vendor/AIMer/sign.h +6 -6
  37. data/vendor/AIMer/tree.c +10 -4
  38. data/vendor/AIMer/tree.h +1 -1
  39. data/vendor/HAETAE/include/fixpoint.h +14 -14
  40. data/vendor/HAETAE/include/rans_byte.h +10 -9
  41. data/vendor/HAETAE/src/decompose.c +8 -4
  42. data/vendor/HAETAE/src/encoding.c +5 -5
  43. data/vendor/HAETAE/src/fft.c +1 -1
  44. data/vendor/HAETAE/src/fips202.c +26 -14
  45. data/vendor/HAETAE/src/fixpoint.c +21 -18
  46. data/vendor/HAETAE/src/ntt.c +2 -0
  47. data/vendor/HAETAE/src/packing.c +15 -15
  48. data/vendor/HAETAE/src/poly.c +30 -3
  49. data/vendor/HAETAE/src/polyfix.c +2 -2
  50. data/vendor/HAETAE/src/polymat.c +2 -2
  51. data/vendor/HAETAE/src/polyvec.c +7 -5
  52. data/vendor/HAETAE/src/reduce.c +2 -0
  53. data/vendor/HAETAE/src/sampler.c +231 -47
  54. data/vendor/HAETAE/src/sign.c +11 -10
  55. data/vendor/NTRUplus/NTRU+1152/api.h +27 -8
  56. data/vendor/NTRUplus/NTRU+1152/fips202/fips202.c +12 -269
  57. data/vendor/NTRUplus/NTRU+1152/fips202/fips202.h +4 -113
  58. data/vendor/NTRUplus/NTRU+1152/kem.c +110 -40
  59. data/vendor/NTRUplus/NTRU+1152/ntt.c +50 -54
  60. data/vendor/NTRUplus/NTRU+1152/poly.c +21 -13
  61. data/vendor/NTRUplus/NTRU+1152/poly.h +3 -3
  62. data/vendor/NTRUplus/NTRU+1152/randombytes.h +1 -0
  63. data/vendor/NTRUplus/NTRU+1152/symmetric.c +3 -9
  64. data/vendor/NTRUplus/NTRU+1152/symmetric.h +13 -3
  65. data/vendor/NTRUplus/NTRU+1152/util.h +15 -0
  66. data/vendor/NTRUplus/NTRU+768/api.h +27 -8
  67. data/vendor/NTRUplus/NTRU+768/fips202/fips202.c +12 -269
  68. data/vendor/NTRUplus/NTRU+768/fips202/fips202.h +4 -113
  69. data/vendor/NTRUplus/NTRU+768/kem.c +110 -40
  70. data/vendor/NTRUplus/NTRU+768/ntt.c +50 -54
  71. data/vendor/NTRUplus/NTRU+768/poly.c +23 -13
  72. data/vendor/NTRUplus/NTRU+768/poly.h +3 -3
  73. data/vendor/NTRUplus/NTRU+768/randombytes.h +1 -0
  74. data/vendor/NTRUplus/NTRU+768/symmetric.c +3 -9
  75. data/vendor/NTRUplus/NTRU+768/symmetric.h +13 -3
  76. data/vendor/NTRUplus/NTRU+768/util.h +15 -0
  77. data/vendor/NTRUplus/NTRU+864/api.h +27 -8
  78. data/vendor/NTRUplus/NTRU+864/fips202/fips202.c +12 -269
  79. data/vendor/NTRUplus/NTRU+864/fips202/fips202.h +4 -113
  80. data/vendor/NTRUplus/NTRU+864/kem.c +110 -40
  81. data/vendor/NTRUplus/NTRU+864/ntt.c +24 -28
  82. data/vendor/NTRUplus/NTRU+864/poly.c +26 -12
  83. data/vendor/NTRUplus/NTRU+864/poly.h +3 -3
  84. data/vendor/NTRUplus/NTRU+864/randombytes.h +1 -0
  85. data/vendor/NTRUplus/NTRU+864/symmetric.c +3 -9
  86. data/vendor/NTRUplus/NTRU+864/symmetric.h +13 -3
  87. data/vendor/NTRUplus/NTRU+864/util.h +15 -0
  88. data/vendor/SMAUG-T/src/cbd.c +4 -4
  89. data/vendor/SMAUG-T/src/ciphertext.c +2 -2
  90. data/vendor/SMAUG-T/src/dg.c +2 -2
  91. data/vendor/SMAUG-T/src/hwt.c +4 -4
  92. data/vendor/SMAUG-T/src/indcpa.c +5 -5
  93. data/vendor/SMAUG-T/src/kem.c +9 -7
  94. data/vendor/SMAUG-T/src/key.c +2 -2
  95. data/vendor/SMAUG-T/src/pack.c +8 -8
  96. metadata +16 -13
  97. data/vendor/AIMer/aim2.c +0 -163
  98. data/vendor/AIMer/aim2.h +0 -36
  99. data/vendor/AIMer/aim2_constant.h +0 -74
  100. data/vendor/SOURCES.json +0 -130
data/vendor/AIMer/sign.c CHANGED
@@ -1,8 +1,7 @@
1
- /* kpqc-py: propagate OS entropy failures (2026-09-06). */
2
1
  // SPDX-License-Identifier: MIT
3
2
 
4
3
  #include "api.h"
5
- #include "aim2.h"
4
+ #include "aim3.h"
6
5
  #include "field.h"
7
6
  #include "hash.h"
8
7
  #include "params.h"
@@ -22,10 +21,13 @@ static void commit_and_expand_tape(tape_t *tape, uint8_t *commit,
22
21
  {
23
22
  hash_instance ctx;
24
23
 
24
+ uint8_t rep_byte = (uint8_t)rep;
25
+ uint8_t party_byte = (uint8_t)party;
26
+
25
27
  hash_init_prefix(&ctx, HASH_PREFIX_5);
26
28
  hash_update(&ctx, salt, AIMER_SALT_SIZE);
27
- hash_update(&ctx, (const uint8_t*)&rep, sizeof(uint8_t));
28
- hash_update(&ctx, (const uint8_t*)&party, sizeof(uint8_t));
29
+ hash_update(&ctx, &rep_byte, sizeof(rep_byte));
30
+ hash_update(&ctx, &party_byte, sizeof(party_byte));
29
31
  hash_update(&ctx, seed, AIMER_SEED_SIZE);
30
32
  hash_final(&ctx);
31
33
 
@@ -34,25 +36,49 @@ static void commit_and_expand_tape(tape_t *tape, uint8_t *commit,
34
36
  hash_ctx_release(&ctx);
35
37
  }
36
38
 
39
+ static inline void adjust_last_share(
40
+ proof_t *proof, tape_t *delta, tape_t *tape,
41
+ const gf pt_gf, const gf *sbox_outputs)
42
+ {
43
+ gf_add(delta->pt_share, delta->pt_share, pt_gf);
44
+ gf_to_bytes(proof->delta_pt_bytes, delta->pt_share);
45
+ gf_add(tape->pt_share, delta->pt_share, tape->pt_share);
46
+
47
+ for (size_t i = 0; i < AIMER_L; i++)
48
+ {
49
+ gf_add(delta->y_shares[i], delta->y_shares[i], sbox_outputs[i]);
50
+ gf_to_bytes(proof->delta_ys_bytes[i], delta->y_shares[i]);
51
+ gf_add(tape->y_shares[i], delta->y_shares[i], tape->y_shares[i]);
52
+ }
53
+
54
+ // c = sum a[i] * y[i] where y = sbox outs
55
+ for (size_t i = 0; i < AIMER_L + 1; i++)
56
+ {
57
+ gf_mul_add(delta->c_share, delta->a_shares[i], sbox_outputs[i]);
58
+ }
59
+ gf_to_bytes(proof->delta_c_bytes, delta->c_share);
60
+ gf_add(tape->c_share, delta->c_share, tape->c_share);
61
+ }
62
+
37
63
  // committing to the seeds and the execution views of the parties
64
+ // Returns 0 on success or -1 on allocation failure.
38
65
  static int run_phase_1(signature_t *sign,
39
66
  uint8_t commits[AIMER_T][AIMER_N][AIMER_COMMIT_SIZE],
40
67
  uint8_t nodes[AIMER_T][2 * AIMER_N - 1][AIMER_SEED_SIZE],
41
68
  mult_chk_t mult_chk[AIMER_T][AIMER_N],
42
- gf alpha_v_shares[AIMER_T][2][AIMER_N],
43
69
  const uint8_t *sk, const uint8_t *rnd,
44
70
  const uint8_t *m, size_t mlen,
45
71
  const uint8_t *pre, size_t prelen)
46
72
  {
47
73
  gf pt_gf = {0,}, ct_gf = {0,};
48
74
  gf_from_bytes(pt_gf, sk);
49
- gf_from_bytes(ct_gf, sk + AIM2_NUM_BYTES_FIELD + AIM2_IV_SIZE);
75
+ gf_from_bytes(ct_gf, sk + AIM3_NUM_BYTES_FIELD + AIM3_IV_SIZE);
50
76
 
51
77
  // message pre-hashing
52
78
  hash_instance ctx;
53
79
  hash_init_prefix(&ctx, HASH_PREFIX_0);
54
- hash_update(&ctx, sk + AIM2_NUM_BYTES_FIELD,
55
- AIM2_IV_SIZE + AIM2_NUM_BYTES_FIELD);
80
+ hash_update(&ctx, sk + AIM3_NUM_BYTES_FIELD,
81
+ AIM3_IV_SIZE + AIM3_NUM_BYTES_FIELD);
56
82
  hash_update(&ctx, pre, prelen);
57
83
  hash_update(&ctx, m, mlen);
58
84
  hash_final(&ctx);
@@ -61,22 +87,21 @@ static int run_phase_1(signature_t *sign,
61
87
  hash_squeeze(&ctx, mu, AIMER_COMMIT_SIZE);
62
88
  hash_ctx_release(&ctx);
63
89
 
64
- // compute first L sboxes' outputs
65
- gf sbox_outputs[AIMER_L];
66
- aim2_sbox_outputs(sbox_outputs, pt_gf);
67
-
68
90
  // derive the binary matrix and the vector from the initial vector
69
- gf(*matrix_A)[AIM2_NUM_BITS_FIELD] = malloc(sizeof(*matrix_A) * AIMER_L);
70
- if (matrix_A == NULL)
91
+ aim_lin_t *lin = malloc(sizeof(aim_lin_t));
92
+ if (lin == NULL)
71
93
  {
72
94
  return -2;
73
95
  }
74
- gf vector_b = {0,};
75
- aim2_generate_linear(matrix_A, vector_b, sk + AIM2_NUM_BYTES_FIELD);
96
+ aim3_generate_linear(lin, sk + AIM3_NUM_BYTES_FIELD);
97
+
98
+ // compute sboxes' outputs
99
+ gf sbox_outputs[AIMER_L + 1];
100
+ aim3_sbox_outputs(sbox_outputs, lin, pt_gf, ct_gf);
76
101
 
77
102
  // generate salt
78
103
  hash_init_prefix(&ctx, HASH_PREFIX_3);
79
- hash_update(&ctx, sk, AIM2_NUM_BYTES_FIELD);
104
+ hash_update(&ctx, sk, AIM3_NUM_BYTES_FIELD);
80
105
  hash_update(&ctx, mu, AIMER_COMMIT_SIZE);
81
106
  hash_update(&ctx, rnd, SECURITY_BYTES);
82
107
  hash_final(&ctx);
@@ -92,6 +117,9 @@ static int run_phase_1(signature_t *sign,
92
117
  hash_update(&ctx, mu, AIMER_COMMIT_SIZE);
93
118
  hash_update(&ctx, sign->salt, AIMER_SALT_SIZE);
94
119
 
120
+ // ct_gf is part of the public key, so it is public throughout the MPC
121
+ crypto_declassify(ct_gf, sizeof(ct_gf));
122
+
95
123
  for (size_t rep = 0; rep < AIMER_T; rep++)
96
124
  {
97
125
  // compute parties' seeds using binary tree
@@ -111,51 +139,29 @@ static int run_phase_1(signature_t *sign,
111
139
  gf_add(delta.pt_share, delta.pt_share, tape.pt_share);
112
140
  for (size_t i = 0; i < AIMER_L; i++)
113
141
  {
114
- gf_add(delta.t_shares[i], delta.t_shares[i], tape.t_shares[i]);
142
+ gf_add(delta.y_shares[i], delta.y_shares[i], tape.y_shares[i]);
143
+ }
144
+ for (size_t i = 0; i < AIMER_L + 1; i++)
145
+ {
146
+ gf_add(delta.a_shares[i], delta.a_shares[i], tape.a_shares[i]);
115
147
  }
116
- gf_add(delta.a_share, delta.a_share, tape.a_share);
117
148
  gf_add(delta.c_share, delta.c_share, tape.c_share);
118
- gf_set0(mult_chk[rep][party].x_shares[AIMER_L]);
119
149
 
120
150
  // adjust the last share and prepare the proof and h_1
121
151
  if (party == AIMER_N - 1)
122
152
  {
123
- gf_add(delta.pt_share, delta.pt_share, pt_gf);
124
- gf_to_bytes(sign->proofs[rep].delta_pt_bytes, delta.pt_share);
125
- gf_add(tape.pt_share, delta.pt_share, tape.pt_share);
126
-
127
- for (size_t i = 0; i < AIMER_L; i++)
128
- {
129
- gf_add(delta.t_shares[i], delta.t_shares[i], sbox_outputs[i]);
130
- gf_to_bytes(sign->proofs[rep].delta_ts_bytes[i], delta.t_shares[i]);
131
- gf_add(tape.t_shares[i], delta.t_shares[i], tape.t_shares[i]);
132
- }
133
-
134
- gf_mul_add(delta.c_share, pt_gf, delta.a_share);
135
- gf_to_bytes(sign->proofs[rep].delta_c_bytes, delta.c_share);
136
- gf_add(tape.c_share, delta.c_share, tape.c_share);
137
-
138
- gf_copy(mult_chk[rep][party].x_shares[AIMER_L], vector_b);
153
+ adjust_last_share(&sign->proofs[rep], &delta, &tape, pt_gf,
154
+ sbox_outputs);
139
155
  }
140
156
 
141
157
  // run the MPC simulation and prepare the mult check inputs
142
- gf_copy(mult_chk[rep][party].pt_share, tape.pt_share);
143
- for (size_t i = 0; i < AIMER_L; i++)
144
- {
145
- gf_copy(mult_chk[rep][party].x_shares[i], tape.t_shares[i]);
146
- }
147
- gf_copy(alpha_v_shares[rep][0][party], tape.a_share);
148
- gf_copy(alpha_v_shares[rep][1][party], tape.c_share);
149
-
150
- crypto_declassify(ct_gf, sizeof(ct_gf));
151
- aim2_mpc(&mult_chk[rep][party],
152
- (const gf(*)[AIM2_NUM_BITS_FIELD])matrix_A, ct_gf);
158
+ aim3_mpc(&mult_chk[rep][party], lin, &tape, ct_gf, party);
153
159
  }
154
160
  hash_update(&ctx, (const uint8_t*)commits[rep], AIMER_COMMIT_SIZE * AIMER_N);
155
161
 
156
162
  // NOTE: depend on the order of values in proof_t
157
163
  hash_update(&ctx, sign->proofs[rep].delta_pt_bytes,
158
- AIM2_NUM_BYTES_FIELD * (AIMER_L + 2));
164
+ AIM3_NUM_BYTES_FIELD * (AIMER_L + 2));
159
165
  }
160
166
 
161
167
  // commit to salt, (all commitments of parties' seeds,
@@ -164,15 +170,17 @@ static int run_phase_1(signature_t *sign,
164
170
  hash_squeeze(&ctx, sign->h_1, AIMER_COMMIT_SIZE);
165
171
  hash_ctx_release(&ctx);
166
172
 
167
- free(matrix_A);
173
+ free(lin);
168
174
  return 0;
169
175
  }
170
176
 
171
177
  static void run_phase_2_and_3(signature_t *sign,
172
- gf alpha_v_shares[AIMER_T][2][AIMER_N],
178
+ gf alpha_shares[AIMER_T][AIMER_N][AIMER_L + 1],
179
+ gf v_share[AIMER_T][AIMER_N],
173
180
  const mult_chk_t mult_chk[AIMER_T][AIMER_N])
174
181
  {
175
182
  gf epsilons[AIMER_L + 1];
183
+ gf alpha[AIMER_L + 1];
176
184
 
177
185
  hash_instance ctx_e;
178
186
  hash_init(&ctx_e);
@@ -184,36 +192,50 @@ static void run_phase_2_and_3(signature_t *sign,
184
192
  hash_update(&ctx, sign->h_1, AIMER_COMMIT_SIZE);
185
193
  hash_update(&ctx, sign->salt, AIMER_SALT_SIZE);
186
194
 
187
- gf alpha = {0,};
188
195
  for (size_t rep = 0; rep < AIMER_T; rep++)
189
196
  {
190
- gf_set0(alpha);
191
197
  hash_squeeze(&ctx_e, (uint8_t *)epsilons, sizeof(epsilons));
192
198
 
193
199
  crypto_declassify(epsilons, sizeof(epsilons));
200
+
201
+ for (size_t ell = 0; ell < AIMER_L + 1; ell++)
202
+ {
203
+ gf_set0(alpha[ell]);
204
+ }
205
+
194
206
  for (size_t party = 0; party < AIMER_N; party++)
195
207
  {
196
- // alpha_share = a_share + sum x_share[i] * eps[i]
197
- // v_share = c_share - pt_share * alpha + sum z_share[i] * eps[i]
208
+ // alpha_share[ell] = a_share[ell] + x_share[ell] * eps[ell]
209
+ // v_share = c_share - sum alpha[ell] * b_share[ell] + sum z_share[ell] * eps[ell]
210
+ gf_copy(v_share[rep][party], mult_chk[rep][party].c_share);
198
211
  for (size_t ell = 0; ell < AIMER_L + 1; ell++)
199
212
  {
200
- gf_mul_add(alpha_v_shares[rep][0][party],
213
+ gf_copy(alpha_shares[rep][party][ell],
214
+ mult_chk[rep][party].a_shares[ell]);
215
+ gf_mul_add(alpha_shares[rep][party][ell],
201
216
  mult_chk[rep][party].x_shares[ell], epsilons[ell]);
202
- gf_mul_add(alpha_v_shares[rep][1][party],
217
+
218
+ gf_add(alpha[ell], alpha[ell], alpha_shares[rep][party][ell]);
219
+
220
+ gf_mul_add(v_share[rep][party],
203
221
  mult_chk[rep][party].z_shares[ell], epsilons[ell]);
204
222
  }
205
- gf_add(alpha, alpha, alpha_v_shares[rep][0][party]);
206
223
  }
207
224
 
208
225
  // alpha is opened, so we can finish calculating v_share
209
226
  crypto_declassify(alpha, sizeof(alpha));
210
227
  for (size_t party = 0; party < AIMER_N; party++)
211
228
  {
212
- gf_mul_add(alpha_v_shares[rep][1][party],
213
- mult_chk[rep][party].pt_share, alpha);
229
+ for (size_t ell = 0; ell < AIMER_L + 1; ell++)
230
+ {
231
+ gf_mul_add(v_share[rep][party],
232
+ mult_chk[rep][party].b_shares[ell], alpha[ell]);
233
+ }
214
234
  }
215
- hash_update(&ctx, (const uint8_t *)alpha_v_shares[rep],
216
- AIM2_NUM_BYTES_FIELD * 2 * AIMER_N);
235
+ hash_update(&ctx, (const uint8_t *)alpha_shares[rep],
236
+ AIM3_NUM_BYTES_FIELD * AIMER_N * (AIMER_L + 1));
237
+ hash_update(&ctx, (const uint8_t *)v_share[rep],
238
+ AIM3_NUM_BYTES_FIELD * AIMER_N);
217
239
  }
218
240
  hash_final(&ctx);
219
241
  hash_squeeze(&ctx, sign->h_2, AIMER_COMMIT_SIZE);
@@ -222,14 +244,12 @@ static void run_phase_2_and_3(signature_t *sign,
222
244
  }
223
245
 
224
246
  ////////////////////////////////////////////////////////////////////////////////
225
- void crypto_sign_keypair_internal(uint8_t *pk, uint8_t *sk,
226
- const uint8_t *pt, const uint8_t *iv)
247
+ // Returns 0 on success, -1 when a zero S-box input requires a retry with fresh
248
+ // randomness, and a value < -1 for a fatal error such as an allocation failure.
249
+ static int crypto_sign_keypair_internal(uint8_t *ct,
250
+ const uint8_t *pt, const uint8_t *iv)
227
251
  {
228
- aim2(pk + AIM2_IV_SIZE, pt, iv);
229
-
230
- memcpy(pk, iv, AIM2_IV_SIZE);
231
- memcpy(sk, pt, AIM2_NUM_BYTES_FIELD);
232
- memcpy(sk + AIM2_NUM_BYTES_FIELD, pk, AIM2_IV_SIZE + AIM2_NUM_BYTES_FIELD);
252
+ return aim3_nozeroinpsb(ct, pt, iv);
233
253
  }
234
254
 
235
255
  int crypto_sign_keypair(uint8_t *pk, uint8_t *sk)
@@ -239,20 +259,41 @@ int crypto_sign_keypair(uint8_t *pk, uint8_t *sk)
239
259
  return -1;
240
260
  }
241
261
 
242
- uint8_t pt[AIM2_NUM_BYTES_FIELD];
243
- uint8_t iv[AIM2_IV_SIZE];
262
+ uint8_t pt[AIM3_NUM_BYTES_FIELD];
263
+ uint8_t iv[AIM3_IV_SIZE];
264
+ uint8_t ct[AIM3_NUM_BYTES_FIELD];
265
+
266
+ while (true)
267
+ {
268
+ if (randombytes(pt, AIM3_NUM_BYTES_FIELD) != 0 ||
269
+ randombytes(iv, AIM3_IV_SIZE) != 0)
270
+ {
271
+ return -1;
272
+ }
273
+ int ret = crypto_sign_keypair_internal(ct, pt, iv);
274
+ if (ret == 0)
275
+ {
276
+ break;
277
+ }
278
+ if (ret != -1)
279
+ {
280
+ // allocation failure: do not retry
281
+ return ret;
282
+ }
283
+ }
244
284
 
245
- if (randombytes(pt, AIM2_NUM_BYTES_FIELD) != 0) return -1;
246
- if (randombytes(iv, AIM2_IV_SIZE) != 0) return -1;
247
- crypto_sign_keypair_internal(pk, sk, pt, iv);
285
+ memcpy(pk, iv, AIM3_IV_SIZE);
286
+ memcpy(pk + AIM3_IV_SIZE, ct, AIM3_NUM_BYTES_FIELD);
287
+ memcpy(sk, pt, AIM3_NUM_BYTES_FIELD);
288
+ memcpy(sk + AIM3_NUM_BYTES_FIELD, pk, AIM3_IV_SIZE + AIM3_NUM_BYTES_FIELD);
248
289
 
249
290
  return 0;
250
291
  }
251
292
 
252
- int crypto_sign_signature_internal(uint8_t *sig, size_t *siglen,
253
- const uint8_t *m, size_t mlen,
254
- const uint8_t *pre, size_t prelen,
255
- const uint8_t *rnd, const uint8_t *sk)
293
+ static int crypto_sign_signature_internal(uint8_t *sig, size_t *siglen,
294
+ const uint8_t *m, size_t mlen,
295
+ const uint8_t *pre, size_t prelen,
296
+ const uint8_t *rnd, const uint8_t *sk)
256
297
  {
257
298
  signature_t *sign = (signature_t *)sig;
258
299
 
@@ -269,30 +310,38 @@ int crypto_sign_signature_internal(uint8_t *sig, size_t *siglen,
269
310
  malloc(sizeof(*commits) * AIMER_T);
270
311
 
271
312
  // multiplication check inputs
272
- mult_chk_t (*mult_chk)[AIMER_N] = calloc(AIMER_T, sizeof(*mult_chk));
313
+ mult_chk_t (*mult_chk)[AIMER_N] = malloc(sizeof(*mult_chk) * AIMER_T);
273
314
 
274
315
  // multiplication check outputs
275
- gf(*alpha_v_shares)[2][AIMER_N] = calloc(AIMER_T, sizeof(*alpha_v_shares));
316
+ gf (*alpha_shares)[AIMER_N][AIMER_L + 1] =
317
+ malloc(sizeof(*alpha_shares) * AIMER_T);
318
+ gf (*v_share)[AIMER_N] = malloc(sizeof(*v_share) * AIMER_T);
276
319
 
277
- if (nodes == NULL || commits == NULL || mult_chk == NULL ||
278
- alpha_v_shares == NULL)
320
+ if (!nodes || !commits || !mult_chk || !alpha_shares || !v_share)
279
321
  {
280
322
  free(nodes);
281
323
  free(commits);
282
324
  free(mult_chk);
283
- free(alpha_v_shares);
325
+ free(alpha_shares);
326
+ free(v_share);
284
327
  return -2;
285
328
  }
286
329
 
330
+ memset(mult_chk, 0, AIMER_T * sizeof(*mult_chk));
331
+ memset(alpha_shares, 0, AIMER_T * sizeof(*alpha_shares));
332
+ memset(v_share, 0, AIMER_T * sizeof(*v_share));
333
+
287
334
  // commitments for phase 1
288
- if (run_phase_1(sign, commits, nodes, mult_chk, alpha_v_shares, sk, rnd,
289
- m, mlen, pre, prelen) != 0)
335
+ int status = run_phase_1(sign, commits, nodes, mult_chk, sk, rnd, m, mlen,
336
+ pre, prelen);
337
+ if (status != 0)
290
338
  {
291
339
  free(nodes);
292
340
  free(commits);
293
341
  free(mult_chk);
294
- free(alpha_v_shares);
295
- return -2;
342
+ free(alpha_shares);
343
+ free(v_share);
344
+ return status;
296
345
  }
297
346
 
298
347
  /////////////////////////////////////////////////////////////////
@@ -301,7 +350,7 @@ int crypto_sign_signature_internal(uint8_t *sig, size_t *siglen,
301
350
  /////////////////////////////////////////////////////////////////
302
351
 
303
352
  // compute the commitment of phase 3
304
- run_phase_2_and_3(sign, alpha_v_shares,
353
+ run_phase_2_and_3(sign, alpha_shares, v_share,
305
354
  (const mult_chk_t (*)[AIMER_N])mult_chk);
306
355
 
307
356
  //////////////////////////////////////////////////////
@@ -333,15 +382,19 @@ int crypto_sign_signature_internal(uint8_t *sig, size_t *siglen,
333
382
  (const uint8_t (*)[AIMER_SEED_SIZE])nodes[rep], i_bar);
334
383
  memcpy(sign->proofs[rep].missing_commitment, commits[rep][i_bar],
335
384
  AIMER_COMMIT_SIZE);
336
- gf_to_bytes(sign->proofs[rep].missing_alpha_share_bytes,
337
- alpha_v_shares[rep][0][i_bar]);
385
+ for (size_t ell = 0; ell < AIMER_L + 1; ell++)
386
+ {
387
+ gf_to_bytes(sign->proofs[rep].missing_alpha_share_bytes[ell],
388
+ alpha_shares[rep][i_bar][ell]);
389
+ }
338
390
  }
339
391
  *siglen = CRYPTO_BYTES;
340
392
 
341
393
  free(nodes);
342
394
  free(commits);
343
395
  free(mult_chk);
344
- free(alpha_v_shares);
396
+ free(alpha_shares);
397
+ free(v_share);
345
398
  return 0;
346
399
  }
347
400
 
@@ -364,7 +417,10 @@ int crypto_sign_signature(uint8_t *sig, size_t *siglen,
364
417
  }
365
418
 
366
419
  #ifdef RANDOMIZED_SIGNING
367
- if (randombytes(randomness, SECURITY_BYTES) != 0) return -1;
420
+ if (randombytes(randomness, SECURITY_BYTES) != 0)
421
+ {
422
+ return -1;
423
+ }
368
424
  #else
369
425
  for (size_t i = 0; i < SECURITY_BYTES; i++)
370
426
  {
@@ -379,25 +435,69 @@ int crypto_sign_signature(uint8_t *sig, size_t *siglen,
379
435
  int crypto_sign(uint8_t *sm, size_t *smlen, const uint8_t *m, size_t mlen,
380
436
  const uint8_t *ctx, size_t ctxlen, const uint8_t *sk)
381
437
  {
382
- int ret;
383
- ret = crypto_sign_signature(sm + mlen, smlen, m, mlen, ctx, ctxlen, sk);
384
-
438
+ int ret = crypto_sign_signature(sm + mlen, smlen, m, mlen, ctx, ctxlen, sk);
385
439
  if (ret != 0)
386
440
  {
387
- *smlen = 0;
388
441
  return ret;
389
442
  }
390
443
 
391
444
  memcpy(sm, m, mlen);
392
445
  *smlen += mlen;
393
446
 
394
- return ret;
447
+ return 0;
448
+ }
449
+
450
+ static inline void recompute_last_share(const proof_t *proof, tape_t *tape)
451
+ {
452
+ gf temp = {0,};
453
+
454
+ gf_from_bytes(temp, proof->delta_pt_bytes);
455
+ gf_add(tape->pt_share, tape->pt_share, temp);
456
+
457
+ for (size_t ell = 0; ell < AIMER_L; ell++)
458
+ {
459
+ gf_from_bytes(temp, proof->delta_ys_bytes[ell]);
460
+ gf_add(tape->y_shares[ell], tape->y_shares[ell], temp);
461
+ }
462
+
463
+ gf_from_bytes(temp, proof->delta_c_bytes);
464
+ gf_add(tape->c_share, tape->c_share, temp);
465
+ }
466
+
467
+ static inline void recompute_missing_alpha(const proof_t *proof,
468
+ gf *alpha_shares, gf *alpha)
469
+ {
470
+ for (size_t ell = 0; ell < AIMER_L + 1; ell++)
471
+ {
472
+ gf_from_bytes(alpha_shares[ell],
473
+ proof->missing_alpha_share_bytes[ell]);
474
+ gf_add(alpha[ell], alpha[ell], alpha_shares[ell]);
475
+ }
476
+ }
477
+
478
+ static inline void recompute_v_shares(gf *v_shares,
479
+ gf (*b_shares)[AIMER_L + 1],
480
+ gf *alpha, size_t i_bar)
481
+ {
482
+ gf_set0(v_shares[i_bar]);
483
+ for (size_t party = 0; party < AIMER_N; party++)
484
+ {
485
+ if (party == i_bar)
486
+ {
487
+ continue;
488
+ }
489
+ for (size_t ell = 0; ell < AIMER_L + 1; ell++)
490
+ {
491
+ gf_mul_add(v_shares[party], b_shares[party][ell], alpha[ell]);
492
+ }
493
+ gf_add(v_shares[i_bar], v_shares[i_bar], v_shares[party]);
494
+ }
395
495
  }
396
496
 
397
- int crypto_sign_verify_internal(const uint8_t *sig, size_t siglen,
398
- const uint8_t *m, size_t mlen,
399
- const uint8_t *pre, size_t prelen,
400
- const uint8_t *pk)
497
+ static int crypto_sign_verify_internal(const uint8_t *sig, size_t siglen,
498
+ const uint8_t *m, size_t mlen,
499
+ const uint8_t *pre, size_t prelen,
500
+ const uint8_t *pk)
401
501
  {
402
502
  if (siglen != CRYPTO_BYTES)
403
503
  {
@@ -407,27 +507,15 @@ int crypto_sign_verify_internal(const uint8_t *sig, size_t siglen,
407
507
  const signature_t *sign = (const signature_t *)sig;
408
508
 
409
509
  gf ct_gf = {0,};
410
- gf_from_bytes(ct_gf, pk + AIM2_IV_SIZE);
510
+ gf_from_bytes(ct_gf, pk + AIM3_IV_SIZE);
411
511
 
412
512
  // derive the binary matrix and the vector from the initial vector
413
- gf(*matrix_A)[AIM2_NUM_BITS_FIELD] = malloc(sizeof(*matrix_A) * AIMER_L);
414
- uint8_t (*nodes)[AIMER_SEED_SIZE] =
415
- malloc(sizeof(*nodes) * (2 * AIMER_N - 2));
416
- gf *pt_shares = malloc(AIMER_N * sizeof(gf));
417
- gf *alpha_shares = malloc(AIMER_N * sizeof(gf));
418
- gf *v_shares = malloc(AIMER_N * sizeof(gf));
419
- if (matrix_A == NULL || nodes == NULL || pt_shares == NULL ||
420
- alpha_shares == NULL || v_shares == NULL)
513
+ aim_lin_t *lin = malloc(sizeof(aim_lin_t));
514
+ if (lin == NULL)
421
515
  {
422
- free(matrix_A);
423
- free(nodes);
424
- free(pt_shares);
425
- free(alpha_shares);
426
- free(v_shares);
427
516
  return -2;
428
517
  }
429
- gf vector_b = {0,};
430
- aim2_generate_linear(matrix_A, vector_b, pk);
518
+ aim3_generate_linear(lin, pk);
431
519
 
432
520
  hash_instance ctx_e, ctx_h1, ctx_h2;
433
521
 
@@ -452,7 +540,7 @@ int crypto_sign_verify_internal(const uint8_t *sig, size_t siglen,
452
540
  // message pre-hashing
453
541
  uint8_t mu[AIMER_COMMIT_SIZE];
454
542
  hash_init_prefix(&ctx_h1, HASH_PREFIX_0);
455
- hash_update(&ctx_h1, pk, AIM2_IV_SIZE + AIM2_NUM_BYTES_FIELD);
543
+ hash_update(&ctx_h1, pk, AIM3_IV_SIZE + AIM3_NUM_BYTES_FIELD);
456
544
  hash_update(&ctx_h1, pre, prelen);
457
545
  hash_update(&ctx_h1, m, mlen);
458
546
  hash_final(&ctx_h1);
@@ -468,6 +556,23 @@ int crypto_sign_verify_internal(const uint8_t *sig, size_t siglen,
468
556
  hash_update(&ctx_h2, sign->h_1, AIMER_COMMIT_SIZE);
469
557
  hash_update(&ctx_h2, sign->salt, AIMER_SALT_SIZE);
470
558
 
559
+ uint8_t (*nodes)[AIMER_SEED_SIZE] =
560
+ malloc(sizeof(*nodes) * (2 * AIMER_N - 2));
561
+
562
+ gf (*b_shares)[AIMER_L + 1] = malloc(AIMER_N * sizeof(*b_shares));
563
+ gf (*alpha_shares)[AIMER_L + 1] = malloc(AIMER_N * sizeof(*alpha_shares));
564
+ gf *v_shares = malloc(AIMER_N * sizeof(gf));
565
+
566
+ if (!nodes || !b_shares || !alpha_shares || !v_shares)
567
+ {
568
+ free(lin);
569
+ free(nodes);
570
+ free(b_shares);
571
+ free(alpha_shares);
572
+ free(v_shares);
573
+ return -2;
574
+ }
575
+
471
576
  for (size_t rep = 0; rep < AIMER_T; rep++)
472
577
  {
473
578
  size_t i_bar = indices[rep];
@@ -477,16 +582,16 @@ int crypto_sign_verify_internal(const uint8_t *sig, size_t siglen,
477
582
  gf epsilons[AIMER_L + 1];
478
583
  hash_squeeze(&ctx_e, (uint8_t *)epsilons, sizeof(epsilons));
479
584
 
480
- gf alpha = {0,};
585
+ gf alpha[AIMER_L + 1];
586
+ memset(alpha, 0, sizeof(alpha));
587
+
481
588
  for (size_t party = 0; party < AIMER_N; party++)
482
589
  {
483
590
  if (party == i_bar)
484
591
  {
485
592
  hash_update(&ctx_h1, sign->proofs[rep].missing_commitment,
486
593
  AIMER_COMMIT_SIZE);
487
- gf_from_bytes(alpha_shares[i_bar],
488
- sign->proofs[rep].missing_alpha_share_bytes);
489
- gf_add(alpha, alpha, alpha_shares[i_bar]);
594
+ recompute_missing_alpha(&sign->proofs[rep], alpha_shares[i_bar], alpha);
490
595
  continue;
491
596
  }
492
597
 
@@ -501,61 +606,36 @@ int crypto_sign_verify_internal(const uint8_t *sig, size_t siglen,
501
606
  memset(&mult_chk, 0, sizeof(mult_chk_t));
502
607
  if (party == AIMER_N - 1)
503
608
  {
504
- gf temp = {0,};
505
-
506
- gf_from_bytes(temp, sign->proofs[rep].delta_pt_bytes);
507
- gf_add(tape.pt_share, tape.pt_share, temp);
508
-
509
- for (size_t ell = 0; ell < AIMER_L; ell++)
510
- {
511
- gf_from_bytes(temp, sign->proofs[rep].delta_ts_bytes[ell]);
512
- gf_add(tape.t_shares[ell], tape.t_shares[ell], temp);
513
- }
514
-
515
- gf_from_bytes(temp, sign->proofs[rep].delta_c_bytes);
516
- gf_add(tape.c_share, tape.c_share, temp);
517
-
518
- gf_copy(mult_chk.x_shares[AIMER_L], vector_b);
609
+ recompute_last_share(&sign->proofs[rep], &tape);
519
610
  }
520
611
 
521
612
  // run the MPC simulation and prepare the mult check inputs
522
- for (size_t ell = 0; ell < AIMER_L; ell++)
523
- {
524
- gf_copy(mult_chk.x_shares[ell], tape.t_shares[ell]);
525
- }
526
- gf_copy(pt_shares[party], tape.pt_share);
527
- gf_copy(alpha_shares[party], tape.a_share);
528
- gf_copy(v_shares[party], tape.c_share);
529
- aim2_mpc(&mult_chk, (const gf(*)[AIM2_NUM_BITS_FIELD])matrix_A, ct_gf);
613
+ aim3_mpc(&mult_chk, lin, &tape, ct_gf, party);
530
614
 
615
+ gf_copy(v_shares[party], mult_chk.c_share);
531
616
  for (size_t ell = 0; ell < AIMER_L + 1; ell++)
532
617
  {
533
- gf_mul_add(alpha_shares[party], mult_chk.x_shares[ell], epsilons[ell]);
618
+ gf_copy(alpha_shares[party][ell], mult_chk.a_shares[ell]);
619
+ gf_mul_add(alpha_shares[party][ell], mult_chk.x_shares[ell],
620
+ epsilons[ell]);
621
+ gf_add(alpha[ell], alpha[ell], alpha_shares[party][ell]);
622
+
623
+ gf_copy(b_shares[party][ell], mult_chk.b_shares[ell]);
534
624
  gf_mul_add(v_shares[party], mult_chk.z_shares[ell], epsilons[ell]);
535
625
  }
536
- gf_add(alpha, alpha, alpha_shares[party]);
537
626
  }
538
627
 
539
628
  // alpha is opened, so we can finish calculating v_share
540
- gf_set0(v_shares[i_bar]);
541
- for (size_t party = 0; party < AIMER_N; party++)
542
- {
543
- if (party == i_bar)
544
- {
545
- continue;
546
- }
547
-
548
- gf_mul_add(v_shares[party], pt_shares[party], alpha);
549
- gf_add(v_shares[i_bar], v_shares[i_bar], v_shares[party]);
550
- }
629
+ recompute_v_shares(v_shares, b_shares, alpha, i_bar);
551
630
 
552
631
  // v is opened
553
- hash_update(&ctx_h2, (const uint8_t *)alpha_shares, AIMER_N * sizeof(gf));
554
- hash_update(&ctx_h2, (const uint8_t *)v_shares, AIMER_N * sizeof(gf));
555
-
632
+ hash_update(&ctx_h2, (const uint8_t *)alpha_shares,
633
+ AIM3_NUM_BYTES_FIELD * AIMER_N * (AIMER_L + 1));
634
+ hash_update(&ctx_h2, (const uint8_t *)v_shares,
635
+ AIM3_NUM_BYTES_FIELD * AIMER_N);
556
636
  // NOTE: depend on the order of values in proof_t
557
637
  hash_update(&ctx_h1, sign->proofs[rep].delta_pt_bytes,
558
- AIM2_NUM_BYTES_FIELD * (AIMER_L + 2));
638
+ AIM3_NUM_BYTES_FIELD * (AIMER_L + 2));
559
639
  }
560
640
  hash_ctx_release(&ctx_e);
561
641
 
@@ -569,9 +649,9 @@ int crypto_sign_verify_internal(const uint8_t *sig, size_t siglen,
569
649
  hash_squeeze(&ctx_h2, h_2_prime, AIMER_COMMIT_SIZE);
570
650
  hash_ctx_release(&ctx_h2);
571
651
 
572
- free(matrix_A);
652
+ free(lin);
573
653
  free(nodes);
574
- free(pt_shares);
654
+ free(b_shares);
575
655
  free(alpha_shares);
576
656
  free(v_shares);
577
657
 
@@ -617,11 +697,10 @@ int crypto_sign_open(uint8_t *m, size_t *mlen, const uint8_t *sm, size_t smlen,
617
697
  const uint8_t *message = sm;
618
698
  const uint8_t *signature = sm + message_len;
619
699
 
620
- int ret = crypto_sign_verify(signature, CRYPTO_BYTES, message, message_len,
621
- ctx, ctxlen, pk);
622
- if (ret != 0)
700
+ if (crypto_sign_verify(signature, CRYPTO_BYTES, message, message_len,
701
+ ctx, ctxlen, pk))
623
702
  {
624
- return ret;
703
+ return -1;
625
704
  }
626
705
 
627
706
  memmove(m, message, message_len);