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 +44 -2
- package/dist/index.js +25 -64
- package/dist/index.js.map +1 -1
- package/dist/sqisign-accel-worker.js +3 -30
- package/dist/sqisign-accel-worker.js.map +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,8 +4,44 @@
|
|
|
4
4
|
[](https://antonymott.github.io/quantum-resistant-rustykey/)
|
|
5
5
|

|
|
6
6
|
|
|
7
|
-
TypeScript-first **WebAssembly
|
|
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
|
-
|
|
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
|
|
319
|
+
return data.toBase64({
|
|
320
|
+
alphabet: "base64url",
|
|
321
|
+
omitPadding: true
|
|
322
|
+
});
|
|
323
323
|
}
|
|
324
324
|
function fromBase64url$2(base64url) {
|
|
325
|
-
|
|
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
|
-
|
|
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
|
|
960
|
+
return data.toBase64({
|
|
961
|
+
alphabet: "base64url",
|
|
962
|
+
omitPadding: true
|
|
963
|
+
});
|
|
966
964
|
}
|
|
967
965
|
function fromBase64url$1(base64url) {
|
|
968
|
-
|
|
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
|
-
|
|
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
|
|
1601
|
+
return data.toBase64({
|
|
1602
|
+
alphabet: "base64url",
|
|
1603
|
+
omitPadding: true
|
|
1604
|
+
});
|
|
1609
1605
|
}
|
|
1610
1606
|
function fromBase64url(base64url) {
|
|
1611
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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;
|