leviathan-crypto 2.1.0 → 3.0.0
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/CLAUDE.md +86 -443
- package/README.md +198 -65
- package/dist/aes/aes-cbc.d.ts +40 -0
- package/dist/aes/aes-cbc.js +158 -0
- package/dist/aes/aes-ctr.d.ts +50 -0
- package/dist/aes/aes-ctr.js +141 -0
- package/dist/aes/aes-gcm-siv.d.ts +67 -0
- package/dist/aes/aes-gcm-siv.js +217 -0
- package/dist/aes/aes-gcm.d.ts +61 -0
- package/dist/aes/aes-gcm.js +226 -0
- package/dist/aes/cipher-suite.d.ts +21 -0
- package/dist/aes/cipher-suite.js +179 -0
- package/dist/aes/embedded.d.ts +1 -0
- package/dist/aes/embedded.js +26 -0
- package/dist/aes/generator.d.ts +14 -0
- package/dist/aes/generator.js +103 -0
- package/dist/aes/index.d.ts +58 -0
- package/dist/aes/index.js +125 -0
- package/dist/aes/ops.d.ts +60 -0
- package/dist/aes/ops.js +164 -0
- package/dist/aes/pool-worker.d.ts +1 -0
- package/dist/aes/pool-worker.js +92 -0
- package/dist/aes/types.d.ts +1 -0
- package/dist/aes/types.js +23 -0
- package/dist/aes.wasm +0 -0
- package/dist/blake3/embedded.d.ts +1 -0
- package/dist/blake3/embedded.js +26 -0
- package/dist/blake3/index.d.ts +143 -0
- package/dist/blake3/index.js +620 -0
- package/dist/blake3/types.d.ts +102 -0
- package/dist/blake3/types.js +31 -0
- package/dist/blake3/validate.d.ts +29 -0
- package/dist/blake3/validate.js +80 -0
- package/dist/blake3.wasm +0 -0
- package/dist/chacha20/cipher-suite.js +47 -25
- package/dist/chacha20/generator.d.ts +2 -2
- package/dist/chacha20/generator.js +4 -4
- package/dist/chacha20/index.d.ts +16 -15
- package/dist/chacha20/index.js +52 -46
- package/dist/chacha20/ops.d.ts +7 -7
- package/dist/chacha20/ops.js +34 -34
- package/dist/chacha20/pool-worker.js +5 -3
- package/dist/cte-wasm.d.ts +1 -0
- package/dist/cte-wasm.js +3 -0
- package/dist/curve25519.wasm +0 -0
- package/dist/ecdsa/der.d.ts +23 -0
- package/dist/ecdsa/der.js +192 -0
- package/dist/ecdsa/ecprivatekey-der.d.ts +32 -0
- package/dist/ecdsa/ecprivatekey-der.js +230 -0
- package/dist/ecdsa/embedded.d.ts +1 -0
- package/dist/ecdsa/embedded.js +25 -0
- package/dist/ecdsa/index.d.ts +124 -0
- package/dist/ecdsa/index.js +366 -0
- package/dist/ecdsa/types.d.ts +31 -0
- package/dist/ecdsa/types.js +28 -0
- package/dist/ecdsa/validate.d.ts +18 -0
- package/dist/ecdsa/validate.js +92 -0
- package/dist/ed25519/embedded.d.ts +1 -0
- package/dist/ed25519/embedded.js +31 -0
- package/dist/ed25519/index.d.ts +70 -0
- package/dist/ed25519/index.js +308 -0
- package/dist/ed25519/types.d.ts +27 -0
- package/dist/ed25519/types.js +27 -0
- package/dist/ed25519/validate.d.ts +7 -0
- package/dist/ed25519/validate.js +77 -0
- package/dist/embedded/aes-pool-worker.d.ts +1 -0
- package/dist/embedded/aes-pool-worker.js +5 -0
- package/dist/embedded/aes.d.ts +1 -0
- package/dist/embedded/aes.js +3 -0
- package/dist/embedded/blake3.d.ts +1 -0
- package/dist/embedded/blake3.js +3 -0
- package/dist/embedded/chacha20-pool-worker.d.ts +1 -1
- package/dist/embedded/chacha20-pool-worker.js +2 -2
- package/dist/embedded/chacha20.d.ts +1 -1
- package/dist/embedded/chacha20.js +2 -2
- package/dist/embedded/curve25519.d.ts +1 -0
- package/dist/embedded/curve25519.js +3 -0
- package/dist/embedded/mldsa.d.ts +1 -0
- package/dist/embedded/mldsa.js +3 -0
- package/dist/embedded/mlkem.d.ts +1 -0
- package/dist/embedded/mlkem.js +3 -0
- package/dist/embedded/p256.d.ts +1 -0
- package/dist/embedded/p256.js +3 -0
- package/dist/embedded/serpent-pool-worker.d.ts +1 -1
- package/dist/embedded/serpent-pool-worker.js +2 -2
- package/dist/embedded/serpent.d.ts +1 -1
- package/dist/embedded/serpent.js +2 -2
- package/dist/embedded/sha2.d.ts +1 -1
- package/dist/embedded/sha2.js +2 -2
- package/dist/embedded/sha3.d.ts +1 -1
- package/dist/embedded/sha3.js +2 -2
- package/dist/embedded/slhdsa.d.ts +1 -0
- package/dist/embedded/slhdsa.js +3 -0
- package/dist/errors.d.ts +92 -1
- package/dist/errors.js +111 -1
- package/dist/fortuna.d.ts +5 -5
- package/dist/fortuna.js +37 -64
- package/dist/index.d.ts +38 -9
- package/dist/index.js +63 -19
- package/dist/init.d.ts +1 -1
- package/dist/init.js +11 -25
- package/dist/keccak/embedded.js +1 -1
- package/dist/keccak/index.d.ts +2 -0
- package/dist/keccak/index.js +4 -2
- package/dist/loader.d.ts +1 -24
- package/dist/loader.js +13 -16
- package/dist/merkle/blake3-tree.d.ts +35 -0
- package/dist/merkle/blake3-tree.js +187 -0
- package/dist/merkle/checkpoint.d.ts +58 -0
- package/dist/merkle/checkpoint.js +217 -0
- package/dist/merkle/index.d.ts +19 -0
- package/dist/merkle/index.js +37 -0
- package/dist/merkle/merkle-log.d.ts +130 -0
- package/dist/merkle/merkle-log.js +207 -0
- package/dist/merkle/merkle-verifier.d.ts +126 -0
- package/dist/merkle/merkle-verifier.js +296 -0
- package/dist/merkle/proof.d.ts +70 -0
- package/dist/merkle/proof.js +300 -0
- package/dist/merkle/sha256-tree.d.ts +33 -0
- package/dist/merkle/sha256-tree.js +145 -0
- package/dist/merkle/signed-log.d.ts +156 -0
- package/dist/merkle/signed-log.js +356 -0
- package/dist/merkle/signed-note.d.ts +309 -0
- package/dist/merkle/signed-note.js +648 -0
- package/dist/merkle/sth.d.ts +31 -0
- package/dist/merkle/sth.js +31 -0
- package/dist/merkle/storage.d.ts +40 -0
- package/dist/merkle/storage.js +71 -0
- package/dist/merkle/tree.d.ts +68 -0
- package/dist/merkle/tree.js +94 -0
- package/dist/mldsa/embedded.d.ts +1 -0
- package/dist/{kyber → mldsa}/embedded.js +5 -5
- package/dist/mldsa/expand.d.ts +53 -0
- package/dist/mldsa/expand.js +188 -0
- package/dist/mldsa/format.d.ts +16 -0
- package/dist/mldsa/format.js +68 -0
- package/dist/mldsa/hashvariant.d.ts +32 -0
- package/dist/mldsa/hashvariant.js +248 -0
- package/dist/mldsa/index.d.ts +142 -0
- package/dist/mldsa/index.js +463 -0
- package/dist/mldsa/keygen.d.ts +16 -0
- package/dist/mldsa/keygen.js +232 -0
- package/dist/mldsa/params.d.ts +21 -0
- package/dist/mldsa/params.js +55 -0
- package/dist/mldsa/sha3-helpers.d.ts +30 -0
- package/dist/mldsa/sha3-helpers.js +124 -0
- package/dist/mldsa/sign.d.ts +36 -0
- package/dist/mldsa/sign.js +380 -0
- package/dist/mldsa/types.d.ts +91 -0
- package/dist/mldsa/types.js +25 -0
- package/dist/mldsa/validate.d.ts +55 -0
- package/dist/mldsa/validate.js +125 -0
- package/dist/mldsa/verify.d.ts +29 -0
- package/dist/mldsa/verify.js +269 -0
- package/dist/mldsa.wasm +0 -0
- package/dist/mlkem/embedded.d.ts +1 -0
- package/dist/mlkem/embedded.js +27 -0
- package/dist/mlkem/indcpa.d.ts +49 -0
- package/dist/{kyber → mlkem}/indcpa.js +44 -44
- package/dist/mlkem/index.d.ts +37 -0
- package/dist/{kyber → mlkem}/index.js +24 -34
- package/dist/mlkem/kem.d.ts +21 -0
- package/dist/{kyber → mlkem}/kem.js +44 -64
- package/dist/{kyber → mlkem}/params.d.ts +4 -4
- package/dist/{kyber → mlkem}/params.js +2 -2
- package/dist/mlkem/suite.d.ts +12 -0
- package/dist/{kyber → mlkem}/suite.js +17 -12
- package/dist/{kyber → mlkem}/types.d.ts +3 -3
- package/dist/{kyber → mlkem}/types.js +1 -1
- package/dist/{kyber → mlkem}/validate.d.ts +7 -7
- package/dist/{kyber → mlkem}/validate.js +7 -7
- package/dist/{kyber.wasm → mlkem.wasm} +0 -0
- package/dist/p256.wasm +0 -0
- package/dist/ratchet/index.d.ts +2 -0
- package/dist/ratchet/index.js +1 -0
- package/dist/ratchet/kdf-chain.js +3 -3
- package/dist/ratchet/ratchet-keypair.js +2 -2
- package/dist/ratchet/root-kdf.js +7 -7
- package/dist/ratchet/skipped-key-store.js +4 -4
- package/dist/ratchet/types.d.ts +1 -1
- package/dist/serpent/cipher-suite.js +20 -17
- package/dist/serpent/generator.d.ts +1 -1
- package/dist/serpent/generator.js +2 -2
- package/dist/serpent/index.d.ts +8 -7
- package/dist/serpent/index.js +18 -27
- package/dist/serpent/pool-worker.js +7 -5
- package/dist/serpent/serpent-cbc.d.ts +4 -4
- package/dist/serpent/serpent-cbc.js +11 -8
- package/dist/serpent/shared-ops.d.ts +3 -23
- package/dist/serpent/shared-ops.js +50 -85
- package/dist/serpent.wasm +0 -0
- package/dist/sha2/hkdf.js +5 -5
- package/dist/sha2/index.d.ts +21 -1
- package/dist/sha2/index.js +65 -10
- package/dist/sha2/types.d.ts +41 -2
- package/dist/sha2.wasm +0 -0
- package/dist/sha3/index.d.ts +72 -3
- package/dist/sha3/index.js +240 -14
- package/dist/sha3/kmac.d.ts +121 -0
- package/dist/sha3/kmac.js +800 -0
- package/dist/sha3.wasm +0 -0
- package/dist/shared/pkcs7.d.ts +22 -0
- package/dist/shared/pkcs7.js +84 -0
- package/dist/sign/ctx.d.ts +41 -0
- package/dist/sign/ctx.js +102 -0
- package/dist/sign/envelope.d.ts +45 -0
- package/dist/sign/envelope.js +152 -0
- package/dist/sign/hasher.d.ts +9 -0
- package/dist/sign/hasher.js +132 -0
- package/dist/sign/index.d.ts +11 -0
- package/dist/sign/index.js +34 -0
- package/dist/sign/sign-stream.d.ts +25 -0
- package/dist/sign/sign-stream.js +112 -0
- package/dist/sign/suites/ecdsa-p256.d.ts +2 -0
- package/dist/sign/suites/ecdsa-p256.js +120 -0
- package/dist/sign/suites/ed25519.d.ts +3 -0
- package/dist/sign/suites/ed25519.js +165 -0
- package/dist/sign/suites/hybrid-classical.d.ts +23 -0
- package/dist/sign/suites/hybrid-classical.js +526 -0
- package/dist/sign/suites/hybrid-pq.d.ts +4 -0
- package/dist/sign/suites/hybrid-pq.js +234 -0
- package/dist/sign/suites/mldsa.d.ts +7 -0
- package/dist/sign/suites/mldsa.js +161 -0
- package/dist/sign/suites/slhdsa.d.ts +7 -0
- package/dist/sign/suites/slhdsa.js +176 -0
- package/dist/sign/types.d.ts +106 -0
- package/dist/sign/types.js +28 -0
- package/dist/sign/verify-stream.d.ts +30 -0
- package/dist/sign/verify-stream.js +227 -0
- package/dist/slhdsa/embedded.d.ts +1 -0
- package/dist/slhdsa/embedded.js +26 -0
- package/dist/slhdsa/index.d.ts +149 -0
- package/dist/slhdsa/index.js +493 -0
- package/dist/slhdsa/params.d.ts +26 -0
- package/dist/slhdsa/params.js +70 -0
- package/dist/slhdsa/prehash.d.ts +68 -0
- package/dist/slhdsa/prehash.js +307 -0
- package/dist/slhdsa/sign.d.ts +39 -0
- package/dist/slhdsa/sign.js +116 -0
- package/dist/slhdsa/types.d.ts +129 -0
- package/dist/slhdsa/types.js +27 -0
- package/dist/slhdsa/validate.d.ts +60 -0
- package/dist/slhdsa/validate.js +127 -0
- package/dist/slhdsa/verify.d.ts +32 -0
- package/dist/slhdsa/verify.js +107 -0
- package/dist/slhdsa.wasm +0 -0
- package/dist/stream/header.js +3 -3
- package/dist/stream/index.d.ts +1 -0
- package/dist/stream/index.js +1 -0
- package/dist/stream/open-stream.js +31 -10
- package/dist/stream/seal-stream-pool.d.ts +1 -0
- package/dist/stream/seal-stream-pool.js +63 -26
- package/dist/stream/seal-stream.d.ts +1 -1
- package/dist/stream/seal-stream.js +20 -9
- package/dist/stream/seal.js +6 -6
- package/dist/stream/types.d.ts +3 -1
- package/dist/stream/types.js +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.js +1 -1
- package/dist/utils.d.ts +3 -3
- package/dist/utils.js +46 -54
- package/dist/wasm-source.d.ts +7 -7
- package/dist/wasm-source.js +1 -1
- package/dist/x25519/embedded.d.ts +1 -0
- package/dist/x25519/embedded.js +31 -0
- package/dist/x25519/index.d.ts +43 -0
- package/dist/x25519/index.js +159 -0
- package/dist/x25519/types.d.ts +25 -0
- package/dist/x25519/types.js +27 -0
- package/dist/x25519/validate.d.ts +2 -0
- package/dist/x25519/validate.js +39 -0
- package/package.json +70 -26
- package/SECURITY.md +0 -163
- package/dist/ct-wasm.d.ts +0 -1
- package/dist/ct-wasm.js +0 -3
- package/dist/docs/aead.md +0 -363
- package/dist/docs/architecture.md +0 -1011
- package/dist/docs/argon2id.md +0 -305
- package/dist/docs/chacha20.md +0 -781
- package/dist/docs/exports.md +0 -277
- package/dist/docs/fortuna.md +0 -530
- package/dist/docs/init.md +0 -301
- package/dist/docs/loader.md +0 -256
- package/dist/docs/serpent.md +0 -617
- package/dist/docs/sha2.md +0 -671
- package/dist/docs/sha3.md +0 -612
- package/dist/docs/types.md +0 -416
- package/dist/docs/utils.md +0 -457
- package/dist/embedded/kyber.d.ts +0 -1
- package/dist/embedded/kyber.js +0 -3
- package/dist/kyber/embedded.d.ts +0 -1
- package/dist/kyber/indcpa.d.ts +0 -49
- package/dist/kyber/index.d.ts +0 -38
- package/dist/kyber/kem.d.ts +0 -21
- package/dist/kyber/suite.d.ts +0 -12
- /package/dist/{ct.wasm → cte.wasm} +0 -0
package/dist/chacha20/index.js
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
// src/ts/chacha20/index.ts
|
|
23
23
|
//
|
|
24
24
|
// Public API classes for the ChaCha20 WASM module.
|
|
25
|
-
// Uses the init() module cache
|
|
25
|
+
// Uses the init() module cache, call chacha20Init(source) before constructing.
|
|
26
26
|
import { getInstance, initModule, _acquireModule, _releaseModule, _assertNotOwned } from '../init.js';
|
|
27
27
|
import { aeadEncrypt, aeadDecrypt, xcEncrypt, xcDecrypt } from './ops.js';
|
|
28
28
|
import { AuthenticationError } from '../errors.js';
|
|
@@ -30,12 +30,13 @@ export { AuthenticationError };
|
|
|
30
30
|
/**
|
|
31
31
|
* Load and initialise the ChaCha20 WASM module from `source`.
|
|
32
32
|
* Must be called before constructing any ChaCha20 class.
|
|
33
|
-
* @param source WASM binary
|
|
33
|
+
* @param source WASM binary, gzip+base64 string, URL, ArrayBuffer, Uint8Array,
|
|
34
34
|
* pre-compiled WebAssembly.Module, Response, or Promise<Response>
|
|
35
35
|
*/
|
|
36
36
|
export async function chacha20Init(source) {
|
|
37
37
|
return initModule('chacha20', source);
|
|
38
38
|
}
|
|
39
|
+
export { isInitialized } from '../init.js';
|
|
39
40
|
/** Returns the raw chacha20 WASM export object. @internal */
|
|
40
41
|
function getExports() {
|
|
41
42
|
return getInstance('chacha20').exports;
|
|
@@ -59,7 +60,7 @@ export class ChaCha20 {
|
|
|
59
60
|
* Load key and nonce into WASM state and set the block counter to 1.
|
|
60
61
|
* Must be called before each message (RFC 8439 §2.4).
|
|
61
62
|
* @param key 32 bytes
|
|
62
|
-
* @param nonce 12 bytes
|
|
63
|
+
* @param nonce 12 bytes, must be unique per (key, message)
|
|
63
64
|
*/
|
|
64
65
|
beginEncrypt(key, nonce) {
|
|
65
66
|
if (this._tok === undefined)
|
|
@@ -76,7 +77,7 @@ export class ChaCha20 {
|
|
|
76
77
|
}
|
|
77
78
|
/**
|
|
78
79
|
* XOR `chunk` with the next keystream block(s). Counter advances automatically.
|
|
79
|
-
* @param chunk Plaintext chunk
|
|
80
|
+
* @param chunk Plaintext chunk, must not exceed WASM CHUNK_SIZE
|
|
80
81
|
* @returns Ciphertext of the same length
|
|
81
82
|
*/
|
|
82
83
|
encryptChunk(chunk) {
|
|
@@ -84,7 +85,7 @@ export class ChaCha20 {
|
|
|
84
85
|
throw new Error('ChaCha20: instance has been disposed');
|
|
85
86
|
const maxChunk = this.x.getChunkSize();
|
|
86
87
|
if (chunk.length > maxChunk)
|
|
87
|
-
throw new RangeError(`chunk exceeds maximum size of ${maxChunk} bytes
|
|
88
|
+
throw new RangeError(`chunk exceeds maximum size of ${maxChunk} bytes, split into smaller chunks`);
|
|
88
89
|
const mem = new Uint8Array(this.x.memory.buffer);
|
|
89
90
|
const ptOff = this.x.getChunkPtOffset();
|
|
90
91
|
const ctOff = this.x.getChunkCtOffset();
|
|
@@ -93,15 +94,15 @@ export class ChaCha20 {
|
|
|
93
94
|
return mem.slice(ctOff, ctOff + chunk.length);
|
|
94
95
|
}
|
|
95
96
|
/**
|
|
96
|
-
* Alias for `beginEncrypt
|
|
97
|
+
* Alias for `beginEncrypt`, ChaCha20 is a stream cipher (symmetric).
|
|
97
98
|
* @param key 32 bytes
|
|
98
|
-
* @param nonce 12 bytes
|
|
99
|
+
* @param nonce 12 bytes, must match the value used to encrypt
|
|
99
100
|
*/
|
|
100
101
|
beginDecrypt(key, nonce) {
|
|
101
102
|
this.beginEncrypt(key, nonce);
|
|
102
103
|
}
|
|
103
104
|
/**
|
|
104
|
-
* Alias for `encryptChunk
|
|
105
|
+
* Alias for `encryptChunk`, ChaCha20 is a stream cipher (symmetric).
|
|
105
106
|
* @param chunk Ciphertext chunk
|
|
106
107
|
* @returns Plaintext of the same length
|
|
107
108
|
*/
|
|
@@ -137,7 +138,7 @@ export class Poly1305 {
|
|
|
137
138
|
}
|
|
138
139
|
/**
|
|
139
140
|
* Compute a 16-byte Poly1305 MAC for `msg` using `key`.
|
|
140
|
-
* @param key 32-byte one-time key
|
|
141
|
+
* @param key 32-byte one-time key, must not be reused across messages
|
|
141
142
|
* @param msg Message to authenticate
|
|
142
143
|
* @returns 16-byte Poly1305 tag
|
|
143
144
|
*/
|
|
@@ -177,7 +178,7 @@ export class Poly1305 {
|
|
|
177
178
|
* Single-use encrypt guard: `encrypt()` may only be called once per instance.
|
|
178
179
|
* Create a new instance for each encryption to prevent nonce reuse.
|
|
179
180
|
*
|
|
180
|
-
* `decrypt()` uses constant-time tag comparison
|
|
181
|
+
* `decrypt()` uses constant-time tag comparison, XOR-accumulate pattern,
|
|
181
182
|
* no early return on mismatch. Plaintext is never returned on failure.
|
|
182
183
|
*/
|
|
183
184
|
export class ChaCha20Poly1305 {
|
|
@@ -190,10 +191,10 @@ export class ChaCha20Poly1305 {
|
|
|
190
191
|
* Encrypt and authenticate `plaintext` with ChaCha20-Poly1305 (RFC 8439 §2.8).
|
|
191
192
|
*
|
|
192
193
|
* **Single-use guard:** `encrypt()` may only be called once per instance.
|
|
193
|
-
* Any throw
|
|
194
|
+
* Any throw, including validation errors, permanently locks this instance.
|
|
194
195
|
* Always create a new `ChaCha20Poly1305` per message.
|
|
195
196
|
* @param key 32 bytes
|
|
196
|
-
* @param nonce 12 bytes
|
|
197
|
+
* @param nonce 12 bytes, must be unique per (key, message)
|
|
197
198
|
* @param plaintext Data to encrypt
|
|
198
199
|
* @param aad Additional authenticated data (optional)
|
|
199
200
|
* @returns Ciphertext || 16-byte Poly1305 tag
|
|
@@ -203,24 +204,29 @@ export class ChaCha20Poly1305 {
|
|
|
203
204
|
throw new Error('leviathan-crypto: encrypt() already called on this instance. '
|
|
204
205
|
+ 'Create a new instance for each encryption to prevent nonce reuse.');
|
|
205
206
|
// Strict single-use: lock FIRST, before anything else. Any subsequent
|
|
206
|
-
// throw
|
|
207
|
+
// throw, including validation errors, terminates the instance.
|
|
207
208
|
this._used = true;
|
|
208
209
|
_assertNotOwned('chacha20');
|
|
209
210
|
if (key.length !== 32)
|
|
210
211
|
throw new RangeError(`key must be 32 bytes (got ${key.length})`);
|
|
211
212
|
if (nonce.length !== 12)
|
|
212
213
|
throw new RangeError(`nonce must be 12 bytes (got ${nonce.length})`);
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
214
|
+
try {
|
|
215
|
+
const { ciphertext, tag } = aeadEncrypt(this.x, key, nonce, plaintext, aad);
|
|
216
|
+
const out = new Uint8Array(ciphertext.length + 16);
|
|
217
|
+
out.set(ciphertext);
|
|
218
|
+
out.set(tag, ciphertext.length);
|
|
219
|
+
return out;
|
|
220
|
+
}
|
|
221
|
+
finally {
|
|
222
|
+
this.x.wipeBuffers();
|
|
223
|
+
}
|
|
218
224
|
}
|
|
219
225
|
/**
|
|
220
226
|
* Verify and decrypt a ChaCha20-Poly1305 ciphertext (RFC 8439 §2.8).
|
|
221
227
|
* Throws `AuthenticationError` if the tag does not match.
|
|
222
228
|
* @param key 32 bytes
|
|
223
|
-
* @param nonce 12 bytes
|
|
229
|
+
* @param nonce 12 bytes, must match the value used to encrypt
|
|
224
230
|
* @param ciphertext Ciphertext || 16-byte tag (combined format from `encrypt`)
|
|
225
231
|
* @param aad Additional authenticated data (optional)
|
|
226
232
|
* @returns Plaintext
|
|
@@ -233,10 +239,15 @@ export class ChaCha20Poly1305 {
|
|
|
233
239
|
if (nonce.length !== 12)
|
|
234
240
|
throw new RangeError(`nonce must be 12 bytes (got ${nonce.length})`);
|
|
235
241
|
if (ciphertext.length < 16)
|
|
236
|
-
throw new RangeError(`ciphertext too short
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
242
|
+
throw new RangeError(`ciphertext too short, must include 16-byte tag (got ${ciphertext.length})`);
|
|
243
|
+
try {
|
|
244
|
+
const ct = ciphertext.subarray(0, ciphertext.length - 16);
|
|
245
|
+
const tag = ciphertext.subarray(ciphertext.length - 16);
|
|
246
|
+
return aeadDecrypt(this.x, key, nonce, ct, tag, aad);
|
|
247
|
+
}
|
|
248
|
+
finally {
|
|
249
|
+
this.x.wipeBuffers();
|
|
250
|
+
}
|
|
240
251
|
}
|
|
241
252
|
/** Wipe WASM cipher and MAC state. */
|
|
242
253
|
dispose() {
|
|
@@ -249,7 +260,7 @@ export class ChaCha20Poly1305 {
|
|
|
249
260
|
* XChaCha20-Poly1305 AEAD (IETF draft-irtf-cfrg-xchacha).
|
|
250
261
|
*
|
|
251
262
|
* Recommended authenticated encryption primitive for most use cases.
|
|
252
|
-
* Uses a 24-byte nonce
|
|
263
|
+
* Uses a 24-byte nonce, safe for random generation via crypto.getRandomValues.
|
|
253
264
|
*
|
|
254
265
|
* Single-use encrypt guard: `encrypt()` may only be called once per instance.
|
|
255
266
|
* Create a new instance for each encryption to prevent nonce reuse.
|
|
@@ -267,10 +278,10 @@ export class XChaCha20Poly1305 {
|
|
|
267
278
|
* (draft-irtf-cfrg-xchacha). Recommended for general-purpose AEAD.
|
|
268
279
|
*
|
|
269
280
|
* **Single-use guard:** `encrypt()` may only be called once per instance.
|
|
270
|
-
* Any throw
|
|
281
|
+
* Any throw, including validation errors, permanently locks this instance.
|
|
271
282
|
* Always create a new `XChaCha20Poly1305` per message to prevent nonce reuse.
|
|
272
283
|
* @param key 32 bytes
|
|
273
|
-
* @param nonce 24 bytes
|
|
284
|
+
* @param nonce 24 bytes, safe to generate randomly via `randomBytes(24)`
|
|
274
285
|
* @param plaintext Data to encrypt
|
|
275
286
|
* @param aad Additional authenticated data (optional)
|
|
276
287
|
* @returns Ciphertext || 16-byte Poly1305 tag
|
|
@@ -280,20 +291,25 @@ export class XChaCha20Poly1305 {
|
|
|
280
291
|
throw new Error('leviathan-crypto: encrypt() already called on this instance. '
|
|
281
292
|
+ 'Create a new instance for each encryption to prevent nonce reuse.');
|
|
282
293
|
// Strict single-use: lock FIRST, before anything else. Any subsequent
|
|
283
|
-
// throw
|
|
294
|
+
// throw, including validation errors, terminates the instance.
|
|
284
295
|
this._used = true;
|
|
285
296
|
_assertNotOwned('chacha20');
|
|
286
297
|
if (key.length !== 32)
|
|
287
298
|
throw new RangeError(`key must be 32 bytes (got ${key.length})`);
|
|
288
299
|
if (nonce.length !== 24)
|
|
289
300
|
throw new RangeError(`XChaCha20 nonce must be 24 bytes (got ${nonce.length})`);
|
|
290
|
-
|
|
301
|
+
try {
|
|
302
|
+
return xcEncrypt(this.x, key, nonce, plaintext, aad);
|
|
303
|
+
}
|
|
304
|
+
finally {
|
|
305
|
+
this.x.wipeBuffers();
|
|
306
|
+
}
|
|
291
307
|
}
|
|
292
308
|
/**
|
|
293
309
|
* Verify and decrypt an XChaCha20-Poly1305 ciphertext.
|
|
294
310
|
* Throws `AuthenticationError` if the tag does not match.
|
|
295
311
|
* @param key 32 bytes
|
|
296
|
-
* @param nonce 24 bytes
|
|
312
|
+
* @param nonce 24 bytes, must match the value used to encrypt
|
|
297
313
|
* @param ciphertext Ciphertext || 16-byte tag (combined format from `encrypt`)
|
|
298
314
|
* @param aad Additional authenticated data (optional)
|
|
299
315
|
* @returns Plaintext
|
|
@@ -305,8 +321,13 @@ export class XChaCha20Poly1305 {
|
|
|
305
321
|
if (nonce.length !== 24)
|
|
306
322
|
throw new RangeError(`XChaCha20 nonce must be 24 bytes (got ${nonce.length})`);
|
|
307
323
|
if (ciphertext.length < 16)
|
|
308
|
-
throw new RangeError(`ciphertext too short
|
|
309
|
-
|
|
324
|
+
throw new RangeError(`ciphertext too short, must include 16-byte tag (got ${ciphertext.length})`);
|
|
325
|
+
try {
|
|
326
|
+
return xcDecrypt(this.x, key, nonce, ciphertext, aad);
|
|
327
|
+
}
|
|
328
|
+
finally {
|
|
329
|
+
this.x.wipeBuffers();
|
|
330
|
+
}
|
|
310
331
|
}
|
|
311
332
|
/** Wipe WASM cipher and MAC state. */
|
|
312
333
|
dispose() {
|
|
@@ -317,18 +338,3 @@ export class XChaCha20Poly1305 {
|
|
|
317
338
|
export { XChaCha20Cipher } from './cipher-suite.js';
|
|
318
339
|
// ── ChaCha20Generator ───────────────────────────────────────────────────────
|
|
319
340
|
export { ChaCha20Generator } from './generator.js';
|
|
320
|
-
// ── Ready check ─────────────────────────────────────────────────────────────
|
|
321
|
-
/**
|
|
322
|
-
* Returns `true` if the chacha20 WASM module has been initialised.
|
|
323
|
-
* Used by tests and internal guards; not part of the public API.
|
|
324
|
-
* @internal
|
|
325
|
-
*/
|
|
326
|
-
export function _chachaReady() {
|
|
327
|
-
try {
|
|
328
|
-
getInstance('chacha20');
|
|
329
|
-
return true;
|
|
330
|
-
}
|
|
331
|
-
catch {
|
|
332
|
-
return false;
|
|
333
|
-
}
|
|
334
|
-
}
|
package/dist/chacha20/ops.d.ts
CHANGED
|
@@ -3,10 +3,10 @@ import type { ChaChaExports } from './types.js';
|
|
|
3
3
|
* ChaCha20-Poly1305 AEAD encrypt (RFC 8439 §2.8).
|
|
4
4
|
* @param x ChaCha20 WASM exports
|
|
5
5
|
* @param key 32-byte key
|
|
6
|
-
* @param nonce 12-byte nonce
|
|
6
|
+
* @param nonce 12-byte nonce, must be unique per (key, message)
|
|
7
7
|
* @param plaintext Data to encrypt (must be ≤ WASM CHUNK_SIZE)
|
|
8
8
|
* @param aad Additional authenticated data
|
|
9
|
-
* @returns `{ ciphertext, tag }
|
|
9
|
+
* @returns `{ ciphertext, tag }`, tag is 16 bytes
|
|
10
10
|
*/
|
|
11
11
|
export declare function aeadEncrypt(x: ChaChaExports, key: Uint8Array, nonce: Uint8Array, plaintext: Uint8Array, aad: Uint8Array): {
|
|
12
12
|
ciphertext: Uint8Array;
|
|
@@ -17,7 +17,7 @@ export declare function aeadEncrypt(x: ChaChaExports, key: Uint8Array, nonce: Ui
|
|
|
17
17
|
* Throws `AuthenticationError` on tag mismatch; never returns plaintext on failure.
|
|
18
18
|
* @param x ChaCha20 WASM exports
|
|
19
19
|
* @param key 32-byte key
|
|
20
|
-
* @param nonce 12-byte nonce
|
|
20
|
+
* @param nonce 12-byte nonce, must match the value used to encrypt
|
|
21
21
|
* @param ciphertext Ciphertext bytes (must be ≤ WASM CHUNK_SIZE)
|
|
22
22
|
* @param tag 16-byte Poly1305 tag
|
|
23
23
|
* @param aad Additional authenticated data
|
|
@@ -30,15 +30,15 @@ export declare function aeadDecrypt(x: ChaChaExports, key: Uint8Array, nonce: Ui
|
|
|
30
30
|
* Used as the inner key for XChaCha20-Poly1305 (draft-irtf-cfrg-xchacha §2.3).
|
|
31
31
|
* @param x ChaCha20 WASM exports
|
|
32
32
|
* @param key 32-byte master key
|
|
33
|
-
* @param nonce 24-byte XChaCha20 nonce (only bytes 0
|
|
33
|
+
* @param nonce 24-byte XChaCha20 nonce (only bytes 0-15 are used)
|
|
34
34
|
* @returns 32-byte HChaCha20 subkey
|
|
35
35
|
*/
|
|
36
36
|
export declare function deriveSubkey(x: ChaChaExports, key: Uint8Array, nonce: Uint8Array): Uint8Array;
|
|
37
37
|
/**
|
|
38
|
-
* Build the inner 12-byte ChaCha20 nonce for XChaCha20 from bytes 16
|
|
38
|
+
* Build the inner 12-byte ChaCha20 nonce for XChaCha20 from bytes 16-23 of the
|
|
39
39
|
* 24-byte XChaCha nonce (draft-irtf-cfrg-xchacha §2.3).
|
|
40
40
|
* @param nonce 24-byte XChaCha20 nonce
|
|
41
|
-
* @returns 12-byte inner nonce (bytes 0
|
|
41
|
+
* @returns 12-byte inner nonce (bytes 0-3 are zero, bytes 4-11 are nonce[16:24])
|
|
42
42
|
*/
|
|
43
43
|
export declare function innerNonce(nonce: Uint8Array): Uint8Array;
|
|
44
44
|
/**
|
|
@@ -59,7 +59,7 @@ export declare function xcEncrypt(x: ChaChaExports, key: Uint8Array, nonce: Uint
|
|
|
59
59
|
* Throws `AuthenticationError` on tag mismatch.
|
|
60
60
|
* @param x ChaCha20 WASM exports
|
|
61
61
|
* @param key 32-byte key
|
|
62
|
-
* @param nonce 24-byte nonce
|
|
62
|
+
* @param nonce 24-byte nonce, must match the value used to encrypt
|
|
63
63
|
* @param ciphertext Ciphertext || 16-byte tag (combined format from `xcEncrypt`)
|
|
64
64
|
* @param aad Additional authenticated data
|
|
65
65
|
* @returns Plaintext
|
package/dist/chacha20/ops.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// src/ts/chacha20/ops.ts
|
|
2
2
|
//
|
|
3
|
-
// Raw XChaCha20-Poly1305 operations
|
|
3
|
+
// Raw XChaCha20-Poly1305 operations, standalone functions that take
|
|
4
4
|
// ChaChaExports explicitly. Used by both the class wrappers (index.ts)
|
|
5
5
|
// and the pool worker (pool.worker.ts), eliminating duplication.
|
|
6
|
-
import { constantTimeEqual } from '../utils.js';
|
|
6
|
+
import { constantTimeEqual, wipe } from '../utils.js';
|
|
7
7
|
import { AuthenticationError } from '../errors.js';
|
|
8
8
|
// ── Module-private helpers ──────────────────────────────────────────────────
|
|
9
9
|
/**
|
|
@@ -37,8 +37,8 @@ function polyFeed(x, data) {
|
|
|
37
37
|
function lenBlock(aadLen, ctLen) {
|
|
38
38
|
const b = new Uint8Array(16);
|
|
39
39
|
const dv = new DataView(b.buffer);
|
|
40
|
-
// RFC 8439 §2.8
|
|
41
|
-
// JS numbers are f64
|
|
40
|
+
// RFC 8439 §2.8, 64-bit LE lengths.
|
|
41
|
+
// JS numbers are f64, write low 32 bits directly, high bits via
|
|
42
42
|
// Math.floor(n / 2^32). Safe for n ≤ Number.MAX_SAFE_INTEGER.
|
|
43
43
|
dv.setUint32(0, aadLen >>> 0, true);
|
|
44
44
|
dv.setUint32(4, Math.floor(aadLen / 0x100000000) >>> 0, true);
|
|
@@ -51,15 +51,15 @@ function lenBlock(aadLen, ctLen) {
|
|
|
51
51
|
* ChaCha20-Poly1305 AEAD encrypt (RFC 8439 §2.8).
|
|
52
52
|
* @param x ChaCha20 WASM exports
|
|
53
53
|
* @param key 32-byte key
|
|
54
|
-
* @param nonce 12-byte nonce
|
|
54
|
+
* @param nonce 12-byte nonce, must be unique per (key, message)
|
|
55
55
|
* @param plaintext Data to encrypt (must be ≤ WASM CHUNK_SIZE)
|
|
56
56
|
* @param aad Additional authenticated data
|
|
57
|
-
* @returns `{ ciphertext, tag }
|
|
57
|
+
* @returns `{ ciphertext, tag }`, tag is 16 bytes
|
|
58
58
|
*/
|
|
59
59
|
export function aeadEncrypt(x, key, nonce, plaintext, aad) {
|
|
60
60
|
const maxChunk = x.getChunkSize();
|
|
61
61
|
if (plaintext.length > maxChunk)
|
|
62
|
-
throw new RangeError(`plaintext exceeds ${maxChunk} bytes
|
|
62
|
+
throw new RangeError(`plaintext exceeds ${maxChunk} bytes, split into smaller chunks`);
|
|
63
63
|
const mem = new Uint8Array(x.memory.buffer);
|
|
64
64
|
// Step 1: Generate Poly1305 one-time key at counter=0 (RFC 8439 §2.6)
|
|
65
65
|
mem.set(key, x.getKeyOffset());
|
|
@@ -73,12 +73,7 @@ export function aeadEncrypt(x, key, nonce, plaintext, aad) {
|
|
|
73
73
|
const aadPad = (16 - aad.length % 16) % 16;
|
|
74
74
|
if (aadPad > 0)
|
|
75
75
|
polyFeed(x, new Uint8Array(aadPad));
|
|
76
|
-
// Step 4:
|
|
77
|
-
// `chachaGenPolyKey` mutated CHACHA_STATE + 48 (the counter word) to 0 but
|
|
78
|
-
// left every other state word intact (constants, key, nonce). Writing
|
|
79
|
-
// counter=1 via `chachaSetCounter` restores the state for encryption —
|
|
80
|
-
// no second `chachaLoadKey()` is needed (the key/nonce buffers and the
|
|
81
|
-
// non-counter state words are already correct).
|
|
76
|
+
// Step 4: counter=1 (state intact from chachaGenPolyKey; no reload needed).
|
|
82
77
|
x.chachaSetCounter(1);
|
|
83
78
|
// Step 5: Encrypt
|
|
84
79
|
mem.set(plaintext, x.getChunkPtOffset());
|
|
@@ -103,7 +98,7 @@ export function aeadEncrypt(x, key, nonce, plaintext, aad) {
|
|
|
103
98
|
* Throws `AuthenticationError` on tag mismatch; never returns plaintext on failure.
|
|
104
99
|
* @param x ChaCha20 WASM exports
|
|
105
100
|
* @param key 32-byte key
|
|
106
|
-
* @param nonce 12-byte nonce
|
|
101
|
+
* @param nonce 12-byte nonce, must match the value used to encrypt
|
|
107
102
|
* @param ciphertext Ciphertext bytes (must be ≤ WASM CHUNK_SIZE)
|
|
108
103
|
* @param tag 16-byte Poly1305 tag
|
|
109
104
|
* @param aad Additional authenticated data
|
|
@@ -113,7 +108,7 @@ export function aeadEncrypt(x, key, nonce, plaintext, aad) {
|
|
|
113
108
|
export function aeadDecrypt(x, key, nonce, ciphertext, tag, aad, cipherName = 'chacha20-poly1305') {
|
|
114
109
|
const maxChunk = x.getChunkSize();
|
|
115
110
|
if (ciphertext.length > maxChunk)
|
|
116
|
-
throw new RangeError(`ciphertext exceeds ${maxChunk} bytes
|
|
111
|
+
throw new RangeError(`ciphertext exceeds ${maxChunk} bytes, split into smaller chunks`);
|
|
117
112
|
const mem = new Uint8Array(x.memory.buffer);
|
|
118
113
|
// Compute expected tag
|
|
119
114
|
mem.set(key, x.getKeyOffset());
|
|
@@ -135,17 +130,12 @@ export function aeadDecrypt(x, key, nonce, ciphertext, tag, aad, cipherName = 'c
|
|
|
135
130
|
const tagOff = x.getPolyTagOffset();
|
|
136
131
|
const expectedTag = new Uint8Array(x.memory.buffer).slice(tagOff, tagOff + 16);
|
|
137
132
|
if (!constantTimeEqual(expectedTag, tag)) {
|
|
138
|
-
//
|
|
133
|
+
// Defense-in-depth wipe on auth fail: chunk ct, chacha block (keystream),
|
|
134
|
+
// Poly1305 one-time subkey copy at POLY_KEY_OFFSET.
|
|
139
135
|
const ctOff = x.getChunkCtOffset();
|
|
140
136
|
mem.fill(0, ctOff, ctOff + maxChunk);
|
|
141
|
-
// Also zero the 64-byte chacha block buffer — it holds keystream bytes
|
|
142
|
-
// generated by chachaGenPolyKey() that would otherwise persist until
|
|
143
|
-
// the next op or dispose().
|
|
144
137
|
const blockOff = x.getChachaBlockOffset();
|
|
145
138
|
mem.fill(0, blockOff, blockOff + 64);
|
|
146
|
-
// And the 32-byte Poly1305 one-time subkey copy at POLY_KEY_OFFSET.
|
|
147
|
-
// chachaGenPolyKey copies keystream[0..32] here; wiping CHACHA_BLOCK
|
|
148
|
-
// zeroes the source but not this copy.
|
|
149
139
|
const polyKeyOff = x.getPolyKeyOffset();
|
|
150
140
|
mem.fill(0, polyKeyOff, polyKeyOff + 32);
|
|
151
141
|
throw new AuthenticationError(cipherName);
|
|
@@ -164,7 +154,7 @@ export function aeadDecrypt(x, key, nonce, ciphertext, tag, aad, cipherName = 'c
|
|
|
164
154
|
* Used as the inner key for XChaCha20-Poly1305 (draft-irtf-cfrg-xchacha §2.3).
|
|
165
155
|
* @param x ChaCha20 WASM exports
|
|
166
156
|
* @param key 32-byte master key
|
|
167
|
-
* @param nonce 24-byte XChaCha20 nonce (only bytes 0
|
|
157
|
+
* @param nonce 24-byte XChaCha20 nonce (only bytes 0-15 are used)
|
|
168
158
|
* @returns 32-byte HChaCha20 subkey
|
|
169
159
|
*/
|
|
170
160
|
export function deriveSubkey(x, key, nonce) {
|
|
@@ -176,10 +166,10 @@ export function deriveSubkey(x, key, nonce) {
|
|
|
176
166
|
return new Uint8Array(x.memory.buffer).slice(off, off + 32);
|
|
177
167
|
}
|
|
178
168
|
/**
|
|
179
|
-
* Build the inner 12-byte ChaCha20 nonce for XChaCha20 from bytes 16
|
|
169
|
+
* Build the inner 12-byte ChaCha20 nonce for XChaCha20 from bytes 16-23 of the
|
|
180
170
|
* 24-byte XChaCha nonce (draft-irtf-cfrg-xchacha §2.3).
|
|
181
171
|
* @param nonce 24-byte XChaCha20 nonce
|
|
182
|
-
* @returns 12-byte inner nonce (bytes 0
|
|
172
|
+
* @returns 12-byte inner nonce (bytes 0-3 are zero, bytes 4-11 are nonce[16:24])
|
|
183
173
|
*/
|
|
184
174
|
export function innerNonce(nonce) {
|
|
185
175
|
const n = new Uint8Array(12);
|
|
@@ -200,12 +190,17 @@ export function innerNonce(nonce) {
|
|
|
200
190
|
*/
|
|
201
191
|
export function xcEncrypt(x, key, nonce, plaintext, aad) {
|
|
202
192
|
const subkey = deriveSubkey(x, key, nonce);
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
193
|
+
try {
|
|
194
|
+
const inner = innerNonce(nonce);
|
|
195
|
+
const { ciphertext, tag } = aeadEncrypt(x, subkey, inner, plaintext, aad);
|
|
196
|
+
const result = new Uint8Array(ciphertext.length + 16);
|
|
197
|
+
result.set(ciphertext);
|
|
198
|
+
result.set(tag, ciphertext.length);
|
|
199
|
+
return result;
|
|
200
|
+
}
|
|
201
|
+
finally {
|
|
202
|
+
wipe(subkey);
|
|
203
|
+
}
|
|
209
204
|
}
|
|
210
205
|
/**
|
|
211
206
|
* XChaCha20-Poly1305 decrypt (draft-irtf-cfrg-xchacha).
|
|
@@ -213,7 +208,7 @@ export function xcEncrypt(x, key, nonce, plaintext, aad) {
|
|
|
213
208
|
* Throws `AuthenticationError` on tag mismatch.
|
|
214
209
|
* @param x ChaCha20 WASM exports
|
|
215
210
|
* @param key 32-byte key
|
|
216
|
-
* @param nonce 24-byte nonce
|
|
211
|
+
* @param nonce 24-byte nonce, must match the value used to encrypt
|
|
217
212
|
* @param ciphertext Ciphertext || 16-byte tag (combined format from `xcEncrypt`)
|
|
218
213
|
* @param aad Additional authenticated data
|
|
219
214
|
* @returns Plaintext
|
|
@@ -222,6 +217,11 @@ export function xcDecrypt(x, key, nonce, ciphertext, aad) {
|
|
|
222
217
|
const ct = ciphertext.subarray(0, ciphertext.length - 16);
|
|
223
218
|
const tag = ciphertext.subarray(ciphertext.length - 16);
|
|
224
219
|
const subkey = deriveSubkey(x, key, nonce);
|
|
225
|
-
|
|
226
|
-
|
|
220
|
+
try {
|
|
221
|
+
const inner = innerNonce(nonce);
|
|
222
|
+
return aeadDecrypt(x, subkey, inner, ct, tag, aad, 'xchacha20-poly1305');
|
|
223
|
+
}
|
|
224
|
+
finally {
|
|
225
|
+
wipe(subkey);
|
|
226
|
+
}
|
|
227
227
|
}
|
|
@@ -12,9 +12,9 @@ let subkey;
|
|
|
12
12
|
* Message handler for the XChaCha20 pool worker.
|
|
13
13
|
*
|
|
14
14
|
* Accepts three message types:
|
|
15
|
-
* - `'init'`
|
|
16
|
-
* - `'wipe'`
|
|
17
|
-
* - `{ op: 'seal' | 'open', ... }
|
|
15
|
+
* - `'init'` , instantiate the chacha20 WASM module and store the derived subkey
|
|
16
|
+
* - `'wipe'` , zero subkey and WASM buffers, then post `{ type: 'wiped' }`
|
|
17
|
+
* - `{ op: 'seal' | 'open', ... }`, encrypt or decrypt one chunk
|
|
18
18
|
*
|
|
19
19
|
* Replies with `{ type: 'result', id, data }` on success or
|
|
20
20
|
* `{ type: 'error', id, message, isAuthError }` on failure.
|
|
@@ -34,6 +34,8 @@ self.onmessage = async (e) => {
|
|
|
34
34
|
self.postMessage({ type: 'ready' });
|
|
35
35
|
}
|
|
36
36
|
catch (err) {
|
|
37
|
+
if (msg.derivedKeyBytes)
|
|
38
|
+
msg.derivedKeyBytes.fill(0);
|
|
37
39
|
self.postMessage({ type: 'error', id: -1, message: err.message, isAuthError: false });
|
|
38
40
|
}
|
|
39
41
|
return;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const CTE_WASM: Uint8Array<ArrayBuffer>;
|
package/dist/cte-wasm.js
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// auto-generated, do not edit
|
|
2
|
+
// raw WASM bytes for constant-time equality comparison module
|
|
3
|
+
export const CTE_WASM = new Uint8Array([0, 97, 115, 109, 1, 0, 0, 0, 1, 8, 1, 96, 3, 127, 127, 127, 1, 127, 3, 2, 1, 0, 5, 4, 1, 1, 1, 1, 7, 20, 2, 7, 99, 111, 109, 112, 97, 114, 101, 0, 0, 6, 109, 101, 109, 111, 114, 121, 2, 0, 10, 133, 1, 1, 130, 1, 3, 2, 127, 1, 126, 1, 123, 3, 64, 32, 3, 65, 16, 106, 34, 4, 32, 2, 76, 4, 64, 32, 6, 32, 0, 32, 3, 106, 253, 0, 4, 0, 32, 1, 32, 3, 106, 253, 0, 4, 0, 253, 81, 253, 80, 33, 6, 32, 4, 33, 3, 12, 1, 11, 11, 3, 64, 32, 2, 32, 3, 74, 4, 64, 32, 5, 32, 0, 32, 3, 106, 49, 0, 0, 32, 1, 32, 3, 106, 49, 0, 0, 133, 132, 33, 5, 32, 3, 65, 1, 106, 33, 3, 12, 1, 11, 11, 66, 0, 32, 5, 32, 6, 253, 29, 0, 32, 6, 253, 29, 1, 132, 132, 34, 5, 125, 32, 5, 132, 66, 63, 135, 66, 127, 133, 167, 65, 1, 113, 11]);
|
|
Binary file
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convert a 64-byte raw r || s signature to DER per RFC 3279 §2.2.3.
|
|
3
|
+
* Output length is variable: 8 bytes minimum (r = s = 1 byte each, no
|
|
4
|
+
* sign-pad), 72 bytes maximum (both components 32 bytes with high bit
|
|
5
|
+
* set, each picking up a 0x00 sign-pad).
|
|
6
|
+
*
|
|
7
|
+
* @throws TypeError if `sig` is not a Uint8Array
|
|
8
|
+
* @throws RangeError if `sig.length !== 64`
|
|
9
|
+
*/
|
|
10
|
+
export declare function ecdsaSignatureToDer(sig: Uint8Array): Uint8Array;
|
|
11
|
+
/**
|
|
12
|
+
* Convert a DER ECDSA-P256 signature to 64-byte raw r || s. Rejects
|
|
13
|
+
* any DER syntax violation via SigningError('sig-malformed-input'):
|
|
14
|
+
* see the file-level header for the rejection rules.
|
|
15
|
+
*
|
|
16
|
+
* Semantic value rejections (r = 0, s = 0, high-s, off-range) are
|
|
17
|
+
* deferred to the WASM verify path; this function only enforces DER
|
|
18
|
+
* structure.
|
|
19
|
+
*
|
|
20
|
+
* @throws TypeError if `der` is not a Uint8Array
|
|
21
|
+
* @throws SigningError('sig-malformed-input') on any DER syntax error
|
|
22
|
+
*/
|
|
23
|
+
export declare function ecdsaSignatureFromDer(der: Uint8Array): Uint8Array;
|