quantum-resistant-rustykey 0.7.9 → 0.8.1

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 (2) hide show
  1. package/README.md +144 -12
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -14,15 +14,14 @@ npm i quantum-resistant-rustykey
14
14
 
15
15
  - ***Recommendation***: Await v1.0.0 (following security audit) for production/regulated deployment.
16
16
  - includes NIST approved as well as riskier NIST 'on-ramp' variants eg SQISign
17
- - *signature algorithms:*
18
- - *FN-DSA (Falcon-512, Falcon-1024)*
19
- - *ML-DSA (Dilithium variants)*
20
- - *SQISign*
21
- - module-lattice-based key-encapsulation mechanism
22
- - **ML-KEM-512**, **ML-KEM-768**, and **ML-KEM-1024** using the same stack: [mlkem-native](https://github.com/pq-code-package/mlkem-native) built with **Emscripten**.
17
+ - **ML-DSA** (ML-DSA-65, ML-DSA-87)
18
+ - **FN-DSA** (FN-DSA-512, FN-DSA-1024)
19
+ - **SQIsign** (Level 1, Level 3, Level 5)
20
+ - **ML-KEM** (512, 768, 1024) using [mlkem-native](https://github.com/pq-code-package/mlkem-native).
23
21
 
24
22
  ### NOTE: Why we support SQISign when it is 'NIST-on-ramp' only
25
23
  *TLDR; to help hurdle the "silent" barrier to post-quantum adoption: 1024-byte buffer limit in many existing FIDO2/WebAuthn implementations*
24
+ - please see our IETF standards track draft for inclusion of SQISign [cose-sqisign](https://www.ietf.org/archive/id/draft-mott-cose-sqisign-00.html)
26
25
 
27
26
  #### WebAuthn PQC Signature size constraints
28
27
  Dilithium variants, and Falcon-1024 are physical incompatibile with millions of existing FIDO2/WebAuthn authenticators that rely on the CTAP2 1024-byte buffer limit.
@@ -202,6 +201,78 @@ run().catch((err) => {
202
201
  });
203
202
  ```
204
203
 
204
+ ## Signatures
205
+
206
+ All signature variants expose the same API (`keypair()`, `sign()`, `verify()`, `buffer_to_string()`).
207
+
208
+ ### Node.js / backend (SQISign I, SQISign V, FN-DSA-512)
209
+
210
+ ```typescript
211
+ import {
212
+ loadSqisignLvl1,
213
+ loadSqisignLvl5,
214
+ loadFnDsa512,
215
+ } from "quantum-resistant-rustykey";
216
+
217
+ async function demo() {
218
+ const message = new TextEncoder().encode("RustyKey signature test");
219
+
220
+ const variants = [
221
+ ["SQIsign-I", await loadSqisignLvl1()],
222
+ ["SQIsign-V", await loadSqisignLvl5()],
223
+ ["FN-DSA-512", await loadFnDsa512()],
224
+ ] as const;
225
+
226
+ for (const [name, signer] of variants) {
227
+ const kp = signer.keypair();
228
+ const pk = await kp.get("public_key");
229
+ const sk = await kp.get("private_key");
230
+ const sig = await signer.sign(message, sk);
231
+ const ok = await signer.verify(sig, message, pk);
232
+ console.log(`${name}:`, ok ? "OK" : "FAIL");
233
+ }
234
+ }
235
+
236
+ demo().catch(console.error);
237
+ ```
238
+
239
+ ### Browser / frontend (SQISign I, SQISign V, FN-DSA-512)
240
+
241
+ ```typescript
242
+ import {
243
+ loadSqisignLvl1,
244
+ loadSqisignLvl5,
245
+ loadFnDsa512,
246
+ } from "quantum-resistant-rustykey";
247
+
248
+ const out = document.querySelector("#output") as HTMLPreElement;
249
+
250
+ async function runSignatures() {
251
+ const message = new TextEncoder().encode("hello from browser signatures");
252
+ const variants = [
253
+ ["SQIsign-I", await loadSqisignLvl1()],
254
+ ["SQIsign-V", await loadSqisignLvl5()],
255
+ ["FN-DSA-512", await loadFnDsa512()],
256
+ ] as const;
257
+
258
+ const lines: string[] = [];
259
+ for (const [name, signer] of variants) {
260
+ const kp = signer.keypair();
261
+ const pk = await kp.get("public_key");
262
+ const sk = await kp.get("private_key");
263
+ const sig = await signer.sign(message, sk);
264
+ const ok = await signer.verify(sig, message, pk);
265
+ lines.push(`${name}: ${ok ? "verify OK" : "verify FAILED"}`);
266
+ }
267
+ out.textContent = lines.join("\n");
268
+ }
269
+
270
+ runSignatures().catch((err) => {
271
+ console.error(err);
272
+ out.textContent = "signature demo failed";
273
+ });
274
+ ```
275
+
205
276
  Security note for web apps:
206
277
  - never store private keys in `localStorage`/`sessionStorage`
207
278
  - prefer HTTPS + short-lived keys
@@ -249,16 +320,41 @@ pnpm build
249
320
 
250
321
  - Run `pnpm test` for ML-KEM-512 / 768 / 1024 round-trips.
251
322
 
252
- ## Browser example (local)
323
+ ### Digital Signatures (Node.js & Frontend)
253
324
 
254
- A Vite app under `examples/browser-demo` links this package from the workspace. From the repo root:
325
+ All signature algorithms (**FN-DSA**, **ML-DSA**, and **SQIsign**) share a common interface.
255
326
 
256
- ```bash
257
- pnpm build
258
- pnpm example:browser
327
+ ```typescript
328
+ import {
329
+ loadFnDsa512,
330
+ loadMlDsa3,
331
+ loadSqisignLvl1
332
+ } from "quantum-resistant-rustykey";
333
+
334
+ async function main() {
335
+ // 1. Load the algorithm (e.g., FN-DSA-512)
336
+ const fnDsa = await loadFnDsa512();
337
+
338
+ // 2. Generate a keypair
339
+ const kp = fnDsa.keypair();
340
+ const publicKey = await kp.get("public_key");
341
+ const privateKey = await kp.get("private_key");
342
+
343
+ // 3. Sign a message
344
+ const message = "Authored by RustyKey";
345
+ const signature = await fnDsa.sign(message, privateKey);
346
+ console.log("Signature (hex):", fnDsa.buffer_to_string(signature));
347
+
348
+ // 4. Verify the signature
349
+ const isValid = await fnDsa.verify(signature, message, publicKey);
350
+ console.log("Is signature valid?", isValid);
351
+ }
259
352
  ```
260
353
 
261
- See `examples/browser-demo/README.md` for details.
354
+ > [!NOTE]
355
+ > **SQIsign Performance**: Level 1 signing is extremely CPU-intensive (can take seconds to minutes depending on hardware). It is recommended for "sign-once, verify-many" scenarios like certificates or firmware updates.
356
+
357
+ ## Browser example (local)
262
358
 
263
359
  ## Project Structure
264
360
 
@@ -279,6 +375,42 @@ This implementation includes patches to withstand side-channel attacks. For more
279
375
 
280
376
  ISC
281
377
 
378
+
379
+ ## Performance Metrics
380
+
381
+ Measured on a standard development environment (Node.js/WASM). Individual results may vary based on hardware and runtime overhead.
382
+
383
+ | Algorithm | KeyGen (ms) | Sign (ms) | Verify (ms) |
384
+ | :--- | :---: | :---: | :---: |
385
+ | **FN-DSA-512** | 8.13 | 0.74 | 0.78 |
386
+ | **FN-DSA-1024** | 25.62 | 1.25 | 0.24 |
387
+ | **ML-DSA-3 (Level 3)** | 0.22 | 0.45 | 0.25 |
388
+ | **ML-DSA-5 (Level 5)** | 0.33 | 0.63 | 0.34 |
389
+ | **SQIsign L1** | 99.95 | 534.41 | 15.35 |
390
+
391
+ ---
392
+
393
+ ## Known Answer Tests (KAT)
394
+
395
+ To ensure implementation correctness, our WASM build is verified against official NIST and reference test vectors.
396
+
397
+ ### ML-DSA-3 (Level 3 / Dilithium-3)
398
+ * **Msg**: `6dbbc4375136df3b07f7c70e639e223e`
399
+ * **PK**: `e50d03fff3b3a70961abbb92a390008dec1283f603f50cdbaaa3d00bd659bc767c3f...`
400
+ * **Sig**: `a0c1af32f9ba4e4beea3016b96d1c780e8b5e020bb07c24478dbdd0ec875666b5a...`
401
+
402
+ ### ML-DSA-5 (Level 5 / Dilithium-5)
403
+ * **Msg**: `6dbbc4375136df3b07f7c70e639e223e`
404
+ * **PK**: `bc89b367d4288f47c71a74679d0fcffbe041de41b5da2f5fc66d8e28c589949404...`
405
+ * **Sig**: `47dc5764266841c1af3073fcead6a13d372979e6cca0b2952b349915f54ef66312...`
406
+
407
+ ### SQIsign Level 1
408
+ * **Msg**: `d81c4d8d734fcbfbeade3d3f8a039faa2a2c9957e835ad55b22e75bf57bb556ac8`
409
+ * **PK**: `07CCD21425136F6E865E497D2D4D208F0054AD81372066E817480787AAF7B2029...`
410
+ * **Sig**: `84228651f271b0f39f2f19f2e8718f31ed3365ac9e5cb303afe663d0cfc11f0455...`
411
+
412
+ *Full byte-perfect vectors are included in the `src/*.test.ts` files.*
413
+
282
414
  ## Funding
283
415
 
284
416
  This project was generously supported by:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quantum-resistant-rustykey",
3
- "version": "0.7.9",
3
+ "version": "0.8.1",
4
4
  "description": "WebAssembly post-quantum-resistant tools for web",
5
5
  "author": "Antony R Mott <a@auditcanary.com> (https://rustykey.app)",
6
6
  "license": "ISC",