@pinkparrot/qsafe-mayo-wasm 0.0.3

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 (97) hide show
  1. package/.gitmodules +3 -0
  2. package/.vscode/launch.json +12 -0
  3. package/LICENSE +201 -0
  4. package/bridge/mayo1_bridge.c +26 -0
  5. package/bridge/mayo2_bridge.c +26 -0
  6. package/bridge/randombytes_inject.c +44 -0
  7. package/build_mayo1.ps1 +36 -0
  8. package/build_mayo2.ps1 +36 -0
  9. package/dist/mayo.browser.min.js +216 -0
  10. package/dist/mayo1.js +0 -0
  11. package/dist/mayo2.js +0 -0
  12. package/dist/mayo_api.js +139 -0
  13. package/dist/package.json +1 -0
  14. package/gitignore +2 -0
  15. package/index.mjs +1 -0
  16. package/mayo-c/.astylerc +16 -0
  17. package/mayo-c/.cmake/flags.cmake +45 -0
  18. package/mayo-c/.cmake/sanitizers.cmake +81 -0
  19. package/mayo-c/.cmake/target.cmake +71 -0
  20. package/mayo-c/.github/workflows/ci_clang.yml +61 -0
  21. package/mayo-c/.github/workflows/ci_gcc.yml +60 -0
  22. package/mayo-c/.github/workflows/cmake.yml +160 -0
  23. package/mayo-c/.github/workflows/macos_m1.yml +68 -0
  24. package/mayo-c/CMakeLists.txt +35 -0
  25. package/mayo-c/KAT/PQCsignKAT_24_MAYO_1.req +900 -0
  26. package/mayo-c/KAT/PQCsignKAT_24_MAYO_1.rsp +902 -0
  27. package/mayo-c/KAT/PQCsignKAT_24_MAYO_2.req +900 -0
  28. package/mayo-c/KAT/PQCsignKAT_24_MAYO_2.rsp +902 -0
  29. package/mayo-c/KAT/PQCsignKAT_32_MAYO_3.req +900 -0
  30. package/mayo-c/KAT/PQCsignKAT_32_MAYO_3.rsp +902 -0
  31. package/mayo-c/KAT/PQCsignKAT_40_MAYO_5.req +900 -0
  32. package/mayo-c/KAT/PQCsignKAT_40_MAYO_5.rsp +902 -0
  33. package/mayo-c/LICENSE +202 -0
  34. package/mayo-c/META/MAYO-1_META.yml +52 -0
  35. package/mayo-c/META/MAYO-2_META.yml +52 -0
  36. package/mayo-c/META/MAYO-3_META.yml +52 -0
  37. package/mayo-c/META/MAYO-5_META.yml +52 -0
  38. package/mayo-c/NOTICE +13 -0
  39. package/mayo-c/README.md +183 -0
  40. package/mayo-c/apps/CMakeLists.txt +31 -0
  41. package/mayo-c/apps/PQCgenKAT_sign.c +281 -0
  42. package/mayo-c/apps/example.c +151 -0
  43. package/mayo-c/apps/example_nistapi.c +124 -0
  44. package/mayo-c/include/mayo.h +442 -0
  45. package/mayo-c/include/mem.h +25 -0
  46. package/mayo-c/include/randombytes.h +31 -0
  47. package/mayo-c/scripts/contstants.py +141 -0
  48. package/mayo-c/scripts/find_irred_poly.sage +39 -0
  49. package/mayo-c/src/AVX2/arithmetic_common.h +159 -0
  50. package/mayo-c/src/AVX2/echelon_form.h +91 -0
  51. package/mayo-c/src/AVX2/echelon_form_loop.h +58 -0
  52. package/mayo-c/src/AVX2/shuffle_arithmetic.h +442 -0
  53. package/mayo-c/src/CMakeLists.txt +98 -0
  54. package/mayo-c/src/arithmetic.c +128 -0
  55. package/mayo-c/src/arithmetic.h +124 -0
  56. package/mayo-c/src/common/aes128ctr.c +293 -0
  57. package/mayo-c/src/common/aes_c.c +741 -0
  58. package/mayo-c/src/common/aes_ctr.h +32 -0
  59. package/mayo-c/src/common/aes_neon.c +201 -0
  60. package/mayo-c/src/common/debug_bench_tools.h +69 -0
  61. package/mayo-c/src/common/fips202.c +1093 -0
  62. package/mayo-c/src/common/fips202.h +12 -0
  63. package/mayo-c/src/common/mem.c +19 -0
  64. package/mayo-c/src/common/randombytes_ctrdrbg.c +141 -0
  65. package/mayo-c/src/common/randombytes_system.c +399 -0
  66. package/mayo-c/src/generic/arithmetic_dynamic.h +68 -0
  67. package/mayo-c/src/generic/arithmetic_fixed.h +84 -0
  68. package/mayo-c/src/generic/echelon_form.h +152 -0
  69. package/mayo-c/src/generic/ef_inner_loop.h +56 -0
  70. package/mayo-c/src/generic/generic_arithmetic.h +294 -0
  71. package/mayo-c/src/mayo.c +675 -0
  72. package/mayo-c/src/mayo_1/api.c +46 -0
  73. package/mayo-c/src/mayo_1/api.h +43 -0
  74. package/mayo-c/src/mayo_2/api.c +46 -0
  75. package/mayo-c/src/mayo_2/api.h +43 -0
  76. package/mayo-c/src/mayo_3/api.c +46 -0
  77. package/mayo-c/src/mayo_3/api.h +43 -0
  78. package/mayo-c/src/mayo_5/api.c +46 -0
  79. package/mayo-c/src/mayo_5/api.h +43 -0
  80. package/mayo-c/src/neon/arithmetic_common.h +132 -0
  81. package/mayo-c/src/neon/echelon_form.h +55 -0
  82. package/mayo-c/src/neon/echelon_form_loop.h +58 -0
  83. package/mayo-c/src/neon/shuffle_arithmetic.h +462 -0
  84. package/mayo-c/src/params.c +42 -0
  85. package/mayo-c/src/simple_arithmetic.h +138 -0
  86. package/mayo-c/test/CMakeLists.txt +51 -0
  87. package/mayo-c/test/bench.c +166 -0
  88. package/mayo-c/test/m1cycles.c +155 -0
  89. package/mayo-c/test/m1cycles.h +13 -0
  90. package/mayo-c/test/test_kat.c +271 -0
  91. package/mayo-c/test/test_mayo.c +139 -0
  92. package/mayo-c/test/test_sample_solution.c +75 -0
  93. package/mayo-c/test/test_various.c +680 -0
  94. package/package.json +39 -0
  95. package/publish.bat +22 -0
  96. package/readme.md +80 -0
  97. package/test/test.mjs +42 -0
@@ -0,0 +1,680 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+
3
+ #include <stdio.h>
4
+ #include <stdlib.h>
5
+ #include <string.h>
6
+ #include <ctype.h>
7
+ #include <randombytes.h>
8
+ #include <time.h>
9
+ #include <mayo.h>
10
+ #include <stdalign.h>
11
+ #include <arithmetic.h>
12
+ #include <fips202.h>
13
+ #include <aes_ctr.h>
14
+ #include <simple_arithmetic.h>
15
+
16
+ #include <mayo.c>
17
+
18
+ #ifdef ENABLE_CT_TESTING
19
+ #include <valgrind/memcheck.h>
20
+ #endif
21
+ #include <debug_bench_tools.h>
22
+
23
+ int test_mayo(const mayo_params_t *p) {
24
+ unsigned char _pk[CPK_BYTES_MAX + 1] = {0};
25
+ unsigned char _sk[CSK_BYTES_MAX + 1] = {0};
26
+ unsigned char _sig[SIG_BYTES_MAX + 32 + 1] = {0};
27
+ unsigned char _msg[32+1] = { 0 };
28
+
29
+ // Enforce unaligned memory addresses
30
+ unsigned char *pk = (unsigned char *) ((uintptr_t)_pk | (uintptr_t)1);
31
+ unsigned char *sk = (unsigned char *) ((uintptr_t)_sk | (uintptr_t)1);
32
+ unsigned char *sig = (unsigned char *) ((uintptr_t)_sig | (uintptr_t)1);
33
+ unsigned char *msg = (unsigned char *) ((uintptr_t)_msg | (uintptr_t)1);
34
+
35
+ for (int i = 0; i < 32; i++)
36
+ {
37
+ msg[i] = i;
38
+ }
39
+
40
+ unsigned char seed[48] = { 0 };
41
+ size_t msglen = 32;
42
+
43
+ randombytes_init(seed, NULL, 256);
44
+
45
+ printf("Testing Keygen, Sign, Open: %s\n", PARAM_name(p));
46
+
47
+ int res = mayo_keypair(p, pk, sk);
48
+ if (res != MAYO_OK) {
49
+ res = -1;
50
+ printf("keygen failed!\n");
51
+ goto err;
52
+ }
53
+
54
+ #ifdef ENABLE_CT_TESTING
55
+ VALGRIND_MAKE_MEM_DEFINED(pk, p->cpk_bytes);
56
+ #endif
57
+
58
+ size_t smlen = PARAM_sig_bytes(p) + 32;
59
+
60
+ res = mayo_sign(p, sig, &smlen, msg, 32, sk);
61
+ if (res != MAYO_OK) {
62
+ res = -1;
63
+ printf("sign failed!\n");
64
+ goto err;
65
+ }
66
+
67
+ /*
68
+ printf("pk: ");
69
+ print_hex(pk, p->cpk_bytes, 40);
70
+ printf("sk: ");
71
+ print_hex(sk, p->csk_bytes, 40);
72
+ printf("sm: ");
73
+ print_hex(sig, smlen, 40); */
74
+
75
+ #ifdef ENABLE_CT_TESTING
76
+ VALGRIND_MAKE_MEM_DEFINED(sig, smlen);
77
+ #endif
78
+
79
+ res = mayo_open(p, msg, &msglen, sig, smlen, pk);
80
+ if (res != MAYO_OK) {
81
+ res = -1;
82
+ printf("verify failed!\n");
83
+ goto err;
84
+ }
85
+
86
+ printf("verify success!\n");
87
+
88
+ sig[0] = ~sig[0];
89
+ res = mayo_open(p, msg, &msglen, sig, smlen, pk);
90
+ if (res != MAYO_ERR) {
91
+ res = -1;
92
+ printf("wrong signature still verified!\n");
93
+ goto err;
94
+ } else {
95
+ res = MAYO_OK;
96
+ }
97
+
98
+ err:
99
+ return res;
100
+ }
101
+
102
+ static void print_hex(const unsigned char *hex, int len, int row_len) {
103
+ int ctr = 0;
104
+ printf("%4d:", ctr);
105
+ for (int i = 0; i < len; ++i) {
106
+ if(i % row_len == 0 && i > 0){
107
+ ctr ++;
108
+ printf("\n%4d:", ctr);
109
+ }
110
+ printf("%2x", hex[i]);
111
+ }
112
+ printf("\n");
113
+ }
114
+
115
+ // Evaluate public map at oil vector as sanity check
116
+ int test_eval_oil(const mayo_params_t *p) {
117
+
118
+ int ret = MAYO_OK;
119
+ unsigned char seed_sk[CSK_BYTES_MAX];
120
+ unsigned char S[PK_SEED_BYTES_MAX + O_BYTES_MAX];
121
+ uint64_t P[P1_LIMBS_MAX + P2_LIMBS_MAX];
122
+ uint64_t P3[O_MAX * O_MAX * M_VEC_LIMBS_MAX] = {0};
123
+
124
+ unsigned char cpk[CPK_BYTES_MAX];
125
+
126
+ unsigned char *seed_pk;
127
+ unsigned char O[V_MAX*O_MAX];
128
+
129
+ const int m_vec_limbs = PARAM_m_vec_limbs(p);
130
+ (void) m_vec_limbs;
131
+ const int param_m = PARAM_m(p);
132
+ const int param_k = PARAM_k(p);
133
+ const int param_n = PARAM_n(p);
134
+ const int param_v = PARAM_v(p);
135
+ const int param_o = PARAM_o(p);
136
+ const int param_O_bytes = PARAM_O_bytes(p);
137
+ const int param_pk_seed_bytes = PARAM_pk_seed_bytes(p);
138
+ const int param_sk_seed_bytes = PARAM_sk_seed_bytes(p);
139
+
140
+ // seed_sk $←- B^(sk_seed bytes)
141
+ randombytes(seed_sk, param_sk_seed_bytes);
142
+
143
+ // S ← shake256(seedsk, pk seed bytes + O bytes)
144
+ shake256(S, param_pk_seed_bytes + param_O_bytes, seed_sk,
145
+ param_sk_seed_bytes);
146
+ // seed_pk ← s[0 : pk_seed_bytes]
147
+ seed_pk = S;
148
+
149
+ // o ← Decode_o(s[pk_seed_bytes : pk_seed_bytes + o_bytes])
150
+ decode(S + param_pk_seed_bytes, O, param_v * param_o);
151
+
152
+ //memset(O, 0, param_v*param_o);
153
+ //O[0] = 1;
154
+
155
+ expand_P1_P2(p, P, seed_pk);
156
+
157
+ uint64_t *P1 = P;
158
+ uint64_t *P2 = P + PARAM_P1_limbs(p);
159
+
160
+ //memset(P1 + 8*5, 0, sizeof(uint64_t[PARAM_P1_limbs(p)-5]));
161
+ //memset(P2, 0, sizeof(uint64_t[PARAM_P2_limbs(p)]));
162
+
163
+ uint64_t P2_copy[P2_LIMBS_MAX];
164
+ memcpy(P2_copy, P2, PARAM_P2_limbs(p)*sizeof(uint64_t));
165
+
166
+ compute_P3(p, P1, P2_copy, O, P3);
167
+
168
+ // store seed_pk in cpk
169
+ memcpy(cpk, seed_pk, param_pk_seed_bytes);
170
+
171
+ uint64_t P3_upper[P3_LIMBS_MAX];
172
+ memset(P3_upper, 1, PARAM_P3_limbs(p)*sizeof(int64_t));
173
+
174
+ // compute Upper(P3) and store in cpk
175
+ m_upper(p, P3, P3_upper, param_o);
176
+
177
+ // sample s from O^k
178
+ unsigned char s[N_MAX*K_MAX] = {0};
179
+ for (int a = 0; a < param_k; a++)
180
+ {
181
+ for (int j = 0; j < param_o; j++)
182
+ {
183
+ s[param_n*a + param_v + j] = rand() % 16;
184
+ for(int i = 0; i < param_v; i++)
185
+ {
186
+ s[param_n*a + i] ^= mul_f(O[i*param_o + j], s[param_n*a + param_v + j]);
187
+ }
188
+ }
189
+ }
190
+
191
+ // evaluate Public map at s
192
+ unsigned char y[2*M_MAX] = {0};
193
+ eval_public_map(p, s, P1,P2,P3_upper, y);
194
+
195
+ for (int i = 0; i < param_m; i++)
196
+ {
197
+ if(y[i] != 0){
198
+ ret = 1;
199
+ }
200
+ }
201
+
202
+ if(ret){
203
+ printf("sanity check failed: evaluation at a random oil vector should be zero:\n");
204
+
205
+ printf("s:\n");
206
+ print_hex(s, param_k*param_n, param_n);
207
+
208
+ printf("P(s):\n");
209
+ print_hex(y, param_m, param_m);
210
+ }
211
+
212
+ printf("oil evaluation check result: %d (0 = OK)\n", ret);
213
+
214
+ return ret;
215
+ }
216
+
217
+
218
+ // Check if public map satisfies P(a*x) = a^2 P(x)
219
+ int test_eval_quad(const mayo_params_t *p) {
220
+
221
+ int ret = MAYO_OK;
222
+ unsigned char seed_sk[CSK_BYTES_MAX];
223
+ unsigned char S[PK_SEED_BYTES_MAX + O_BYTES_MAX];
224
+ uint64_t P[P1_LIMBS_MAX + P2_LIMBS_MAX];
225
+ uint64_t P3[O_MAX * O_MAX * M_VEC_LIMBS_MAX] = {0};
226
+
227
+ unsigned char *seed_pk;
228
+ unsigned char O[V_MAX*O_MAX];
229
+
230
+ const int m_vec_limbs = PARAM_m_vec_limbs(p);
231
+ (void) m_vec_limbs;
232
+
233
+ const int param_m = PARAM_m(p);
234
+ const int param_k = PARAM_k(p);
235
+ const int param_n = PARAM_n(p);
236
+ const int param_v = PARAM_v(p);
237
+ const int param_o = PARAM_o(p);
238
+ const int param_O_bytes = PARAM_O_bytes(p);
239
+ const int param_pk_seed_bytes = PARAM_pk_seed_bytes(p);
240
+ const int param_sk_seed_bytes = PARAM_sk_seed_bytes(p);
241
+
242
+ // seed_sk $←- B^(sk_seed bytes)
243
+ randombytes(seed_sk, param_sk_seed_bytes);
244
+
245
+ // S ← shake256(seedsk, pk seed bytes + O bytes)
246
+ shake256(S, param_pk_seed_bytes + param_O_bytes, seed_sk,
247
+ param_sk_seed_bytes);
248
+ // seed_pk ← s[0 : pk_seed_bytes]
249
+ seed_pk = S;
250
+
251
+ // o ← Decode_o(s[pk_seed_bytes : pk_seed_bytes + o_bytes])
252
+ decode(S + param_pk_seed_bytes, O, param_v * param_o);
253
+
254
+ //memset(O, 0, param_v*param_o);
255
+ //O[1] = 1;
256
+
257
+ expand_P1_P2(p, P, seed_pk);
258
+
259
+ uint64_t *P1 = P;
260
+ uint64_t *P2 = P + PARAM_P1_limbs(p);
261
+
262
+ uint64_t P2_copy[P2_LIMBS_MAX];
263
+ memcpy(P2_copy, P2, PARAM_P2_limbs(p)*sizeof(uint64_t));
264
+ compute_P3(p, P1, P2_copy, O, P3);
265
+
266
+ uint64_t P3_upper[P3_LIMBS_MAX];
267
+ memset(P3_upper, 1, PARAM_P3_limbs(p)*sizeof(int64_t));
268
+
269
+ // compute Upper(P3) and store in cpk
270
+ m_upper(p, P3, P3_upper, param_o);
271
+
272
+ // sample s
273
+ unsigned char s[N_MAX*K_MAX] = {0};
274
+ for (int a = 0; a < param_k*param_n; a++)
275
+ {
276
+ s[a] = rand() % 16;
277
+ }
278
+
279
+ unsigned char y[2*M_MAX] = {0};
280
+ eval_public_map(p, s, P1,P2,P3_upper, y);
281
+
282
+ for (int i = 0; i < 16; i++)
283
+ {
284
+ unsigned char ss[N_MAX*K_MAX] = {0};
285
+ unsigned char yy[2*M_MAX] = {0};
286
+ unsigned char yyy[2*M_MAX] = {0};
287
+
288
+ for (int j = 0; j < param_k*param_n; j++)
289
+ {
290
+ ss[j] = mul_f(s[j], i);
291
+ }
292
+
293
+ eval_public_map(p, ss, P1,P2,P3_upper, yy);
294
+ unsigned char i_sq = mul_f(i,i);
295
+
296
+ for (int j = 0; j < param_m; j++)
297
+ {
298
+ ss[j] = mul_f(s[j], i);
299
+ yyy[j] = mul_f(i_sq, y[j]);
300
+ if ( yyy[j] != yy[j]){
301
+ ret = MAYO_ERR;
302
+ }
303
+ }
304
+
305
+ if (ret != 0){
306
+ printf("%2d^2*P(s):", i);
307
+ print_hex(yy, param_m, param_m);
308
+ printf("P(%2d*s): ", i);
309
+ print_hex(yyy, param_m, param_m);
310
+
311
+ for (int j = 0; j < param_m; j++)
312
+ {
313
+ yyy[j] ^= yy[j];
314
+ }
315
+
316
+ printf("difference:");
317
+ print_hex(yyy, param_m, param_m);
318
+
319
+ }
320
+ }
321
+
322
+ printf("quad evaluation check result: %d (0 = OK)\n", ret);
323
+
324
+ return ret;
325
+ }
326
+
327
+ // Compute A in two ways and compare result
328
+ int test_A(const mayo_params_t *p) {
329
+
330
+ int ret = MAYO_OK;
331
+ unsigned char seed_sk[CSK_BYTES_MAX];
332
+ unsigned char S[PK_SEED_BYTES_MAX + O_BYTES_MAX];
333
+ uint64_t P[P1_LIMBS_MAX + P2_LIMBS_MAX];
334
+ uint64_t P3[O_MAX * O_MAX * M_VEC_LIMBS_MAX] = {0};
335
+
336
+ unsigned char *seed_pk;
337
+ unsigned char O[V_MAX*O_MAX];
338
+
339
+ const int m_vec_limbs = PARAM_m_vec_limbs(p);
340
+ (void) m_vec_limbs;
341
+
342
+ const int param_m = PARAM_m(p);
343
+ const int param_k = PARAM_k(p);
344
+ const int param_n = PARAM_n(p);
345
+ const int param_v = PARAM_v(p);
346
+ const int param_o = PARAM_o(p);
347
+ const int param_O_bytes = PARAM_O_bytes(p);
348
+ const int param_pk_seed_bytes = PARAM_pk_seed_bytes(p);
349
+ const int param_sk_seed_bytes = PARAM_sk_seed_bytes(p);
350
+ uint64_t Mtmp[K_MAX * O_MAX * M_VEC_LIMBS_MAX] = {0};
351
+
352
+ // seed_sk $←- B^(sk_seed bytes)
353
+ randombytes(seed_sk, param_sk_seed_bytes);
354
+
355
+ // S ← shake256(seedsk, pk seed bytes + O bytes)
356
+ shake256(S, param_pk_seed_bytes + param_O_bytes, seed_sk,
357
+ param_sk_seed_bytes);
358
+ // seed_pk ← s[0 : pk_seed_bytes]
359
+ seed_pk = S;
360
+
361
+ // o ← Decode_o(s[pk_seed_bytes : pk_seed_bytes + o_bytes])
362
+ decode(S + param_pk_seed_bytes, O, param_v * param_o);
363
+
364
+ expand_P1_P2(p, P, seed_pk);
365
+
366
+ uint64_t *P1 = P;
367
+ uint64_t *P2 = P + PARAM_P1_limbs(p);
368
+
369
+ uint64_t P2_copy[P2_LIMBS_MAX];
370
+ memcpy(P2_copy, P2, PARAM_P2_limbs(p)*sizeof(uint64_t));
371
+ compute_P3(p, P1, P2_copy, O, P3);
372
+
373
+ uint64_t P3_upper[P3_LIMBS_MAX];
374
+ memset(P3_upper, 1, PARAM_P3_limbs(p)*sizeof(int64_t));
375
+
376
+ // compute Upper(P3) and store in cpk
377
+ m_upper(p, P3, P3_upper, param_o);
378
+
379
+ // compute L_i = (P1 + P1^t)*O + P2
380
+ uint64_t L[P2_LIMBS_MAX] = {0};
381
+ memcpy(L, P2, PARAM_P2_limbs(p)*sizeof(uint64_t));
382
+ P1P1t_times_O(p, P1, O, L);
383
+
384
+ // sample vinegar
385
+ unsigned char v[V_MAX * K_MAX] = {0};
386
+ for (int i = 0; i < param_v*param_k; i++)
387
+ {
388
+ v[i] = rand() % 16;
389
+ }
390
+
391
+ unsigned char A1[((M_MAX+7)/8*8) * (K_MAX * O_MAX + 1)] = {0};
392
+ unsigned char A2[M_MAX * (K_MAX * O_MAX + 1)] = {0};
393
+
394
+ uint64_t VPV[ PARAM_m_vec_limbs(p)*V_MAX*V_MAX];
395
+ compute_M_and_VPV(p, v, L, P1, Mtmp, VPV);
396
+
397
+ compute_A(p, Mtmp, A1);
398
+
399
+ unsigned char s_base[N_MAX*K_MAX] = {0};
400
+ for (int i = 0; i < param_k; i++)
401
+ {
402
+ for (int j = 0; j < param_v; j++)
403
+ {
404
+ s_base[i*param_n + j] = v[i*param_v + j];
405
+ }
406
+ }
407
+
408
+ unsigned char y_base[M_MAX] = {0};
409
+ eval_public_map(p, s_base, P1, P2, P3_upper, y_base);
410
+
411
+ for (int i = 0; i < param_k; i++)
412
+ {
413
+ for (int j = 0; j < param_o; j++)
414
+ {
415
+ unsigned char s[N_MAX*K_MAX] = {0};
416
+ memcpy(s, s_base, param_n*param_k);
417
+
418
+ for (int k = 0; k < param_v; k++)
419
+ {
420
+ s[k + i * param_n] ^= O[k*param_o + j];
421
+ }
422
+ s[param_v + i*param_n + j] ^= 1;
423
+
424
+ unsigned char y[M_MAX] = {0};
425
+ eval_public_map(p, s, P1, P2, P3_upper, y);
426
+
427
+ for (int k = 0; k < param_m; k++)
428
+ {
429
+ y[k] ^= y_base[k];
430
+ }
431
+
432
+ for (int k = 0; k < param_m; k++)
433
+ {
434
+ A2[k*(param_k*param_o+1) + i*param_o + j] = y[k];
435
+ }
436
+ }
437
+ }
438
+
439
+ for (int i = 0; i < param_m*(param_k*param_o+1); i++)
440
+ {
441
+ if (A1[i] != A2[i]){
442
+ ret = 1;
443
+
444
+ printf("A differs in row %d, col %d\n", i / (param_k*param_o + 1), i % (param_k*param_o + 1) );
445
+ break;
446
+ }
447
+ }
448
+
449
+ if(ret == 1){
450
+
451
+ printf("A computed normally:\n");
452
+ for (int i = 0; i < param_m; i++)
453
+ {
454
+ printf("%3d: ", i);
455
+ for (int j = 0; j < param_k*param_o + 1; j++)
456
+ {
457
+ if (j % param_o == 0 && j > 0){
458
+ printf("|");
459
+ }
460
+ printf("%1x", A1[i*(param_k*param_o+1)+j]);
461
+ }
462
+ printf("\n");
463
+ }
464
+
465
+ printf("A computed via evaluations:\n");
466
+ for (int i = 0; i < param_m; i++)
467
+ {
468
+ printf("%3d: ", i);
469
+ for (int j = 0; j < param_k*param_o + 1; j++)
470
+ {
471
+ if (j % param_o == 0 && j > 0){
472
+ printf("|");
473
+ }
474
+ printf("%1x", A2[i*(param_k*param_o+1)+j]);
475
+ }
476
+ printf("\n");
477
+ }
478
+ }
479
+
480
+ unsigned char s[N_MAX*K_MAX] = {0};
481
+ memcpy(s, s_base, param_n*param_k);
482
+
483
+ // sample random s = v + o
484
+ for (int i = 0; i < param_k; i++)
485
+ {
486
+ for (int j = 0; j < param_o; j++)
487
+ {
488
+ s[i*param_n + param_v + j] = rand() % 16;
489
+
490
+ for (int k = 0; k < param_v; k++)
491
+ {
492
+ s[k + i * param_n] ^= mul_f(s[i*param_n + param_v + j], O[k*param_o + j]);
493
+ }
494
+ }
495
+ }
496
+
497
+ unsigned char y[M_MAX] = {0};
498
+ unsigned char y1[M_MAX] = {0};
499
+ unsigned char y2[M_MAX] = {0};
500
+ eval_public_map(p, s, P1, P2, P3_upper, y);
501
+
502
+ // compute y_base + A*o
503
+ memcpy(y1, y_base, param_m);
504
+ memcpy(y2, y_base, param_m);
505
+
506
+ for (int i = 0; i < param_k; i++)
507
+ {
508
+ for (int j = 0; j < param_o; j++)
509
+ {
510
+ for (int k = 0; k < param_m; k++)
511
+ {
512
+ y1[k] ^= mul_f( s[i*param_n + param_v + j], A1[k*(param_k*param_o+1)+i*param_o+j] );
513
+ y2[k] ^= mul_f( s[i*param_n + param_v + j], A2[k*(param_k*param_o+1)+i*param_o+j] );
514
+ }
515
+ }
516
+ }
517
+
518
+ if (memcmp(y,y1, param_m) != 0){
519
+ printf("A1 is wrong!\n");
520
+ ret = MAYO_ERR;
521
+ }
522
+
523
+ if (memcmp(y,y2, param_m) != 0){
524
+ printf("A2 is wrong!\n");
525
+ ret = MAYO_ERR;
526
+ }
527
+
528
+ unsigned char t[M_MAX] = {0};
529
+ unsigned char tt[M_MAX] = {0};
530
+ unsigned char x[V_MAX*K_MAX] = {0};
531
+ unsigned char r[V_MAX*K_MAX] = {0};
532
+
533
+ for (int i = 0; i < param_k*param_o; i++)
534
+ {
535
+ r[i] = rand() % 16;
536
+ }
537
+
538
+ for (int i = 0; i < param_m; i++)
539
+ {
540
+ t[i] = rand() % 16;
541
+ tt[i] = t[i];
542
+ }
543
+
544
+ for (int i = 0; i < param_m; i++)
545
+ {
546
+ tt[i] ^= y_base[i];
547
+ }
548
+
549
+ sample_solution(p, A1, tt, r, x, param_k, param_o, param_m, param_k*param_o + 1);
550
+
551
+ memcpy(s, s_base, param_n*param_k);
552
+
553
+ unsigned char *vi;
554
+ unsigned char Ox[V_MAX] = {0};
555
+
556
+ for (int i = 0; i <= param_k - 1; ++i) {
557
+ vi = s_base + i * param_n;
558
+ mat_mul(O, x + i * param_o, Ox, param_o, param_v, 1);
559
+ mat_add(vi, Ox, s + i * param_n, param_v, 1);
560
+ memcpy(s + i * param_n + param_v, x + i * param_o, param_o);
561
+ }
562
+
563
+ unsigned char eval[M_MAX] = {0};
564
+ eval_public_map(p, s, P1, P2, P3_upper, eval);
565
+
566
+
567
+ if (memcmp(t, eval, param_m) != 0){
568
+ ret = MAYO_ERR;
569
+
570
+ printf("target:\n");
571
+ print_hex(t, param_m, param_m);
572
+
573
+ printf("eval: \n");
574
+ print_hex(eval, param_m, param_m);
575
+ }
576
+
577
+ printf("A check result: %d (0 = OK)\n", ret);
578
+ return ret;
579
+ }
580
+
581
+
582
+ // test sample_solution
583
+ int test_sample_sol(const mayo_params_t *p) {
584
+
585
+ int ret = MAYO_OK;
586
+
587
+ const int param_m = PARAM_m(p);
588
+ const int param_k = PARAM_k(p);
589
+ const int param_o = PARAM_o(p);
590
+
591
+ #define M_MAX_ROUND_UP (((M_MAX +7)/8)*8)
592
+
593
+ unsigned char A[M_MAX_ROUND_UP * (K_MAX * O_MAX + 1)] = {0};
594
+ unsigned char A1[M_MAX_ROUND_UP * (K_MAX * O_MAX + 1)] = {0};
595
+ unsigned char y[M_MAX] = {0};
596
+ unsigned char x[K_MAX * N_MAX] = {0};
597
+ unsigned char r[K_MAX * O_MAX + 1] = {0};
598
+
599
+ const int cols = param_k*param_o + 1;
600
+
601
+ for (int i = 0; i < param_m*(param_k*param_o + 1); i++)
602
+ {
603
+ A[i] = rand() % 16;
604
+ A1[i] = A[i];
605
+ }
606
+
607
+ for (int i = 0; i < param_m; i++)
608
+ {
609
+ y[i] = rand() % 16;
610
+ }
611
+
612
+ for (int i = 0; i < param_o*param_k; i++)
613
+ {
614
+ r[i] = rand() % 16;
615
+ }
616
+
617
+ //sample random A
618
+
619
+ sample_solution(p, A, y, r, x, param_k, param_o, param_m, cols);
620
+
621
+ unsigned char yy[M_MAX] = {0};
622
+
623
+ // compute A*x
624
+
625
+ for (int i = 0; i < param_k*param_o; i++)
626
+ {
627
+ for (int k = 0; k < param_m; k++)
628
+ {
629
+ yy[k] ^= mul_f( x[i], A1[k*(param_k*param_o+1)+i] );
630
+ }
631
+ }
632
+
633
+ if (memcmp(y,yy, param_m) != 0){
634
+ printf("sample solution is wrong!\n");
635
+ ret = MAYO_ERR;
636
+
637
+ printf("y and A*x:\n");
638
+ print_hex(y, param_m, param_m);
639
+ print_hex(yy, param_m, param_m);
640
+ }
641
+
642
+ printf("Sample solution check result: %d (0 = OK)\n", ret);
643
+ return ret;
644
+ }
645
+
646
+ int main(int argc, char *argv[]) {
647
+ int rc = 0;
648
+
649
+ srand(time(NULL));
650
+
651
+ const mayo_params_t *p;
652
+
653
+ #ifdef ENABLE_PARAMS_DYNAMIC
654
+ if (!strcmp(argv[1], "MAYO-1")) {
655
+ p = &MAYO_1;
656
+ } else if (!strcmp(argv[1], "MAYO-2")) {
657
+ p = &MAYO_2;
658
+ } else if (!strcmp(argv[1], "MAYO-3")) {
659
+ p = &MAYO_3;
660
+ } else if (!strcmp(argv[1], "MAYO-5")) {
661
+ p = &MAYO_5;
662
+ } else {
663
+ printf("unknown parameter set\n");
664
+ return MAYO_ERR;
665
+ }
666
+ #else
667
+ p = NULL;
668
+ #endif
669
+
670
+ rc ^= test_mayo(p);
671
+ rc ^= test_eval_oil(p);
672
+ rc ^= test_eval_quad(p);
673
+ rc ^= test_A(p);
674
+ rc ^= test_sample_sol(p);
675
+
676
+ if (rc != MAYO_OK) {
677
+ printf("test failed for %s\n", argv[1]);
678
+ }
679
+ return rc;
680
+ }
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@pinkparrot/qsafe-mayo-wasm",
3
+ "version": "0.0.3",
4
+ "author": "Pink Parrot",
5
+ "description": "Post-quantum signatures in WebAssembly — MAYO-1 & MAYO-2, browser & Node.js ready",
6
+ "type": "module",
7
+ "exports": {
8
+ ".": {
9
+ "browser": "./dist/mayo.browser.min.js",
10
+ "default": "./index.mjs"
11
+ }
12
+ },
13
+ "main": "index.mjs",
14
+ "scripts": {
15
+ "test": "node test/test.mjs",
16
+ "build:min": "esbuild index.mjs --bundle --minify --outfile=dist/mayo.browser.min.js --format=esm --platform=browser --define:ENVIRONMENT_IS_NODE=false --external:node:fs --external:node:path --external:node:crypto --external:node:url",
17
+ "build": "npm run build:min"
18
+ },
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://github.com/Seigneur-Machiavel/qsafe-mayo-wasm.git"
22
+ },
23
+ "keywords": [
24
+ "post-quantum",
25
+ "mayo",
26
+ "wasm",
27
+ "signature",
28
+ "cryptography",
29
+ "pqc"
30
+ ],
31
+ "license": "Apache-2.0",
32
+ "bugs": {
33
+ "url": "https://github.com/Seigneur-Machiavel/qsafe-mayo-wasm/issues"
34
+ },
35
+ "devDependencies": {
36
+ "esbuild": "^0.25.10"
37
+ },
38
+ "homepage": "https://github.com/Seigneur-Machiavel/qsafe-mayo-wasm#readme"
39
+ }