leviathan-crypto 1.3.1 → 2.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 +129 -76
- package/README.md +166 -221
- package/SECURITY.md +89 -37
- package/dist/chacha20/cipher-suite.d.ts +4 -0
- package/dist/chacha20/cipher-suite.js +78 -0
- package/dist/chacha20/embedded.d.ts +1 -0
- package/dist/chacha20/embedded.js +27 -0
- package/dist/chacha20/index.d.ts +20 -7
- package/dist/chacha20/index.js +41 -14
- package/dist/chacha20/ops.d.ts +1 -1
- package/dist/chacha20/ops.js +19 -18
- package/dist/chacha20/pool-worker.js +77 -0
- package/dist/ct-wasm.d.ts +1 -0
- package/dist/ct-wasm.js +3 -0
- package/dist/ct.wasm +0 -0
- package/dist/docs/aead.md +320 -0
- package/dist/docs/architecture.md +419 -285
- package/dist/docs/argon2id.md +42 -30
- package/dist/docs/chacha20.md +218 -150
- package/dist/docs/exports.md +241 -0
- package/dist/docs/fortuna.md +65 -74
- package/dist/docs/init.md +172 -178
- package/dist/docs/loader.md +87 -132
- package/dist/docs/serpent.md +134 -565
- package/dist/docs/sha2.md +91 -103
- package/dist/docs/sha3.md +70 -36
- package/dist/docs/types.md +93 -16
- package/dist/docs/utils.md +114 -41
- package/dist/embedded/chacha20.d.ts +1 -1
- package/dist/embedded/chacha20.js +2 -1
- package/dist/embedded/kyber.d.ts +1 -0
- package/dist/embedded/kyber.js +3 -0
- package/dist/embedded/serpent.d.ts +1 -1
- package/dist/embedded/serpent.js +2 -1
- package/dist/embedded/sha2.d.ts +1 -1
- package/dist/embedded/sha2.js +2 -1
- package/dist/embedded/sha3.d.ts +1 -1
- package/dist/embedded/sha3.js +2 -1
- package/dist/errors.d.ts +10 -0
- package/dist/{serpent/seal.js → errors.js} +14 -46
- package/dist/fortuna.d.ts +2 -8
- package/dist/fortuna.js +11 -9
- package/dist/index.d.ts +25 -9
- package/dist/index.js +36 -7
- package/dist/init.d.ts +3 -7
- package/dist/init.js +18 -35
- package/dist/keccak/embedded.d.ts +1 -0
- package/dist/keccak/embedded.js +27 -0
- package/dist/keccak/index.d.ts +4 -0
- package/dist/keccak/index.js +31 -0
- package/dist/kyber/embedded.d.ts +1 -0
- package/dist/kyber/embedded.js +27 -0
- package/dist/kyber/indcpa.d.ts +49 -0
- package/dist/kyber/indcpa.js +352 -0
- package/dist/kyber/index.d.ts +38 -0
- package/dist/kyber/index.js +150 -0
- package/dist/kyber/kem.d.ts +21 -0
- package/dist/kyber/kem.js +160 -0
- package/dist/kyber/params.d.ts +14 -0
- package/dist/kyber/params.js +37 -0
- package/dist/kyber/suite.d.ts +13 -0
- package/dist/kyber/suite.js +93 -0
- package/dist/kyber/types.d.ts +98 -0
- package/dist/kyber/types.js +25 -0
- package/dist/kyber/validate.d.ts +19 -0
- package/dist/kyber/validate.js +68 -0
- package/dist/kyber.wasm +0 -0
- package/dist/loader.d.ts +19 -4
- package/dist/loader.js +91 -25
- package/dist/serpent/cipher-suite.d.ts +4 -0
- package/dist/serpent/cipher-suite.js +121 -0
- package/dist/serpent/embedded.d.ts +1 -0
- package/dist/serpent/embedded.js +27 -0
- package/dist/serpent/index.d.ts +6 -37
- package/dist/serpent/index.js +9 -118
- package/dist/serpent/pool-worker.d.ts +1 -0
- package/dist/serpent/pool-worker.js +202 -0
- package/dist/serpent/serpent-cbc.d.ts +30 -0
- package/dist/serpent/serpent-cbc.js +136 -0
- package/dist/sha2/embedded.d.ts +1 -0
- package/dist/sha2/embedded.js +27 -0
- package/dist/sha2/hkdf.js +6 -2
- package/dist/sha2/index.d.ts +3 -2
- package/dist/sha2/index.js +3 -4
- package/dist/sha3/embedded.d.ts +1 -0
- package/dist/sha3/embedded.js +27 -0
- package/dist/sha3/index.d.ts +3 -2
- package/dist/sha3/index.js +3 -4
- package/dist/stream/constants.d.ts +6 -0
- package/dist/stream/constants.js +30 -0
- package/dist/stream/header.d.ts +9 -0
- package/dist/stream/header.js +77 -0
- package/dist/stream/index.d.ts +7 -0
- package/dist/stream/index.js +27 -0
- package/dist/stream/open-stream.d.ts +21 -0
- package/dist/stream/open-stream.js +146 -0
- package/dist/stream/seal-stream-pool.d.ts +38 -0
- package/dist/stream/seal-stream-pool.js +391 -0
- package/dist/stream/seal-stream.d.ts +20 -0
- package/dist/stream/seal-stream.js +142 -0
- package/dist/stream/seal.d.ts +9 -0
- package/dist/stream/seal.js +75 -0
- package/dist/stream/types.d.ts +24 -0
- package/dist/stream/types.js +26 -0
- package/dist/utils.d.ts +12 -7
- package/dist/utils.js +75 -19
- package/dist/wasm-source.d.ts +12 -0
- package/dist/wasm-source.js +26 -0
- package/package.json +13 -5
- package/dist/chacha20/pool.d.ts +0 -52
- package/dist/chacha20/pool.js +0 -188
- package/dist/chacha20/pool.worker.js +0 -37
- package/dist/docs/chacha20_pool.md +0 -309
- package/dist/docs/wasm.md +0 -194
- package/dist/serpent/seal.d.ts +0 -8
- package/dist/serpent/stream-pool.d.ts +0 -48
- package/dist/serpent/stream-pool.js +0 -285
- package/dist/serpent/stream-sealer.d.ts +0 -50
- package/dist/serpent/stream-sealer.js +0 -341
- package/dist/serpent/stream.d.ts +0 -28
- package/dist/serpent/stream.js +0 -205
- package/dist/serpent/stream.worker.d.ts +0 -32
- package/dist/serpent/stream.worker.js +0 -117
- /package/dist/chacha20/{pool.worker.d.ts → pool-worker.d.ts} +0 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
// ▄▄▄▄▄▄▄▄▄▄
|
|
2
|
+
// ▄████████████████████▄▄ ▒ ▄▀▀ ▒ ▒ █ ▄▀▄ ▀█▀ █ ▒ ▄▀▄ █▀▄
|
|
3
|
+
// ▄██████████████████████ ▀████▄ ▓ ▓▀ ▓ ▓ ▓ ▓▄▓ ▓ ▓▀▓ ▓▄▓ ▓ ▓
|
|
4
|
+
// ▄█████████▀▀▀ ▀███████▄▄███████▌ ▀▄ ▀▄▄ ▀▄▀ ▒ ▒ ▒ ▒ ▒ █ ▒ ▒ ▒ █
|
|
5
|
+
// ▐████████▀ ▄▄▄▄ ▀████████▀██▀█▌
|
|
6
|
+
// ████████ ███▀▀ ████▀ █▀ █▀ Leviathan Crypto Library
|
|
7
|
+
// ███████▌ ▀██▀ ███
|
|
8
|
+
// ███████ ▀███ ▀██ ▀█▄ Repository & Mirror:
|
|
9
|
+
// ▀██████ ▄▄██ ▀▀ ██▄ github.com/xero/leviathan-crypto
|
|
10
|
+
// ▀█████▄ ▄██▄ ▄▀▄▀ unpkg.com/leviathan-crypto
|
|
11
|
+
// ▀████▄ ▄██▄
|
|
12
|
+
// ▐████ ▐███ Author: xero (https://x-e.ro)
|
|
13
|
+
// ▄▄██████████ ▐███ ▄▄ License: MIT
|
|
14
|
+
// ▄██▀▀▀▀▀▀▀▀▀▀ ▄████ ▄██▀
|
|
15
|
+
// ▄▀ ▄▄█████████▄▄ ▀▀▀▀▀ ▄███ This file is provided completely
|
|
16
|
+
// ▄██████▀▀▀▀▀▀██████▄ ▀▄▄▄▄████▀ free, "as is", and without
|
|
17
|
+
// ████▀ ▄▄▄▄▄▄▄ ▀████▄ ▀█████▀ ▄▄▄▄ warranty of any kind. The author
|
|
18
|
+
// █████▄▄█████▀▀▀▀▀▀▄ ▀███▄ ▄████ assumes absolutely no liability
|
|
19
|
+
// ▀██████▀ ▀████▄▄▄████▀ for its {ab,mis,}use.
|
|
20
|
+
// ▀█████▀▀
|
|
21
|
+
//
|
|
22
|
+
// src/ts/stream/seal-stream.ts
|
|
23
|
+
//
|
|
24
|
+
// SealStream — cipher-agnostic streaming encryption using the STREAM
|
|
25
|
+
// construction (Hoang/Reyhanitabar/Rogaway/Vizár, CRYPTO 2015).
|
|
26
|
+
import { randomBytes, concat } from '../utils.js';
|
|
27
|
+
import { isInitialized } from '../init.js';
|
|
28
|
+
import { CHUNK_MIN, CHUNK_MAX, TAG_DATA, TAG_FINAL } from './constants.js';
|
|
29
|
+
import { writeHeader, makeCounterNonce } from './header.js';
|
|
30
|
+
function u32beFrame(n) {
|
|
31
|
+
const b = new Uint8Array(4);
|
|
32
|
+
new DataView(b.buffer).setUint32(0, n, false);
|
|
33
|
+
return b;
|
|
34
|
+
}
|
|
35
|
+
// Module-level nonce injection slot — used only by _fromNonce for KAT tests.
|
|
36
|
+
// Set immediately before constructing, cleared inside the constructor.
|
|
37
|
+
let _injectNonce;
|
|
38
|
+
export class SealStream {
|
|
39
|
+
/** Preamble sent before the first chunk: header [|| kemCiphertext]. */
|
|
40
|
+
preamble;
|
|
41
|
+
cipher;
|
|
42
|
+
keys;
|
|
43
|
+
chunkSize;
|
|
44
|
+
framed;
|
|
45
|
+
counter = 0;
|
|
46
|
+
state = 'ready';
|
|
47
|
+
constructor(cipher, key, opts) {
|
|
48
|
+
this.cipher = cipher;
|
|
49
|
+
this.chunkSize = opts?.chunkSize ?? 65536;
|
|
50
|
+
this.framed = opts?.framed ?? false;
|
|
51
|
+
if (!isInitialized('sha2'))
|
|
52
|
+
throw new Error('leviathan-crypto: stream layer requires sha2 for key derivation — '
|
|
53
|
+
+ 'call init({ sha2: ... }) before creating a SealStream');
|
|
54
|
+
if (key.length !== cipher.keySize)
|
|
55
|
+
throw new RangeError(`key must be ${cipher.keySize} bytes (got ${key.length})`);
|
|
56
|
+
if (this.chunkSize < CHUNK_MIN || this.chunkSize > CHUNK_MAX)
|
|
57
|
+
throw new RangeError(`chunkSize must be in [${CHUNK_MIN}, ${CHUNK_MAX}] (got ${this.chunkSize})`);
|
|
58
|
+
const nonce = _injectNonce ?? randomBytes(16);
|
|
59
|
+
_injectNonce = undefined;
|
|
60
|
+
this.keys = cipher.deriveKeys(key, nonce);
|
|
61
|
+
const kemCt = this.keys.kemCiphertext;
|
|
62
|
+
const header = writeHeader(cipher.formatEnum, this.framed, nonce, this.chunkSize);
|
|
63
|
+
this.preamble = kemCt ? concat(header, kemCt) : header;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* @internal
|
|
67
|
+
* KAT-only factory — injects a fixed nonce so seal output is deterministic.
|
|
68
|
+
* Stripped from published `.d.ts` by `stripInternal`. Do not use in production.
|
|
69
|
+
*/
|
|
70
|
+
static _fromNonce(cipher, key, opts, nonce) {
|
|
71
|
+
if (nonce.length !== 16)
|
|
72
|
+
throw new RangeError(`_nonce must be 16 bytes (got ${nonce.length})`);
|
|
73
|
+
_injectNonce = nonce;
|
|
74
|
+
try {
|
|
75
|
+
return new SealStream(cipher, key, opts);
|
|
76
|
+
}
|
|
77
|
+
finally {
|
|
78
|
+
_injectNonce = undefined;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
push(chunk, opts) {
|
|
82
|
+
if (this.state !== 'ready')
|
|
83
|
+
throw new Error('SealStream: cannot push after finalize');
|
|
84
|
+
if (chunk.length > this.chunkSize)
|
|
85
|
+
throw new RangeError(`chunk exceeds chunkSize (${chunk.length} > ${this.chunkSize})`);
|
|
86
|
+
const nonce = makeCounterNonce(this.counter, TAG_DATA);
|
|
87
|
+
const result = this.cipher.sealChunk(this.keys, nonce, chunk, opts?.aad);
|
|
88
|
+
this.counter++;
|
|
89
|
+
return this.framed ? concat(u32beFrame(result.length), result) : result;
|
|
90
|
+
}
|
|
91
|
+
finalize(chunk, opts) {
|
|
92
|
+
if (this.state !== 'ready')
|
|
93
|
+
throw new Error('SealStream: already finalized');
|
|
94
|
+
if (chunk.length > this.chunkSize)
|
|
95
|
+
throw new RangeError(`chunk exceeds chunkSize (${chunk.length} > ${this.chunkSize})`);
|
|
96
|
+
const nonce = makeCounterNonce(this.counter, TAG_FINAL);
|
|
97
|
+
const result = this.cipher.sealChunk(this.keys, nonce, chunk, opts?.aad);
|
|
98
|
+
this.cipher.wipeKeys(this.keys);
|
|
99
|
+
this.state = 'finalized';
|
|
100
|
+
return this.framed ? concat(u32beFrame(result.length), result) : result;
|
|
101
|
+
}
|
|
102
|
+
dispose() {
|
|
103
|
+
if (this.state === 'ready') {
|
|
104
|
+
this.cipher.wipeKeys(this.keys);
|
|
105
|
+
this.state = 'finalized';
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
toTransformStream() {
|
|
109
|
+
let headerSent = false;
|
|
110
|
+
let buffered = null;
|
|
111
|
+
return new TransformStream({
|
|
112
|
+
transform: (chunk, controller) => {
|
|
113
|
+
try {
|
|
114
|
+
if (!headerSent) {
|
|
115
|
+
controller.enqueue(this.preamble);
|
|
116
|
+
headerSent = true;
|
|
117
|
+
}
|
|
118
|
+
if (buffered !== null) {
|
|
119
|
+
controller.enqueue(this.push(buffered));
|
|
120
|
+
}
|
|
121
|
+
buffered = chunk;
|
|
122
|
+
}
|
|
123
|
+
catch (err) {
|
|
124
|
+
this.dispose();
|
|
125
|
+
throw err;
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
flush: (controller) => {
|
|
129
|
+
try {
|
|
130
|
+
if (!headerSent) {
|
|
131
|
+
controller.enqueue(this.preamble);
|
|
132
|
+
}
|
|
133
|
+
controller.enqueue(this.finalize(buffered ?? new Uint8Array(0)));
|
|
134
|
+
}
|
|
135
|
+
catch (err) {
|
|
136
|
+
this.dispose();
|
|
137
|
+
throw err;
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { CipherSuite } from './types.js';
|
|
2
|
+
export declare class Seal {
|
|
3
|
+
static encrypt(suite: CipherSuite, key: Uint8Array, pt: Uint8Array, opts?: {
|
|
4
|
+
aad?: Uint8Array;
|
|
5
|
+
}): Uint8Array;
|
|
6
|
+
static decrypt(suite: CipherSuite, key: Uint8Array, blob: Uint8Array, opts?: {
|
|
7
|
+
aad?: Uint8Array;
|
|
8
|
+
}): Uint8Array;
|
|
9
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// ▄▄▄▄▄▄▄▄▄▄
|
|
2
|
+
// ▄████████████████████▄▄ ▒ ▄▀▀ ▒ ▒ █ ▄▀▄ ▀█▀ █ ▒ ▄▀▄ █▀▄
|
|
3
|
+
// ▄██████████████████████ ▀████▄ ▓ ▓▀ ▓ ▓ ▓ ▓▄▓ ▓ ▓▀▓ ▓▄▓ ▓ ▓
|
|
4
|
+
// ▄█████████▀▀▀ ▀███████▄▄███████▌ ▀▄ ▀▄▄ ▀▄▀ ▒ ▒ ▒ ▒ ▒ █ ▒ ▒ ▒ █
|
|
5
|
+
// ▐████████▀ ▄▄▄▄ ▀████████▀██▀█▌
|
|
6
|
+
// ████████ ███▀▀ ████▀ █▀ █▀ Leviathan Crypto Library
|
|
7
|
+
// ███████▌ ▀██▀ ███
|
|
8
|
+
// ███████ ▀███ ▀██ ▀█▄ Repository & Mirror:
|
|
9
|
+
// ▀██████ ▄▄██ ▀▀ ██▄ github.com/xero/leviathan-crypto
|
|
10
|
+
// ▀█████▄ ▄██▄ ▄▀▄▀ unpkg.com/leviathan-crypto
|
|
11
|
+
// ▀████▄ ▄██▄
|
|
12
|
+
// ▐████ ▐███ Author: xero (https://x-e.ro)
|
|
13
|
+
// ▄▄██████████ ▐███ ▄▄ License: MIT
|
|
14
|
+
// ▄██▀▀▀▀▀▀▀▀▀▀ ▄████ ▄██▀
|
|
15
|
+
// ▄▀ ▄▄█████████▄▄ ▀▀▀▀▀ ▄███ This file is provided completely
|
|
16
|
+
// ▄██████▀▀▀▀▀▀██████▄ ▀▄▄▄▄████▀ free, "as is", and without
|
|
17
|
+
// ████▀ ▄▄▄▄▄▄▄ ▀████▄ ▀█████▀ ▄▄▄▄ warranty of any kind. The author
|
|
18
|
+
// █████▄▄█████▀▀▀▀▀▀▄ ▀███▄ ▄████ assumes absolutely no liability
|
|
19
|
+
// ▀██████▀ ▀████▄▄▄████▀ for its {ab,mis,}use.
|
|
20
|
+
// ▀█████▀▀
|
|
21
|
+
//
|
|
22
|
+
// src/ts/stream/seal.ts
|
|
23
|
+
//
|
|
24
|
+
// Seal — unified single-shot encrypt/decrypt using the STREAM construction.
|
|
25
|
+
// Seal blobs are valid SealStream blobs with a single final chunk.
|
|
26
|
+
// OpenStream can decrypt a Seal blob without modification.
|
|
27
|
+
import { concat } from '../utils.js';
|
|
28
|
+
import { SealStream } from './seal-stream.js';
|
|
29
|
+
import { OpenStream } from './open-stream.js';
|
|
30
|
+
import { HEADER_SIZE, CHUNK_MAX, CHUNK_MIN } from './constants.js';
|
|
31
|
+
// eslint-disable-next-line @typescript-eslint/no-extraneous-class -- static-only class required for stripInternal to strip _fromNonce from .d.ts
|
|
32
|
+
export class Seal {
|
|
33
|
+
static encrypt(suite, key, pt, opts) {
|
|
34
|
+
if (pt.length > CHUNK_MAX)
|
|
35
|
+
throw new RangeError(`Seal.encrypt: plaintext exceeds maximum (${CHUNK_MAX} bytes) — use SealStream for large data`);
|
|
36
|
+
const sealer = new SealStream(suite, key, { chunkSize: Math.max(pt.length, CHUNK_MIN) });
|
|
37
|
+
try {
|
|
38
|
+
const ct = sealer.finalize(pt, opts);
|
|
39
|
+
return concat(sealer.preamble, ct);
|
|
40
|
+
}
|
|
41
|
+
finally {
|
|
42
|
+
sealer.dispose();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
static decrypt(suite, key, blob, opts) {
|
|
46
|
+
const preambleLen = HEADER_SIZE + suite.kemCtSize;
|
|
47
|
+
if (blob.length < preambleLen)
|
|
48
|
+
throw new RangeError(`Seal.decrypt: blob too short — need at least ${preambleLen} bytes (got ${blob.length})`);
|
|
49
|
+
const preamble = blob.subarray(0, preambleLen);
|
|
50
|
+
const opener = new OpenStream(suite, key, preamble);
|
|
51
|
+
try {
|
|
52
|
+
return opener.finalize(blob.subarray(preambleLen), opts);
|
|
53
|
+
}
|
|
54
|
+
finally {
|
|
55
|
+
opener.dispose();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* @internal
|
|
60
|
+
* KAT-only — injects a fixed nonce so output is deterministic.
|
|
61
|
+
* Stripped from published `.d.ts` by `stripInternal`. Do not use in production.
|
|
62
|
+
*/
|
|
63
|
+
static _fromNonce(suite, key, pt, nonce, opts) {
|
|
64
|
+
if (pt.length > CHUNK_MAX)
|
|
65
|
+
throw new RangeError(`Seal._fromNonce: plaintext exceeds maximum (${CHUNK_MAX} bytes) — use SealStream for large data`);
|
|
66
|
+
const sealer = SealStream._fromNonce(suite, key, { chunkSize: Math.max(pt.length, CHUNK_MIN) }, nonce);
|
|
67
|
+
try {
|
|
68
|
+
const ct = sealer.finalize(pt, opts);
|
|
69
|
+
return concat(sealer.preamble, ct);
|
|
70
|
+
}
|
|
71
|
+
finally {
|
|
72
|
+
sealer.dispose();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface DerivedKeys {
|
|
2
|
+
readonly bytes: Uint8Array;
|
|
3
|
+
readonly kemCiphertext?: Uint8Array;
|
|
4
|
+
}
|
|
5
|
+
export interface CipherSuite {
|
|
6
|
+
readonly formatEnum: number;
|
|
7
|
+
readonly formatName: string;
|
|
8
|
+
readonly hkdfInfo: string;
|
|
9
|
+
readonly keySize: number;
|
|
10
|
+
readonly decKeySize?: number;
|
|
11
|
+
readonly kemCtSize: number;
|
|
12
|
+
readonly tagSize: number;
|
|
13
|
+
readonly padded: boolean;
|
|
14
|
+
deriveKeys(key: Uint8Array, nonce: Uint8Array, kemCt?: Uint8Array): DerivedKeys;
|
|
15
|
+
sealChunk(keys: DerivedKeys, counterNonce: Uint8Array, chunk: Uint8Array, aad?: Uint8Array): Uint8Array;
|
|
16
|
+
openChunk(keys: DerivedKeys, counterNonce: Uint8Array, chunk: Uint8Array, aad?: Uint8Array): Uint8Array;
|
|
17
|
+
wipeKeys(keys: DerivedKeys): void;
|
|
18
|
+
readonly wasmModules: readonly string[];
|
|
19
|
+
createPoolWorker(): Worker;
|
|
20
|
+
}
|
|
21
|
+
export interface SealStreamOpts {
|
|
22
|
+
chunkSize?: number;
|
|
23
|
+
framed?: boolean;
|
|
24
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// ▄▄▄▄▄▄▄▄▄▄
|
|
2
|
+
// ▄████████████████████▄▄ ▒ ▄▀▀ ▒ ▒ █ ▄▀▄ ▀█▀ █ ▒ ▄▀▄ █▀▄
|
|
3
|
+
// ▄██████████████████████ ▀████▄ ▓ ▓▀ ▓ ▓ ▓ ▓▄▓ ▓ ▓▀▓ ▓▄▓ ▓ ▓
|
|
4
|
+
// ▄█████████▀▀▀ ▀███████▄▄███████▌ ▀▄ ▀▄▄ ▀▄▀ ▒ ▒ ▒ ▒ ▒ █ ▒ ▒ ▒ █
|
|
5
|
+
// ▐████████▀ ▄▄▄▄ ▀████████▀██▀█▌
|
|
6
|
+
// ████████ ███▀▀ ████▀ █▀ █▀ Leviathan Crypto Library
|
|
7
|
+
// ███████▌ ▀██▀ ███
|
|
8
|
+
// ███████ ▀███ ▀██ ▀█▄ Repository & Mirror:
|
|
9
|
+
// ▀██████ ▄▄██ ▀▀ ██▄ github.com/xero/leviathan-crypto
|
|
10
|
+
// ▀█████▄ ▄██▄ ▄▀▄▀ unpkg.com/leviathan-crypto
|
|
11
|
+
// ▀████▄ ▄██▄
|
|
12
|
+
// ▐████ ▐███ Author: xero (https://x-e.ro)
|
|
13
|
+
// ▄▄██████████ ▐███ ▄▄ License: MIT
|
|
14
|
+
// ▄██▀▀▀▀▀▀▀▀▀▀ ▄████ ▄██▀
|
|
15
|
+
// ▄▀ ▄▄█████████▄▄ ▀▀▀▀▀ ▄███ This file is provided completely
|
|
16
|
+
// ▄██████▀▀▀▀▀▀██████▄ ▀▄▄▄▄████▀ free, "as is", and without
|
|
17
|
+
// ████▀ ▄▄▄▄▄▄▄ ▀████▄ ▀█████▀ ▄▄▄▄ warranty of any kind. The author
|
|
18
|
+
// █████▄▄█████▀▀▀▀▀▀▄ ▀███▄ ▄████ assumes absolutely no liability
|
|
19
|
+
// ▀██████▀ ▀████▄▄▄████▀ for its {ab,mis,}use.
|
|
20
|
+
// ▀█████▀▀
|
|
21
|
+
//
|
|
22
|
+
// src/ts/stream/types.ts
|
|
23
|
+
//
|
|
24
|
+
// CipherSuite interface — cipher-specific logic injected into SealStream
|
|
25
|
+
// and OpenStream. Implementations are plain objects (not classes).
|
|
26
|
+
export {};
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** Hex string to Uint8Array. Accepts lowercase/uppercase, optional 0x prefix. */
|
|
1
|
+
/** Hex string to Uint8Array. Accepts lowercase/uppercase, optional 0x prefix. Throws RangeError on odd-length input. */
|
|
2
2
|
export declare const hexToBytes: (hex: string) => Uint8Array;
|
|
3
3
|
/** Uint8Array to lowercase hex string. */
|
|
4
4
|
export declare const bytesToHex: (bytes: Uint8Array) => string;
|
|
@@ -6,26 +6,31 @@ export declare const bytesToHex: (bytes: Uint8Array) => string;
|
|
|
6
6
|
export declare const utf8ToBytes: (str: string) => Uint8Array;
|
|
7
7
|
/** Uint8Array to UTF-8 string. */
|
|
8
8
|
export declare const bytesToUtf8: (bytes: Uint8Array) => string;
|
|
9
|
-
/** Base64 or base64url string to Uint8Array. Returns undefined on invalid input. */
|
|
9
|
+
/** Base64 or base64url string to Uint8Array. Handles padded, unpadded, and legacy %3d padding. Returns undefined on invalid input. */
|
|
10
10
|
export declare const base64ToBytes: (b64: string) => Uint8Array | undefined;
|
|
11
|
-
/** Uint8Array to base64 string. Pass url=true for base64url
|
|
11
|
+
/** Uint8Array to base64 string. Pass url=true for base64url (RFC 4648 §5 — no padding characters). */
|
|
12
12
|
export declare const bytesToBase64: (bytes: Uint8Array, url?: boolean) => string;
|
|
13
|
+
export declare const CT_MAX_BYTES = 32768;
|
|
13
14
|
/**
|
|
14
15
|
* Constant-time byte-array equality.
|
|
15
|
-
*
|
|
16
|
+
* Uses WASM SIMD when available (no JIT short-circuiting, no speculative
|
|
17
|
+
* optimization). Falls back to a JS XOR-accumulate loop on runtimes
|
|
18
|
+
* without SIMD support.
|
|
16
19
|
* Length check is not constant-time (length is non-secret in all protocols).
|
|
20
|
+
* Max input size: 32768 bytes per side (enforced regardless of code path).
|
|
17
21
|
*/
|
|
18
22
|
export declare const constantTimeEqual: (a: Uint8Array, b: Uint8Array) => boolean;
|
|
19
23
|
/** Zero a typed array in place. */
|
|
20
24
|
export declare const wipe: (data: Uint8Array | Uint16Array | Uint32Array) => void;
|
|
21
25
|
/** XOR two equal-length Uint8Arrays, returns new array. */
|
|
22
26
|
export declare const xor: (a: Uint8Array, b: Uint8Array) => Uint8Array;
|
|
23
|
-
/** Concatenate
|
|
24
|
-
export declare const concat: (
|
|
27
|
+
/** Concatenate one or more Uint8Arrays into a new array. */
|
|
28
|
+
export declare const concat: (...arrays: Uint8Array[]) => Uint8Array;
|
|
25
29
|
/** Cryptographically secure random bytes via Web Crypto API. */
|
|
26
30
|
export declare const randomBytes: (n: number) => Uint8Array;
|
|
27
31
|
/**
|
|
28
32
|
* Detects WASM SIMD support once and caches the result.
|
|
29
|
-
*
|
|
33
|
+
* Used by init() to preflight-check before loading serpent/chacha20 modules.
|
|
34
|
+
* Exported for consumers who want to feature-detect before calling init().
|
|
30
35
|
*/
|
|
31
36
|
export declare function hasSIMD(): boolean;
|
package/dist/utils.js
CHANGED
|
@@ -24,12 +24,12 @@
|
|
|
24
24
|
// Pure TypeScript utilities — no init() dependency.
|
|
25
25
|
// Ported from leviathan/src/base.ts (Convert namespace, Util namespace, constantTimeEqual).
|
|
26
26
|
// ── Encoding ─────────────────────────────────────────────────────────────────
|
|
27
|
-
/** Hex string to Uint8Array. Accepts lowercase/uppercase, optional 0x prefix. */
|
|
27
|
+
/** Hex string to Uint8Array. Accepts lowercase/uppercase, optional 0x prefix. Throws RangeError on odd-length input. */
|
|
28
28
|
export const hexToBytes = (hex) => {
|
|
29
29
|
if (hex.startsWith('0x') || hex.startsWith('0X'))
|
|
30
30
|
hex = hex.slice(2);
|
|
31
31
|
if (hex.length % 2)
|
|
32
|
-
hex
|
|
32
|
+
throw new RangeError(`hexToBytes: odd-length string (${hex.length} chars) — input must be an even-length hex string`);
|
|
33
33
|
const bin = new Uint8Array(hex.length >>> 1);
|
|
34
34
|
for (let i = 0, len = hex.length >>> 1; i < len; i++)
|
|
35
35
|
bin[i] = parseInt(hex.slice(i << 1, (i << 1) + 2), 16);
|
|
@@ -51,12 +51,18 @@ export const utf8ToBytes = (str) => {
|
|
|
51
51
|
export const bytesToUtf8 = (bytes) => {
|
|
52
52
|
return new TextDecoder().decode(bytes);
|
|
53
53
|
};
|
|
54
|
-
/** Base64 or base64url string to Uint8Array. Returns undefined on invalid input. */
|
|
54
|
+
/** Base64 or base64url string to Uint8Array. Handles padded, unpadded, and legacy %3d padding. Returns undefined on invalid input. */
|
|
55
55
|
export const base64ToBytes = (b64) => {
|
|
56
56
|
// Normalise base64url → base64
|
|
57
|
-
b64 = b64.replace(/-/g, '+').replace(/_/g, '/').replace(/%3d/
|
|
58
|
-
if (
|
|
59
|
-
|
|
57
|
+
b64 = b64.replace(/-/g, '+').replace(/_/g, '/').replace(/%3d/gi, '=');
|
|
58
|
+
// Re-pad if unpadded (RFC 4648 §5 base64url omits '=')
|
|
59
|
+
const rem = b64.length % 4;
|
|
60
|
+
if (rem === 1)
|
|
61
|
+
return undefined; // always invalid — no valid b64 produces this
|
|
62
|
+
if (rem === 2)
|
|
63
|
+
b64 += '==';
|
|
64
|
+
if (rem === 3)
|
|
65
|
+
b64 += '=';
|
|
60
66
|
if (!/^[A-Za-z0-9+/]*={0,2}$/.test(b64))
|
|
61
67
|
return undefined;
|
|
62
68
|
let strlen = b64.length / 4 * 3;
|
|
@@ -104,11 +110,11 @@ export const base64ToBytes = (b64) => {
|
|
|
104
110
|
}
|
|
105
111
|
return bin;
|
|
106
112
|
};
|
|
107
|
-
/** Uint8Array to base64 string. Pass url=true for base64url
|
|
113
|
+
/** Uint8Array to base64 string. Pass url=true for base64url (RFC 4648 §5 — no padding characters). */
|
|
108
114
|
export const bytesToBase64 = (bytes, url = false) => {
|
|
109
115
|
if (typeof btoa !== 'undefined') {
|
|
110
116
|
const raw = btoa(String.fromCharCode.apply(null, Array.from(bytes)));
|
|
111
|
-
return url ? raw.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '
|
|
117
|
+
return url ? raw.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '') : raw;
|
|
112
118
|
}
|
|
113
119
|
// Fallback: manual encode
|
|
114
120
|
const table = url
|
|
@@ -125,20 +131,65 @@ export const bytesToBase64 = (bytes, url = false) => {
|
|
|
125
131
|
const triple = (a << 0x10) + (b << 0x08) + c;
|
|
126
132
|
base64 += table.charAt((triple >>> 18) & 0x3F);
|
|
127
133
|
base64 += table.charAt((triple >>> 12) & 0x3F);
|
|
128
|
-
base64 += (i < bytes.length + 2) ? table.charAt((triple >>> 6) & 0x3F) : (url ? '
|
|
129
|
-
base64 += (i < bytes.length + 1) ? table.charAt(triple & 0x3F) : (url ? '
|
|
134
|
+
base64 += (i < bytes.length + 2) ? table.charAt((triple >>> 6) & 0x3F) : (url ? '' : '=');
|
|
135
|
+
base64 += (i < bytes.length + 1) ? table.charAt(triple & 0x3F) : (url ? '' : '=');
|
|
130
136
|
}
|
|
131
137
|
return base64;
|
|
132
138
|
};
|
|
133
|
-
// ──
|
|
139
|
+
// ── Constant-time comparison ─────────────────────────────────────────────────
|
|
140
|
+
import { CT_WASM } from './ct-wasm.js';
|
|
141
|
+
let _ctCompare = null;
|
|
142
|
+
let _ctMem = null;
|
|
143
|
+
let _ctInit = false;
|
|
144
|
+
// CT WASM module uses 1 page (64KB) of linear memory with both buffers
|
|
145
|
+
// laid out side-by-side: a at offset 0, b at offset a.length.
|
|
146
|
+
// Max per-side = _ctMem.buffer.byteLength >>> 1 = 32768 bytes.
|
|
147
|
+
// In practice the largest comparison is a 32-byte HMAC-SHA-256 tag.
|
|
148
|
+
export const CT_MAX_BYTES = 32768;
|
|
149
|
+
/** Try to compile the SIMD WASM ct module. Returns false if unavailable. */
|
|
150
|
+
function _initCt() {
|
|
151
|
+
if (_ctInit)
|
|
152
|
+
return _ctCompare !== null;
|
|
153
|
+
_ctInit = true;
|
|
154
|
+
try {
|
|
155
|
+
if (!hasSIMD())
|
|
156
|
+
return false;
|
|
157
|
+
_ctMem = new WebAssembly.Memory({ initial: 1, maximum: 1 });
|
|
158
|
+
const buf = CT_WASM.buffer.slice(CT_WASM.byteOffset, CT_WASM.byteOffset + CT_WASM.byteLength);
|
|
159
|
+
const mod = new WebAssembly.Module(buf);
|
|
160
|
+
const inst = new WebAssembly.Instance(mod, { env: { memory: _ctMem } });
|
|
161
|
+
_ctCompare = inst.exports.compare;
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
134
168
|
/**
|
|
135
169
|
* Constant-time byte-array equality.
|
|
136
|
-
*
|
|
170
|
+
* Uses WASM SIMD when available (no JIT short-circuiting, no speculative
|
|
171
|
+
* optimization). Falls back to a JS XOR-accumulate loop on runtimes
|
|
172
|
+
* without SIMD support.
|
|
137
173
|
* Length check is not constant-time (length is non-secret in all protocols).
|
|
174
|
+
* Max input size: 32768 bytes per side (enforced regardless of code path).
|
|
138
175
|
*/
|
|
139
176
|
export const constantTimeEqual = (a, b) => {
|
|
140
177
|
if (a.length !== b.length)
|
|
141
178
|
return false;
|
|
179
|
+
if (a.length > CT_MAX_BYTES)
|
|
180
|
+
throw new RangeError(`constantTimeEqual: max ${CT_MAX_BYTES} bytes (got ${a.length})`);
|
|
181
|
+
if (_initCt() && _ctMem && _ctCompare) {
|
|
182
|
+
const mem = new Uint8Array(_ctMem.buffer);
|
|
183
|
+
mem.set(a, 0);
|
|
184
|
+
mem.set(b, a.length);
|
|
185
|
+
try {
|
|
186
|
+
return _ctCompare(0, a.length, a.length) === 1;
|
|
187
|
+
}
|
|
188
|
+
finally {
|
|
189
|
+
mem.fill(0, 0, a.length * 2);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
// JS fallback — best-effort constant-time via XOR accumulate
|
|
142
193
|
let diff = 0;
|
|
143
194
|
for (let i = 0; i < a.length; i++)
|
|
144
195
|
diff |= a[i] ^ b[i];
|
|
@@ -154,12 +205,16 @@ export const xor = (a, b) => {
|
|
|
154
205
|
throw new RangeError(`xor: length mismatch (${a.length} vs ${b.length})`);
|
|
155
206
|
return a.map((val, i) => val ^ b[i]);
|
|
156
207
|
};
|
|
157
|
-
/** Concatenate
|
|
158
|
-
export const concat = (
|
|
159
|
-
const
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
208
|
+
/** Concatenate one or more Uint8Arrays into a new array. */
|
|
209
|
+
export const concat = (...arrays) => {
|
|
210
|
+
const len = arrays.reduce((s, a) => s + a.length, 0);
|
|
211
|
+
const out = new Uint8Array(len);
|
|
212
|
+
let off = 0;
|
|
213
|
+
for (const a of arrays) {
|
|
214
|
+
out.set(a, off);
|
|
215
|
+
off += a.length;
|
|
216
|
+
}
|
|
217
|
+
return out;
|
|
163
218
|
};
|
|
164
219
|
/** Cryptographically secure random bytes via Web Crypto API. */
|
|
165
220
|
export const randomBytes = (n) => {
|
|
@@ -171,7 +226,8 @@ export const randomBytes = (n) => {
|
|
|
171
226
|
let _simd = null;
|
|
172
227
|
/**
|
|
173
228
|
* Detects WASM SIMD support once and caches the result.
|
|
174
|
-
*
|
|
229
|
+
* Used by init() to preflight-check before loading serpent/chacha20 modules.
|
|
230
|
+
* Exported for consumers who want to feature-detect before calling init().
|
|
175
231
|
*/
|
|
176
232
|
export function hasSIMD() {
|
|
177
233
|
if (_simd !== null)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* All accepted forms of WASM input for init functions.
|
|
3
|
+
*
|
|
4
|
+
* - `string` — gzip+base64 embedded blob (from `/embedded` subpath)
|
|
5
|
+
* - `URL` — fetched via `WebAssembly.instantiateStreaming`
|
|
6
|
+
* - `ArrayBuffer` — raw WASM bytes, compiled inline
|
|
7
|
+
* - `Uint8Array` — raw WASM bytes, compiled inline
|
|
8
|
+
* - `WebAssembly.Module` — pre-compiled module (Cloudflare Workers, edge runtimes)
|
|
9
|
+
* - `Response` — streaming instantiation from an in-flight fetch response
|
|
10
|
+
* - `Promise<Response>` — streaming instantiation from a deferred fetch
|
|
11
|
+
*/
|
|
12
|
+
export type WasmSource = string | URL | ArrayBuffer | Uint8Array | WebAssembly.Module | Response | Promise<Response>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// ▄▄▄▄▄▄▄▄▄▄
|
|
2
|
+
// ▄████████████████████▄▄ ▒ ▄▀▀ ▒ ▒ █ ▄▀▄ ▀█▀ █ ▒ ▄▀▄ █▀▄
|
|
3
|
+
// ▄██████████████████████ ▀████▄ ▓ ▓▀ ▓ ▓ ▓ ▓▄▓ ▓ ▓▀▓ ▓▄▓ ▓ ▓
|
|
4
|
+
// ▄█████████▀▀▀ ▀███████▄▄███████▌ ▀▄ ▀▄▄ ▀▄▀ ▒ ▒ ▒ ▒ ▒ █ ▒ ▒ ▒ █
|
|
5
|
+
// ▐████████▀ ▄▄▄▄ ▀████████▀██▀█▌
|
|
6
|
+
// ████████ ███▀▀ ████▀ █▀ █▀ Leviathan Crypto Library
|
|
7
|
+
// ███████▌ ▀██▀ ███
|
|
8
|
+
// ███████ ▀███ ▀██ ▀█▄ Repository & Mirror:
|
|
9
|
+
// ▀██████ ▄▄██ ▀▀ ██▄ github.com/xero/leviathan-crypto
|
|
10
|
+
// ▀█████▄ ▄██▄ ▄▀▄▀ unpkg.com/leviathan-crypto
|
|
11
|
+
// ▀████▄ ▄██▄
|
|
12
|
+
// ▐████ ▐███ Author: xero (https://x-e.ro)
|
|
13
|
+
// ▄▄██████████ ▐███ ▄▄ License: MIT
|
|
14
|
+
// ▄██▀▀▀▀▀▀▀▀▀▀ ▄████ ▄██▀
|
|
15
|
+
// ▄▀ ▄▄█████████▄▄ ▀▀▀▀▀ ▄███ This file is provided completely
|
|
16
|
+
// ▄██████▀▀▀▀▀▀██████▄ ▀▄▄▄▄████▀ free, "as is", and without
|
|
17
|
+
// ████▀ ▄▄▄▄▄▄▄ ▀████▄ ▀█████▀ ▄▄▄▄ warranty of any kind. The author
|
|
18
|
+
// █████▄▄█████▀▀▀▀▀▀▄ ▀███▄ ▄████ assumes absolutely no liability
|
|
19
|
+
// ▀██████▀ ▀████▄▄▄████▀ for its {ab,mis,}use.
|
|
20
|
+
// ▀█████▀▀
|
|
21
|
+
//
|
|
22
|
+
// src/ts/wasm-source.ts
|
|
23
|
+
//
|
|
24
|
+
// Union type for all accepted WASM loading strategies.
|
|
25
|
+
// The argument type determines the loading path — no mode string required.
|
|
26
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,18 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "leviathan-crypto",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"author": "xero (https://x-e.ro)",
|
|
5
5
|
"license": "MIT",
|
|
6
|
-
"description": "Zero-dependency
|
|
6
|
+
"description": "Zero-dependency WASM cryptography for TypeScript. Paranoid ciphers, post-quantum key encapsulation, and Fortuna CSPRNG behind a strictly typed API. All computation runs outside the JS JIT on vector-verified primitives.",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"sideEffects": false,
|
|
9
9
|
"exports": {
|
|
10
10
|
".": "./dist/index.js",
|
|
11
|
+
"./stream": "./dist/stream/index.js",
|
|
11
12
|
"./serpent": "./dist/serpent/index.js",
|
|
13
|
+
"./serpent/embedded": "./dist/serpent/embedded.js",
|
|
12
14
|
"./chacha20": "./dist/chacha20/index.js",
|
|
13
|
-
"./chacha20/
|
|
15
|
+
"./chacha20/embedded": "./dist/chacha20/embedded.js",
|
|
14
16
|
"./sha2": "./dist/sha2/index.js",
|
|
15
|
-
"./
|
|
17
|
+
"./sha2/embedded": "./dist/sha2/embedded.js",
|
|
18
|
+
"./sha3": "./dist/sha3/index.js",
|
|
19
|
+
"./sha3/embedded": "./dist/sha3/embedded.js",
|
|
20
|
+
"./keccak": "./dist/keccak/index.js",
|
|
21
|
+
"./keccak/embedded": "./dist/keccak/embedded.js",
|
|
22
|
+
"./kyber": "./dist/kyber/index.js",
|
|
23
|
+
"./kyber/embedded": "./dist/kyber/embedded.js"
|
|
16
24
|
},
|
|
17
25
|
"types": "./dist/index.d.ts",
|
|
18
26
|
"files": [
|
|
@@ -24,7 +32,7 @@
|
|
|
24
32
|
"type": "git",
|
|
25
33
|
"url": "git+https://github.com/xero/leviathan-crypto.git"
|
|
26
34
|
},
|
|
27
|
-
"homepage": "https://
|
|
35
|
+
"homepage": "https://leviathan.3xi.club",
|
|
28
36
|
"bugs": {
|
|
29
37
|
"url": "https://github.com/xero/leviathan-crypto/issues"
|
|
30
38
|
},
|
package/dist/chacha20/pool.d.ts
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
export interface PoolOpts {
|
|
2
|
-
/** Number of workers. Default: navigator.hardwareConcurrency ?? 4 */
|
|
3
|
-
workers?: number;
|
|
4
|
-
}
|
|
5
|
-
/**
|
|
6
|
-
* Parallel worker pool for XChaCha20-Poly1305 AEAD.
|
|
7
|
-
*
|
|
8
|
-
* Each worker owns its own `WebAssembly.Instance` with isolated linear memory.
|
|
9
|
-
* Jobs are dispatched round-robin to idle workers; excess jobs queue until a
|
|
10
|
-
* worker frees up.
|
|
11
|
-
*
|
|
12
|
-
* **Warning:** Input buffers (`key`, `nonce`, `plaintext`/`ciphertext`, `aad`)
|
|
13
|
-
* are transferred to the worker and neutered on the calling side. The caller
|
|
14
|
-
* must copy any buffer they need to retain after calling `encrypt()`/`decrypt()`.
|
|
15
|
-
*/
|
|
16
|
-
export declare class XChaCha20Poly1305Pool {
|
|
17
|
-
private readonly _workers;
|
|
18
|
-
private readonly _idle;
|
|
19
|
-
private readonly _queue;
|
|
20
|
-
private readonly _pending;
|
|
21
|
-
private _nextId;
|
|
22
|
-
private _disposed;
|
|
23
|
-
private constructor();
|
|
24
|
-
/**
|
|
25
|
-
* Create a new pool. Requires `init(['chacha20'])` to have been called.
|
|
26
|
-
* Compiles the WASM module once and distributes it to all workers.
|
|
27
|
-
*/
|
|
28
|
-
static create(opts?: PoolOpts): Promise<XChaCha20Poly1305Pool>;
|
|
29
|
-
/**
|
|
30
|
-
* Encrypt plaintext with XChaCha20-Poly1305.
|
|
31
|
-
* Returns `ciphertext || tag` (plaintext.length + 16 bytes).
|
|
32
|
-
*
|
|
33
|
-
* **Warning:** All input buffers are transferred and neutered after dispatch.
|
|
34
|
-
*/
|
|
35
|
-
encrypt(key: Uint8Array, nonce: Uint8Array, plaintext: Uint8Array, aad?: Uint8Array): Promise<Uint8Array>;
|
|
36
|
-
/**
|
|
37
|
-
* Decrypt ciphertext with XChaCha20-Poly1305.
|
|
38
|
-
* Input is `ciphertext || tag` (at least 16 bytes).
|
|
39
|
-
*
|
|
40
|
-
* **Warning:** All input buffers are transferred and neutered after dispatch.
|
|
41
|
-
*/
|
|
42
|
-
decrypt(key: Uint8Array, nonce: Uint8Array, ciphertext: Uint8Array, aad?: Uint8Array): Promise<Uint8Array>;
|
|
43
|
-
/** Terminates all workers. Rejects all pending and queued jobs. */
|
|
44
|
-
dispose(): void;
|
|
45
|
-
/** Number of workers in the pool. */
|
|
46
|
-
get size(): number;
|
|
47
|
-
/** Number of jobs currently queued (waiting for a free worker). */
|
|
48
|
-
get queueDepth(): number;
|
|
49
|
-
private _dispatch;
|
|
50
|
-
private _send;
|
|
51
|
-
private _onMessage;
|
|
52
|
-
}
|