quantum-resistant-rustykey 0.13.5 → 0.13.7

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/README.md CHANGED
@@ -4,8 +4,44 @@
4
4
  [![docs](https://img.shields.io/badge/docs-GitHub%20Pages-1a5f4a)](https://antonymott.github.io/quantum-resistant-rustykey/)
5
5
  ![Node v26.7.0](https://img.shields.io/badge/node-v26.7.0-blue.svg)
6
6
 
7
- TypeScript-first **WebAssembly post-quantum** crypto for Node and the browser — SQIsign, ML-DSA, FN-DSA, SLH-DSA, ML-KEM.
8
- RustyKey® is a **FIDO Alliance** member.
7
+ TypeScript-first **WebAssembly and WebGPU\* quantum-resistant** crypto for Node and browser — SQIsign, ML-DSA, FN-DSA, SLH-DSA, ML-KEM.
8
+ RustyKey® is a **FIDO® Alliance** member.
9
+
10
+ > \*Only the SQIsign algorithm ships WebGPU-accelerated variants, at all three security
11
+ > levels (L5, L3, L1). We introduced them experimentally, since several of SQIsign's
12
+ > isogeny computations are GPU-parallelizable, and offloading them to WebGPU
13
+ > meaningfully speeds up signature creation over the WebAssembly path (itself already
14
+ > faster than plain JS) — typically 1.25x–1.8x, depending on security level and GPU.
15
+ >
16
+ > **⚠️ Treat WebGPU variants as experimental — no production use at all — until v1.0.0.**
17
+ > Combining WebAssembly and WebGPU with the inherent mathematical properties of isogenies
18
+ > shifts the most likely attack vectors toward algorithmic side-channels, GPU
19
+ > memory-architecture quirks, and memory-safety mismatches at the Wasm/WGSL translation
20
+ > boundary (full analysis: `docs/security/threat-model.md`). This risk is more likely to
21
+ > affect the WebGPU-accelerated path — the WebAssembly-only implementation is less likely
22
+ > affected by these GPU-specific vectors.
23
+ >
24
+ > These WebGPU variants are **browser-only** and require the page to be served with
25
+ > COOP and COEP headers so that `self.crossOriginIsolated === true`. Without cross-origin
26
+ > isolation, WebGPU compute cannot be used at all — the library detects this and
27
+ > automatically falls back to the WebAssembly implementation, which is also the
28
+ > default (and only) backend in Node.
29
+ >
30
+ > **Do not patch out or bypass the `crossOriginIsolated` check to force WebGPU execution
31
+ > on a non-isolated page.** That check is not a convenience gate — it enforces the same
32
+ > isolation boundary that limits the cross-tab cache-timing and high-resolution-timer
33
+ > attacks this package's WebGPU path is otherwise exposed to. The same applies if your
34
+ > own application runs keygen and other, untrusted code in the same tab, worker, or
35
+ > execution context even with the check fully intact — that is not isolation, it's just
36
+ > two things sharing a room. Builds or integrations that do either of these fall outside
37
+ > this package's threat model and support/disclosure scope — key-recovery incidents on
38
+ > such setups should not be attributed to the maintained package's supported
39
+ > configuration.
40
+ >
41
+ > **Think you've found a genuine key-recovery or forgery issue under a properly isolated
42
+ > configuration?** Please report it per `SECURITY.md` before sharing it publicly or with
43
+ > standards bodies — it defines what's in scope and includes a safe-harbor commitment for
44
+ > good-faith research.
9
45
 
10
46
  ```bash
11
47
  pnpm i quantum-resistant-rustykey@latest
@@ -13,6 +49,12 @@ pnpm i quantum-resistant-rustykey@latest
13
49
 
14
50
  TypeScript types are included (`dist/index.d.ts`) — no `@types/quantum-resistant-rustykey`.
15
51
 
52
+ ### NIST™ approval status: quantum resistant algorithms
53
+ - ML-DSA, FN-DSA, SLH-DSA, ML-KEM [NIST™ approved](https://www.nist.gov/news-events/news/2024/08/nist-releases-first-3-finalized-post-quantum-encryption-standards)
54
+ - SQIsign [NIST™ NOT YET approved, advanced to round 3](https://csrc.nist.gov/projects/pqc-dig-sig/round-3-additional-signatures)
55
+
56
+ A model running in the browser eventually becomes a sequence of GPU operations: matrix multiplications, normalizations, convolutions, attention primitives, quantization operations, data-layout transformations, and many more. WebGPU makes these operations available across modern browsers through a portable API, while WGSL provides a common language for the shaders that execute them.
57
+
16
58
  **Docs:** [antonymott.github.io/quantum-resistant-rustykey](https://antonymott.github.io/quantum-resistant-rustykey/)
17
59
  **Live testbed:** [pqc.rustykey.me](https://pqc.rustykey.me)
18
60
  **License:** ISC
package/dist/index.js CHANGED
@@ -39,10 +39,7 @@ var wasm_module_default = (() => {
39
39
  var wasmBinary;
40
40
  if (typeof WebAssembly != "object") abort("no native wasm support detected");
41
41
  function intArrayFromBase64(s) {
42
- var decoded = atob(s);
43
- var bytes = new Uint8Array(decoded.length);
44
- for (var i = 0; i < decoded.length; ++i) bytes[i] = decoded.charCodeAt(i);
45
- return bytes;
42
+ return Uint8Array.fromBase64(s);
46
43
  }
47
44
  function tryParseAsDataURI(filename) {
48
45
  if (!isDataURI(filename)) return;
@@ -319,12 +316,13 @@ function _isSupportedCryptoKey$2(key) {
319
316
  return key instanceof CryptoKey && keyIdKey$2 in key && key[keyIdKey$2] == noClone$2 && internalKeyData$2.has(key);
320
317
  }
321
318
  function toBase64url$2(data) {
322
- return btoa(String.fromCharCode(...data)).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
319
+ return data.toBase64({
320
+ alphabet: "base64url",
321
+ omitPadding: true
322
+ });
323
323
  }
324
324
  function fromBase64url$2(base64url) {
325
- const base64 = base64url.replace(/-/g, "+").replace(/_/g, "/");
326
- const binary = atob(base64 + "===".slice((base64.length + 3) % 4));
327
- return Uint8Array.from(binary, (c) => c.charCodeAt(0));
325
+ return Uint8Array.fromBase64(base64url, { alphabet: "base64url" });
328
326
  }
329
327
  var PUBLICKEY_BYTES$2 = 1184;
330
328
  var SECRETKEY_BYTES$2 = 2400;
@@ -682,10 +680,7 @@ var wasm_module_512_default = (() => {
682
680
  var wasmBinary;
683
681
  if (typeof WebAssembly != "object") abort("no native wasm support detected");
684
682
  function intArrayFromBase64(s) {
685
- var decoded = atob(s);
686
- var bytes = new Uint8Array(decoded.length);
687
- for (var i = 0; i < decoded.length; ++i) bytes[i] = decoded.charCodeAt(i);
688
- return bytes;
683
+ return Uint8Array.fromBase64(s);
689
684
  }
690
685
  function tryParseAsDataURI(filename) {
691
686
  if (!isDataURI(filename)) return;
@@ -962,12 +957,13 @@ function _isSupportedCryptoKey$1(key) {
962
957
  return key instanceof CryptoKey && keyIdKey$1 in key && key[keyIdKey$1] == noClone$1 && internalKeyData$1.has(key);
963
958
  }
964
959
  function toBase64url$1(data) {
965
- return btoa(String.fromCharCode(...data)).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
960
+ return data.toBase64({
961
+ alphabet: "base64url",
962
+ omitPadding: true
963
+ });
966
964
  }
967
965
  function fromBase64url$1(base64url) {
968
- const base64 = base64url.replace(/-/g, "+").replace(/_/g, "/");
969
- const binary = atob(base64 + "===".slice((base64.length + 3) % 4));
970
- return Uint8Array.from(binary, (c) => c.charCodeAt(0));
966
+ return Uint8Array.fromBase64(base64url, { alphabet: "base64url" });
971
967
  }
972
968
  var PUBLICKEY_BYTES$1 = 800;
973
969
  var SECRETKEY_BYTES$1 = 1632;
@@ -1325,10 +1321,7 @@ var wasm_module_1024_default = (() => {
1325
1321
  var wasmBinary;
1326
1322
  if (typeof WebAssembly != "object") abort("no native wasm support detected");
1327
1323
  function intArrayFromBase64(s) {
1328
- var decoded = atob(s);
1329
- var bytes = new Uint8Array(decoded.length);
1330
- for (var i = 0; i < decoded.length; ++i) bytes[i] = decoded.charCodeAt(i);
1331
- return bytes;
1324
+ return Uint8Array.fromBase64(s);
1332
1325
  }
1333
1326
  function tryParseAsDataURI(filename) {
1334
1327
  if (!isDataURI(filename)) return;
@@ -1605,12 +1598,13 @@ function _isSupportedCryptoKey(key) {
1605
1598
  return key instanceof CryptoKey && keyIdKey in key && key[keyIdKey] == noClone && internalKeyData.has(key);
1606
1599
  }
1607
1600
  function toBase64url(data) {
1608
- return btoa(String.fromCharCode(...data)).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
1601
+ return data.toBase64({
1602
+ alphabet: "base64url",
1603
+ omitPadding: true
1604
+ });
1609
1605
  }
1610
1606
  function fromBase64url(base64url) {
1611
- const base64 = base64url.replace(/-/g, "+").replace(/_/g, "/");
1612
- const binary = atob(base64 + "===".slice((base64.length + 3) % 4));
1613
- return Uint8Array.from(binary, (c) => c.charCodeAt(0));
1607
+ return Uint8Array.fromBase64(base64url, { alphabet: "base64url" });
1614
1608
  }
1615
1609
  var PUBLICKEY_BYTES = 1568;
1616
1610
  var SECRETKEY_BYTES = 3168;
@@ -2009,10 +2003,7 @@ var falcon_512_module_default = (() => {
2009
2003
  var wasmBinary;
2010
2004
  if (typeof WebAssembly != "object") abort("no native wasm support detected");
2011
2005
  function intArrayFromBase64(s) {
2012
- var decoded = atob(s);
2013
- var bytes = new Uint8Array(decoded.length);
2014
- for (var i = 0; i < decoded.length; ++i) bytes[i] = decoded.charCodeAt(i);
2015
- return bytes;
2006
+ return Uint8Array.fromBase64(s);
2016
2007
  }
2017
2008
  function tryParseAsDataURI(filename) {
2018
2009
  if (!isDataURI(filename)) return;
@@ -2256,10 +2247,7 @@ var falcon_1024_module_default = (() => {
2256
2247
  var wasmBinary;
2257
2248
  if (typeof WebAssembly != "object") abort("no native wasm support detected");
2258
2249
  function intArrayFromBase64(s) {
2259
- var decoded = atob(s);
2260
- var bytes = new Uint8Array(decoded.length);
2261
- for (var i = 0; i < decoded.length; ++i) bytes[i] = decoded.charCodeAt(i);
2262
- return bytes;
2250
+ return Uint8Array.fromBase64(s);
2263
2251
  }
2264
2252
  function tryParseAsDataURI(filename) {
2265
2253
  if (!isDataURI(filename)) return;
@@ -2608,10 +2596,7 @@ var mldsa_65_module_default = (() => {
2608
2596
  var wasmBinary;
2609
2597
  if (typeof WebAssembly != "object") abort("no native wasm support detected");
2610
2598
  function intArrayFromBase64(s) {
2611
- var decoded = atob(s);
2612
- var bytes = new Uint8Array(decoded.length);
2613
- for (var i = 0; i < decoded.length; ++i) bytes[i] = decoded.charCodeAt(i);
2614
- return bytes;
2599
+ return Uint8Array.fromBase64(s);
2615
2600
  }
2616
2601
  function tryParseAsDataURI(filename) {
2617
2602
  if (!isDataURI(filename)) return;
@@ -2845,10 +2830,7 @@ var mldsa_87_module_default = (() => {
2845
2830
  var wasmBinary;
2846
2831
  if (typeof WebAssembly != "object") abort("no native wasm support detected");
2847
2832
  function intArrayFromBase64(s) {
2848
- var decoded = atob(s);
2849
- var bytes = new Uint8Array(decoded.length);
2850
- for (var i = 0; i < decoded.length; ++i) bytes[i] = decoded.charCodeAt(i);
2851
- return bytes;
2833
+ return Uint8Array.fromBase64(s);
2852
2834
  }
2853
2835
  function tryParseAsDataURI(filename) {
2854
2836
  if (!isDataURI(filename)) return;
@@ -3307,14 +3289,7 @@ var sqisign_lvl1_module_default = (() => {
3307
3289
  var wasmBinary;
3308
3290
  if (typeof WebAssembly != "object") abort("no native wasm support detected");
3309
3291
  function intArrayFromBase64(s) {
3310
- if (typeof ENVIRONMENT_IS_NODE != "undefined" && ENVIRONMENT_IS_NODE) {
3311
- var buf = Buffer.from(s, "base64");
3312
- return new Uint8Array(buf.buffer, buf.byteOffset, buf.length);
3313
- }
3314
- var decoded = atob(s);
3315
- var bytes = new Uint8Array(decoded.length);
3316
- for (var i = 0; i < decoded.length; ++i) bytes[i] = decoded.charCodeAt(i);
3317
- return bytes;
3292
+ return Uint8Array.fromBase64(s);
3318
3293
  }
3319
3294
  function tryParseAsDataURI(filename) {
3320
3295
  if (!isDataURI(filename)) return;
@@ -3679,14 +3654,7 @@ var sqisign_lvl3_module_default = (() => {
3679
3654
  var wasmBinary;
3680
3655
  if (typeof WebAssembly != "object") abort("no native wasm support detected");
3681
3656
  function intArrayFromBase64(s) {
3682
- if (typeof ENVIRONMENT_IS_NODE != "undefined" && ENVIRONMENT_IS_NODE) {
3683
- var buf = Buffer.from(s, "base64");
3684
- return new Uint8Array(buf.buffer, buf.byteOffset, buf.length);
3685
- }
3686
- var decoded = atob(s);
3687
- var bytes = new Uint8Array(decoded.length);
3688
- for (var i = 0; i < decoded.length; ++i) bytes[i] = decoded.charCodeAt(i);
3689
- return bytes;
3657
+ return Uint8Array.fromBase64(s);
3690
3658
  }
3691
3659
  function tryParseAsDataURI(filename) {
3692
3660
  if (!isDataURI(filename)) return;
@@ -4051,14 +4019,7 @@ var sqisign_lvl5_module_default = (() => {
4051
4019
  var wasmBinary;
4052
4020
  if (typeof WebAssembly != "object") abort("no native wasm support detected");
4053
4021
  function intArrayFromBase64(s) {
4054
- if (typeof ENVIRONMENT_IS_NODE != "undefined" && ENVIRONMENT_IS_NODE) {
4055
- var buf = Buffer.from(s, "base64");
4056
- return new Uint8Array(buf.buffer, buf.byteOffset, buf.length);
4057
- }
4058
- var decoded = atob(s);
4059
- var bytes = new Uint8Array(decoded.length);
4060
- for (var i = 0; i < decoded.length; ++i) bytes[i] = decoded.charCodeAt(i);
4061
- return bytes;
4022
+ return Uint8Array.fromBase64(s);
4062
4023
  }
4063
4024
  function tryParseAsDataURI(filename) {
4064
4025
  if (!isDataURI(filename)) return;