@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.
- package/.gitmodules +3 -0
- package/.vscode/launch.json +12 -0
- package/LICENSE +201 -0
- package/bridge/mayo1_bridge.c +26 -0
- package/bridge/mayo2_bridge.c +26 -0
- package/bridge/randombytes_inject.c +44 -0
- package/build_mayo1.ps1 +36 -0
- package/build_mayo2.ps1 +36 -0
- package/dist/mayo.browser.min.js +216 -0
- package/dist/mayo1.js +0 -0
- package/dist/mayo2.js +0 -0
- package/dist/mayo_api.js +139 -0
- package/dist/package.json +1 -0
- package/gitignore +2 -0
- package/index.mjs +1 -0
- package/mayo-c/.astylerc +16 -0
- package/mayo-c/.cmake/flags.cmake +45 -0
- package/mayo-c/.cmake/sanitizers.cmake +81 -0
- package/mayo-c/.cmake/target.cmake +71 -0
- package/mayo-c/.github/workflows/ci_clang.yml +61 -0
- package/mayo-c/.github/workflows/ci_gcc.yml +60 -0
- package/mayo-c/.github/workflows/cmake.yml +160 -0
- package/mayo-c/.github/workflows/macos_m1.yml +68 -0
- package/mayo-c/CMakeLists.txt +35 -0
- package/mayo-c/KAT/PQCsignKAT_24_MAYO_1.req +900 -0
- package/mayo-c/KAT/PQCsignKAT_24_MAYO_1.rsp +902 -0
- package/mayo-c/KAT/PQCsignKAT_24_MAYO_2.req +900 -0
- package/mayo-c/KAT/PQCsignKAT_24_MAYO_2.rsp +902 -0
- package/mayo-c/KAT/PQCsignKAT_32_MAYO_3.req +900 -0
- package/mayo-c/KAT/PQCsignKAT_32_MAYO_3.rsp +902 -0
- package/mayo-c/KAT/PQCsignKAT_40_MAYO_5.req +900 -0
- package/mayo-c/KAT/PQCsignKAT_40_MAYO_5.rsp +902 -0
- package/mayo-c/LICENSE +202 -0
- package/mayo-c/META/MAYO-1_META.yml +52 -0
- package/mayo-c/META/MAYO-2_META.yml +52 -0
- package/mayo-c/META/MAYO-3_META.yml +52 -0
- package/mayo-c/META/MAYO-5_META.yml +52 -0
- package/mayo-c/NOTICE +13 -0
- package/mayo-c/README.md +183 -0
- package/mayo-c/apps/CMakeLists.txt +31 -0
- package/mayo-c/apps/PQCgenKAT_sign.c +281 -0
- package/mayo-c/apps/example.c +151 -0
- package/mayo-c/apps/example_nistapi.c +124 -0
- package/mayo-c/include/mayo.h +442 -0
- package/mayo-c/include/mem.h +25 -0
- package/mayo-c/include/randombytes.h +31 -0
- package/mayo-c/scripts/contstants.py +141 -0
- package/mayo-c/scripts/find_irred_poly.sage +39 -0
- package/mayo-c/src/AVX2/arithmetic_common.h +159 -0
- package/mayo-c/src/AVX2/echelon_form.h +91 -0
- package/mayo-c/src/AVX2/echelon_form_loop.h +58 -0
- package/mayo-c/src/AVX2/shuffle_arithmetic.h +442 -0
- package/mayo-c/src/CMakeLists.txt +98 -0
- package/mayo-c/src/arithmetic.c +128 -0
- package/mayo-c/src/arithmetic.h +124 -0
- package/mayo-c/src/common/aes128ctr.c +293 -0
- package/mayo-c/src/common/aes_c.c +741 -0
- package/mayo-c/src/common/aes_ctr.h +32 -0
- package/mayo-c/src/common/aes_neon.c +201 -0
- package/mayo-c/src/common/debug_bench_tools.h +69 -0
- package/mayo-c/src/common/fips202.c +1093 -0
- package/mayo-c/src/common/fips202.h +12 -0
- package/mayo-c/src/common/mem.c +19 -0
- package/mayo-c/src/common/randombytes_ctrdrbg.c +141 -0
- package/mayo-c/src/common/randombytes_system.c +399 -0
- package/mayo-c/src/generic/arithmetic_dynamic.h +68 -0
- package/mayo-c/src/generic/arithmetic_fixed.h +84 -0
- package/mayo-c/src/generic/echelon_form.h +152 -0
- package/mayo-c/src/generic/ef_inner_loop.h +56 -0
- package/mayo-c/src/generic/generic_arithmetic.h +294 -0
- package/mayo-c/src/mayo.c +675 -0
- package/mayo-c/src/mayo_1/api.c +46 -0
- package/mayo-c/src/mayo_1/api.h +43 -0
- package/mayo-c/src/mayo_2/api.c +46 -0
- package/mayo-c/src/mayo_2/api.h +43 -0
- package/mayo-c/src/mayo_3/api.c +46 -0
- package/mayo-c/src/mayo_3/api.h +43 -0
- package/mayo-c/src/mayo_5/api.c +46 -0
- package/mayo-c/src/mayo_5/api.h +43 -0
- package/mayo-c/src/neon/arithmetic_common.h +132 -0
- package/mayo-c/src/neon/echelon_form.h +55 -0
- package/mayo-c/src/neon/echelon_form_loop.h +58 -0
- package/mayo-c/src/neon/shuffle_arithmetic.h +462 -0
- package/mayo-c/src/params.c +42 -0
- package/mayo-c/src/simple_arithmetic.h +138 -0
- package/mayo-c/test/CMakeLists.txt +51 -0
- package/mayo-c/test/bench.c +166 -0
- package/mayo-c/test/m1cycles.c +155 -0
- package/mayo-c/test/m1cycles.h +13 -0
- package/mayo-c/test/test_kat.c +271 -0
- package/mayo-c/test/test_mayo.c +139 -0
- package/mayo-c/test/test_sample_solution.c +75 -0
- package/mayo-c/test/test_various.c +680 -0
- package/package.json +39 -0
- package/publish.bat +22 -0
- package/readme.md +80 -0
- package/test/test.mjs +42 -0
package/publish.bat
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
@echo off
|
|
2
|
+
echo Building qsafe-mayo-wasm...
|
|
3
|
+
|
|
4
|
+
call npm run build:min
|
|
5
|
+
if errorlevel 1 (
|
|
6
|
+
echo Build failed. Aborting.
|
|
7
|
+
pause
|
|
8
|
+
exit /b 1
|
|
9
|
+
)
|
|
10
|
+
echo.
|
|
11
|
+
|
|
12
|
+
set /p PUBLISH="Publish to npm? (y/n): "
|
|
13
|
+
if /i not "%PUBLISH%"=="y" (
|
|
14
|
+
echo Build complete. Nothing published.
|
|
15
|
+
pause
|
|
16
|
+
exit /b 0
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
call npm version patch
|
|
20
|
+
call npm publish --access public
|
|
21
|
+
echo Done.
|
|
22
|
+
pause
|
package/readme.md
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# qsafe-mayo-wasm 🔐
|
|
2
|
+
|
|
3
|
+
> Post-quantum signatures in WebAssembly — MAYO-1 & MAYO-2, browser & Node.js ready
|
|
4
|
+
|
|
5
|
+
JavaScript/WASM wrapper around [MAYO-C](https://github.com/PQCMayo/MAYO-C), a NIST post-quantum signature scheme finalist. Ships as two self-contained single-file modules with an unified JS API.
|
|
6
|
+
|
|
7
|
+
## Links
|
|
8
|
+
|
|
9
|
+
- **NPM:** coming soon
|
|
10
|
+
- **MAYO spec:** [pqmayo.org](https://pqmayo.org)
|
|
11
|
+
- **MAYO-C source:** [github.com/PQCMayo/MAYO-C](https://github.com/PQCMayo/MAYO-C)
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
```bash
|
|
15
|
+
npm install qsafe-mayo-wasm
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
```js
|
|
20
|
+
import { MayoSigner } from 'qsafe-mayo-wasm';
|
|
21
|
+
|
|
22
|
+
const mayo = await MayoSigner.create('mayo1'); // or 'mayo2'
|
|
23
|
+
|
|
24
|
+
// Generate a deterministic keypair from a 24-byte seed
|
|
25
|
+
const { publicKey, secretKey } = mayo.keypairFromSeed(seed);
|
|
26
|
+
|
|
27
|
+
// Sign
|
|
28
|
+
const signature = mayo.sign(msg);
|
|
29
|
+
|
|
30
|
+
// Verify (stateless — no secret key needed)
|
|
31
|
+
const valid = mayo.verify(msg, signature, publicKey);
|
|
32
|
+
|
|
33
|
+
// Load an existing secret key
|
|
34
|
+
mayo.loadSecretKey(secretKey);
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## API
|
|
38
|
+
|
|
39
|
+
### `MayoSigner.create(variant?)` → `Promise<MayoSigner>`
|
|
40
|
+
Factory method. Loads the WASM module and returns a ready instance.
|
|
41
|
+
- `variant`: `'mayo1'` (default) or `'mayo2'`
|
|
42
|
+
|
|
43
|
+
### `new MayoSigner(variant?)` + `await signer.init()`
|
|
44
|
+
Alternative if you need manual lifecycle control.
|
|
45
|
+
|
|
46
|
+
### `keypairFromSeed(seed, storeSecretKey?)` → `Keypair | null`
|
|
47
|
+
Derives a keypair deterministically from a 24-byte `Uint8Array` seed.
|
|
48
|
+
Stores the secret key internally by default (`storeSecretKey = true`).
|
|
49
|
+
|
|
50
|
+
### `loadSecretKey(secretKey)`
|
|
51
|
+
Loads an existing secret key for subsequent `sign()` calls.
|
|
52
|
+
|
|
53
|
+
### `sign(msg)` → `Uint8Array | null`
|
|
54
|
+
Signs a message using the loaded secret key. Returns `null` on failure.
|
|
55
|
+
|
|
56
|
+
### `verify(msg, signature, publicKey)` → `boolean`
|
|
57
|
+
Verifies a signature. Stateless — no secret key required.
|
|
58
|
+
|
|
59
|
+
## Key sizes
|
|
60
|
+
|
|
61
|
+
| Variant | Secret key | Public key | Signature |
|
|
62
|
+
|---------|-----------|------------|-----------|
|
|
63
|
+
| MAYO-1 | 24 B | 1420 B | 454 B |
|
|
64
|
+
| MAYO-2 | 24 B | 4912 B | 186 B |
|
|
65
|
+
|
|
66
|
+
## Building from source
|
|
67
|
+
|
|
68
|
+
Requires [Emscripten](https://emscripten.org/docs/getting_started/downloads.html).
|
|
69
|
+
```powershell
|
|
70
|
+
git clone --recurse-submodules https://github.com/you/qsafe-mayo-wasm
|
|
71
|
+
.\build_mayo1.ps1 # → dist/mayo1.js
|
|
72
|
+
.\build_mayo2.ps1 # → dist/mayo2.js
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
WASM is inlined in each `.js` file (`SINGLE_FILE=1`) — no separate `.wasm` asset needed.
|
|
76
|
+
|
|
77
|
+
## License
|
|
78
|
+
|
|
79
|
+
Apache-2.0 — see [LICENSE](./LICENSE).
|
|
80
|
+
MAYO-C is also Apache-2.0 — see [mayo-c/LICENSE](./mayo-c/LICENSE).
|
package/test/test.mjs
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { MayoSigner } from '../dist/mayo_api.js';
|
|
2
|
+
|
|
3
|
+
const msg = new TextEncoder().encode('hello qsafe');
|
|
4
|
+
|
|
5
|
+
/** @param {'mayo1'|'mayo2'} variant */
|
|
6
|
+
async function testVariant(variant) {
|
|
7
|
+
const mayo = await MayoSigner.create(variant);
|
|
8
|
+
const seed1 = new Uint8Array(24).fill(1);
|
|
9
|
+
const seed2 = new Uint8Array(24).fill(2);
|
|
10
|
+
|
|
11
|
+
// -- Keypair determinism --
|
|
12
|
+
const kp1a = mayo.keypairFromSeed(seed1);
|
|
13
|
+
const kp1b = mayo.keypairFromSeed(seed1, false); // no need to store twice
|
|
14
|
+
console.assert(kp1a !== null, `${variant} keypair should not be null`);
|
|
15
|
+
console.assert(kp1a.publicKey.every((b, i) => b === kp1b.publicKey[i]), `${variant} keypair should be deterministic`);
|
|
16
|
+
console.log(`✓ ${variant} keypair determinism OK`);
|
|
17
|
+
|
|
18
|
+
// -- Sign/verify roundtrip (secretKey stored from kp1a) --
|
|
19
|
+
const signature = mayo.sign(msg);
|
|
20
|
+
console.assert(signature !== null, `${variant} signature should not be null`);
|
|
21
|
+
console.assert(mayo.verify(msg, signature, kp1a.publicKey), `${variant} signature should verify`);
|
|
22
|
+
console.log(`✓ ${variant} sign/verify OK`);
|
|
23
|
+
|
|
24
|
+
// -- loadSecretKey --
|
|
25
|
+
const mayo2 = await MayoSigner.create(variant);
|
|
26
|
+
mayo2.loadSecretKey(kp1a.secretKey);
|
|
27
|
+
const signature2 = mayo2.sign(msg);
|
|
28
|
+
console.assert(mayo2.verify(msg, signature2, kp1a.publicKey), `${variant} loadSecretKey + sign should verify`);
|
|
29
|
+
console.log(`✓ ${variant} loadSecretKey OK`);
|
|
30
|
+
|
|
31
|
+
// -- Cross-key rejection --
|
|
32
|
+
const kp2 = mayo.keypairFromSeed(seed2); // stores seed2 secretKey
|
|
33
|
+
console.assert(!mayo2.verify(msg, signature, kp2.publicKey), `${variant} signature should not verify with wrong key`);
|
|
34
|
+
console.log(`✓ ${variant} cross-key rejection OK`);
|
|
35
|
+
|
|
36
|
+
console.log(`✓ ${variant} all checks passed\n`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
await testVariant('mayo1');
|
|
40
|
+
await testVariant('mayo2');
|
|
41
|
+
|
|
42
|
+
console.log('All tests passed.');
|