leviathan-crypto 1.4.0 → 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 -94
- package/README.md +166 -223
- package/SECURITY.md +85 -45
- 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 -27
- package/dist/chacha20/index.js +40 -59
- 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 +192 -266
- package/dist/docs/exports.md +241 -0
- package/dist/docs/fortuna.md +60 -69
- package/dist/docs/init.md +172 -178
- package/dist/docs/loader.md +87 -142
- package/dist/docs/serpent.md +134 -583
- 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 +109 -32
- package/dist/embedded/kyber.d.ts +1 -0
- package/dist/embedded/kyber.js +3 -0
- package/dist/errors.d.ts +10 -0
- package/dist/errors.js +38 -0
- package/dist/fortuna.d.ts +0 -6
- package/dist/fortuna.js +5 -5
- 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 +15 -6
- package/dist/loader.js +65 -21
- 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 +7 -2
- package/dist/utils.js +49 -3
- 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 -178
- package/dist/chacha20/pool.worker.js +0 -37
- package/dist/chacha20/stream-sealer.d.ts +0 -49
- package/dist/chacha20/stream-sealer.js +0 -327
- 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/seal.js +0 -72
- package/dist/serpent/stream-pool.d.ts +0 -48
- package/dist/serpent/stream-pool.js +0 -275
- package/dist/serpent/stream-sealer.d.ts +0 -55
- package/dist/serpent/stream-sealer.js +0 -342
- 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
package/dist/docs/init.md
CHANGED
|
@@ -1,50 +1,51 @@
|
|
|
1
1
|
# Module Initialization and WASM Loading
|
|
2
2
|
|
|
3
|
-
> [!
|
|
4
|
-
>
|
|
5
|
-
>
|
|
6
|
-
> perform the actual cryptographic work, caches them in memory, and makes them
|
|
3
|
+
> [!IMPORTANT]
|
|
4
|
+
> Call `init()` before using any cryptographic class. It loads the WebAssembly
|
|
5
|
+
> modules that perform cryptographic work, caches them in memory, and makes them
|
|
7
6
|
> available to all wrapper classes.
|
|
8
7
|
|
|
8
|
+
> ### Table of Contents
|
|
9
|
+
> - [Overview](#overview)
|
|
10
|
+
> - [Security Notes](#security-notes)
|
|
11
|
+
> - [API Reference](#api-reference)
|
|
12
|
+
> - [Usage Examples](#usage-examples)
|
|
13
|
+
> - [Error Conditions](#error-conditions)
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
9
17
|
## Overview
|
|
10
18
|
|
|
11
19
|
leviathan-crypto runs all cryptographic computation inside WebAssembly modules.
|
|
12
|
-
These modules are not
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
`init()`
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
- **Three loading modes.** Embedded (default, zero-config), streaming
|
|
24
|
-
(better performance for large apps), and manual (full control over how
|
|
25
|
-
binaries are provided).
|
|
26
|
-
- **Idempotent.** Calling `init()` multiple times with the same module is
|
|
27
|
-
safe, it skips modules that are already loaded. This means you can call
|
|
28
|
-
`init()` in multiple places in your application without worrying about
|
|
29
|
-
redundant work.
|
|
30
|
-
- **Async.** `init()` returns a Promise. Use `await` or `.then()` before
|
|
31
|
-
proceeding.
|
|
20
|
+
These modules are not loaded automatically. You tell `init()` which modules you
|
|
21
|
+
need and provide a source for each one. After that, every class backed by those
|
|
22
|
+
modules is ready to use.
|
|
23
|
+
|
|
24
|
+
`init()` is idempotent. Calling it multiple times with the same module is safe.
|
|
25
|
+
It skips modules already loaded, so you can call `init()` in multiple places
|
|
26
|
+
without redundant work. It returns a Promise. Always `await` it before
|
|
27
|
+
constructing any class.
|
|
28
|
+
|
|
29
|
+
If you try to use a cryptographic class before calling `init()`, you get a clear
|
|
30
|
+
error telling you exactly which module to load.
|
|
32
31
|
|
|
33
32
|
---
|
|
34
33
|
|
|
35
34
|
## Security Notes
|
|
36
35
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
36
|
+
**WASM runs outside the JavaScript JIT.** Cryptographic code executes in
|
|
37
|
+
WebAssembly, which provides more predictable execution timing than optimized
|
|
38
|
+
JavaScript. This reduces the risk of timing side-channels introduced by the
|
|
39
|
+
JIT compiler.
|
|
40
|
+
|
|
41
|
+
**Each module gets its own linear memory.** Every WASM module receives 3 pages
|
|
42
|
+
(192 KB) of independent memory. Key material in one module cannot be read by
|
|
43
|
+
another. There is no shared memory between modules.
|
|
44
|
+
|
|
45
|
+
**No silent auto-initialization.** Every wrapper class checks that its backing
|
|
46
|
+
module has been initialized. If it has not, the class throws immediately rather
|
|
47
|
+
than loading the module in the background. Initialization is explicit and
|
|
48
|
+
auditable.
|
|
48
49
|
|
|
49
50
|
---
|
|
50
51
|
|
|
@@ -53,236 +54,230 @@ Key properties:
|
|
|
53
54
|
### Types
|
|
54
55
|
|
|
55
56
|
```typescript
|
|
56
|
-
type Module = 'serpent' | 'chacha20' | 'sha2' | 'sha3'
|
|
57
|
+
type Module = 'serpent' | 'chacha20' | 'sha2' | 'sha3' | 'keccak' | 'kyber'
|
|
57
58
|
```
|
|
58
59
|
|
|
59
|
-
The
|
|
60
|
-
|
|
61
|
-
| Module | Classes it enables |
|
|
62
|
-
|-------------|----------------------------------------------------------------|
|
|
63
|
-
| `'serpent'` | `Serpent`, `SerpentCbc`, `SerpentCtr`, `SerpentSeal`, `SerpentStream`, `SerpentStreamPool`, `Fortuna` |
|
|
64
|
-
| `'chacha20'`| `ChaCha20`, `XChaCha20Poly1305` |
|
|
65
|
-
| `'sha2'` | `SHA256`, `SHA384`, `SHA512`, `HMAC` (SHA-2 based), `Fortuna` |
|
|
66
|
-
| `'sha3'` | `SHA3`, `SHAKE128`, `SHAKE256` |
|
|
67
|
-
|
|
68
|
-
```typescript
|
|
69
|
-
type Mode = 'embedded' | 'streaming' | 'manual'
|
|
70
|
-
```
|
|
60
|
+
The WASM module families. Each one backs a group of related classes.
|
|
61
|
+
`'keccak'` is an alias for `'sha3'` — same WASM binary, same instance slot.
|
|
71
62
|
|
|
72
|
-
|
|
73
|
-
|
|
63
|
+
| Module | Classes it enables |
|
|
64
|
+
|---|---|
|
|
65
|
+
| `'serpent'` | `Serpent`, `SerpentCbc`, `SerpentCtr` |
|
|
66
|
+
| `'serpent'` + `'sha2'` | `SerpentCipher`, `Seal` (with `SerpentCipher`), `SealStream`, `OpenStream`, `Fortuna` — see [aead.md](./aead.md) |
|
|
67
|
+
| `'chacha20'` | `ChaCha20`, `ChaCha20Poly1305`, `XChaCha20Poly1305` |
|
|
68
|
+
| `'chacha20'` + `'sha2'` | `XChaCha20Cipher`, `Seal` (with `XChaCha20Cipher`), `SealStream`, `OpenStream` — see [aead.md](./aead.md) |
|
|
69
|
+
| `'sha2'` | `SHA256`, `SHA384`, `SHA512`, `HMAC` (SHA-2 based), `HKDF` |
|
|
70
|
+
| `'sha3'` / `'keccak'` | `SHA3_224`, `SHA3_256`, `SHA3_384`, `SHA3_512`, `SHAKE128`, `SHAKE256` |
|
|
71
|
+
| `'kyber'` | `MlKem512`, `MlKem768`, `MlKem1024` (also requires `'sha3'`) — see [kyber.md](./kyber.md) |
|
|
72
|
+
| `'kyber'` + `'sha3'` + inner cipher modules | `KyberSuite`, `MlKem512`, `MlKem768`, `MlKem1024` — see [kyber.md](./kyber.md) |
|
|
74
73
|
|
|
75
74
|
```typescript
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
wasmBinary?: Partial<Record<Module, Uint8Array | ArrayBuffer>>
|
|
79
|
-
}
|
|
75
|
+
type WasmSource = string | URL | ArrayBuffer | Uint8Array
|
|
76
|
+
| WebAssembly.Module | Response | Promise<Response>
|
|
80
77
|
```
|
|
81
78
|
|
|
82
|
-
|
|
79
|
+
A value that resolves to a WASM binary. The loading strategy is inferred from
|
|
80
|
+
the type:
|
|
83
81
|
|
|
84
|
-
|
|
|
85
|
-
|
|
86
|
-
| `
|
|
87
|
-
| `
|
|
88
|
-
| `
|
|
82
|
+
| Source type | What happens |
|
|
83
|
+
|---|---|
|
|
84
|
+
| `string` | Treated as a gzip+base64 embedded blob. Decoded and decompressed. |
|
|
85
|
+
| `URL` | Fetched with streaming compilation (`WebAssembly.compileStreaming`). |
|
|
86
|
+
| `ArrayBuffer` | Compiled directly via `WebAssembly.instantiate`. |
|
|
87
|
+
| `Uint8Array` | Compiled directly via `WebAssembly.instantiate`. |
|
|
88
|
+
| `WebAssembly.Module` | Already compiled. Instantiated immediately. |
|
|
89
|
+
| `Response` / `Promise<Response>` | Streaming compilation via `WebAssembly.instantiateStreaming`. |
|
|
89
90
|
|
|
90
91
|
---
|
|
91
92
|
|
|
92
93
|
### Functions
|
|
93
94
|
|
|
94
|
-
####
|
|
95
|
-
|
|
96
|
-
> [!NOTE]
|
|
97
|
-
> `init()` is no longer exported from `init.ts`. It is defined in the
|
|
98
|
-
> root barrel (`src/ts/index.ts`) and dispatches to each module's own init
|
|
99
|
-
> function (`serpentInit`, `chacha20Init`, `sha2Init`, `sha3Init`).
|
|
100
|
-
> See [README.md](./README.md) for details.
|
|
101
|
-
|
|
102
|
-
The public `init()` signature is unchanged:
|
|
95
|
+
#### init()
|
|
103
96
|
|
|
104
97
|
```typescript
|
|
105
98
|
async function init(
|
|
106
|
-
|
|
107
|
-
mode?: Mode, // default: 'embedded'
|
|
108
|
-
opts?: InitOpts,
|
|
99
|
+
sources: Partial<Record<Module, WasmSource>>,
|
|
109
100
|
): Promise<void>
|
|
110
101
|
```
|
|
111
102
|
|
|
103
|
+
Initializes one or more WASM modules. Pass an object mapping module names to
|
|
104
|
+
their `WasmSource`. Only modules present in the object are loaded. Others are
|
|
105
|
+
left untouched.
|
|
106
|
+
|
|
112
107
|
---
|
|
113
108
|
|
|
114
|
-
####
|
|
109
|
+
#### Per-module init functions
|
|
110
|
+
|
|
111
|
+
Each module subpath exports its own init function for tree-shakeable imports.
|
|
112
|
+
These take a single `WasmSource` argument.
|
|
115
113
|
|
|
116
114
|
```typescript
|
|
117
|
-
async function
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
): Promise<void>
|
|
115
|
+
async function serpentInit(source: WasmSource): Promise<void>
|
|
116
|
+
async function chacha20Init(source: WasmSource): Promise<void>
|
|
117
|
+
async function sha2Init(source: WasmSource): Promise<void>
|
|
118
|
+
async function sha3Init(source: WasmSource): Promise<void>
|
|
119
|
+
async function keccakInit(source: WasmSource): Promise<void>
|
|
120
|
+
async function kyberInit(source: WasmSource): Promise<void>
|
|
123
121
|
```
|
|
124
122
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
123
|
+
Each function initializes only its own WASM module, keeping other modules out
|
|
124
|
+
of your bundle.
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
#### Embedded subpath exports
|
|
129
129
|
|
|
130
|
-
|
|
130
|
+
The `/embedded` subpath for each module provides the gzip+base64 blob as a
|
|
131
|
+
ready-to-use `WasmSource`:
|
|
131
132
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
133
|
+
| Subpath | Export |
|
|
134
|
+
|---|---|
|
|
135
|
+
| `leviathan-crypto/serpent/embedded` | `serpentWasm` |
|
|
136
|
+
| `leviathan-crypto/chacha20/embedded` | `chacha20Wasm` |
|
|
137
|
+
| `leviathan-crypto/sha2/embedded` | `sha2Wasm` |
|
|
138
|
+
| `leviathan-crypto/sha3/embedded` | `sha3Wasm` |
|
|
139
|
+
| `leviathan-crypto/keccak/embedded` | `keccakWasm` |
|
|
140
|
+
| `leviathan-crypto/kyber/embedded` | `kyberWasm` |
|
|
138
141
|
|
|
139
|
-
|
|
142
|
+
`keccakWasm` and `sha3Wasm` are the same gzip+base64 blob. Both point to `sha3.wasm`.
|
|
140
143
|
|
|
141
|
-
|
|
144
|
+
> [!NOTE]
|
|
145
|
+
> `MlKem512`, `MlKem768`, and `MlKem1024` require both `kyber` and `sha3`
|
|
146
|
+
> (or `keccak`) to be initialized. The kyber module handles polynomial arithmetic.
|
|
147
|
+
> The sha3 module provides the Keccak sponge operations used for key generation
|
|
148
|
+
> and encapsulation.
|
|
149
|
+
|
|
150
|
+
---
|
|
142
151
|
|
|
143
|
-
|
|
152
|
+
#### isInitialized()
|
|
144
153
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
154
|
+
```typescript
|
|
155
|
+
function isInitialized(mod: Module): boolean
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Returns `true` if the given module has been loaded and cached. Exported from
|
|
159
|
+
both `init.ts` and the root barrel.
|
|
151
160
|
|
|
152
161
|
> [!NOTE]
|
|
153
|
-
>
|
|
154
|
-
>
|
|
155
|
-
> to its embedded import. This meant any consumer importing `init()`,
|
|
156
|
-
> even through a subpath like `leviathan-crypto/serpent`, pulled all four
|
|
157
|
-
> embedded binaries into the bundle. Moving `init()` to the root barrel and
|
|
158
|
-
> giving each module its own thunk isolates the dependency graph so bundlers
|
|
159
|
-
> can tree-shake unused modules, optimizing build size.
|
|
162
|
+
> `isInitialized` is a diagnostic indicator, not a control mechanism. Use
|
|
163
|
+
> `init()` to load modules. Do not guard calls on this value.
|
|
160
164
|
|
|
161
165
|
---
|
|
162
166
|
|
|
163
|
-
####
|
|
167
|
+
#### getInstance()
|
|
164
168
|
|
|
165
169
|
```typescript
|
|
166
170
|
function getInstance(mod: Module): WebAssembly.Instance
|
|
167
171
|
```
|
|
168
172
|
|
|
169
|
-
Returns the cached WebAssembly instance for a module.
|
|
170
|
-
|
|
173
|
+
Returns the cached WebAssembly instance for a module. Used internally by
|
|
174
|
+
wrapper classes. You do not normally need to call this yourself.
|
|
171
175
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
module has not been initialized.
|
|
176
|
+
Throws `'leviathan-crypto: call init({ <mod>: ... }) before using this class'`
|
|
177
|
+
if the module has not been initialized.
|
|
175
178
|
|
|
176
179
|
---
|
|
177
180
|
|
|
178
|
-
####
|
|
181
|
+
#### compileWasm()
|
|
179
182
|
|
|
180
183
|
```typescript
|
|
181
|
-
function
|
|
184
|
+
async function compileWasm(source: WasmSource): Promise<WebAssembly.Module>
|
|
182
185
|
```
|
|
183
186
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
> [!NOTE]
|
|
188
|
-
> `isInitialized` is a diagnostic indicator only — not a control mechanism.
|
|
189
|
-
> Use `init()` to initialize modules; do not guard calls on this value.
|
|
187
|
+
Compiles a `WasmSource` to a `WebAssembly.Module` without instantiating it.
|
|
188
|
+
Used by pool infrastructure to send compiled modules to workers. See
|
|
189
|
+
[loader.md](./loader.md) for details.
|
|
190
190
|
|
|
191
191
|
---
|
|
192
192
|
|
|
193
|
-
####
|
|
193
|
+
#### _resetForTesting()
|
|
194
194
|
|
|
195
195
|
```typescript
|
|
196
196
|
function _resetForTesting(): void
|
|
197
197
|
```
|
|
198
198
|
|
|
199
|
-
Clears all cached WASM instances.
|
|
200
|
-
suites to reset the initialization state between test runs. Do not use this in
|
|
199
|
+
Clears all cached WASM instances. Testing utility only. Do not use in
|
|
201
200
|
production code.
|
|
202
201
|
|
|
203
202
|
---
|
|
204
203
|
|
|
205
204
|
## Usage Examples
|
|
206
205
|
|
|
207
|
-
### Embedded
|
|
206
|
+
### Embedded init (most common)
|
|
208
207
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
files to serve or fetch.
|
|
208
|
+
The WASM binaries are bundled inside the package as gzip+base64 strings. Import
|
|
209
|
+
the blob from the module's `/embedded` subpath and pass it to `init()`.
|
|
212
210
|
|
|
213
211
|
```typescript
|
|
214
|
-
import { init
|
|
215
|
-
|
|
216
|
-
|
|
212
|
+
import { init } from 'leviathan-crypto'
|
|
213
|
+
import { serpentWasm } from 'leviathan-crypto/serpent/embedded'
|
|
214
|
+
import { sha2Wasm } from 'leviathan-crypto/sha2/embedded'
|
|
217
215
|
|
|
218
|
-
|
|
219
|
-
const digest = hash.hash(myData)
|
|
216
|
+
await init({ serpent: serpentWasm, sha2: sha2Wasm })
|
|
220
217
|
```
|
|
221
218
|
|
|
222
|
-
###
|
|
219
|
+
### Per-module init (tree-shaking)
|
|
223
220
|
|
|
224
|
-
|
|
221
|
+
Use the subpath init function when you need one module and want the smallest
|
|
222
|
+
possible bundle:
|
|
225
223
|
|
|
226
224
|
```typescript
|
|
227
|
-
import {
|
|
225
|
+
import { serpentInit } from 'leviathan-crypto/serpent'
|
|
226
|
+
import { serpentWasm } from 'leviathan-crypto/serpent/embedded'
|
|
228
227
|
|
|
229
|
-
await
|
|
230
|
-
|
|
231
|
-
const cipher = new Serpent(key)
|
|
232
|
-
const hash = new SHA256()
|
|
228
|
+
await serpentInit(serpentWasm)
|
|
233
229
|
```
|
|
234
230
|
|
|
235
|
-
###
|
|
236
|
-
|
|
237
|
-
Streaming mode fetches `.wasm` files from a URL and uses the browser's
|
|
238
|
-
streaming compilation (`WebAssembly.instantiateStreaming`). This can be
|
|
239
|
-
faster than embedded mode because the browser can begin compiling the WASM
|
|
240
|
-
binary while it is still downloading.
|
|
231
|
+
### Keccak alias (for ML-KEM)
|
|
241
232
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
233
|
+
`'keccak'` is an alias for `'sha3'`. Both resolve to the same WASM binary and
|
|
234
|
+
the same instance slot. Use it when you want the semantically correct primitive
|
|
235
|
+
name for ML-KEM consumers:
|
|
245
236
|
|
|
246
237
|
```typescript
|
|
247
|
-
import { init
|
|
248
|
-
|
|
249
|
-
await init('serpent', 'streaming', {
|
|
250
|
-
wasmUrl: '/static/wasm/'
|
|
251
|
-
})
|
|
238
|
+
import { init } from 'leviathan-crypto'
|
|
239
|
+
import { keccakWasm } from 'leviathan-crypto/keccak/embedded'
|
|
252
240
|
|
|
253
|
-
|
|
241
|
+
await init({ keccak: keccakWasm })
|
|
242
|
+
// isInitialized('sha3') === true — same slot
|
|
243
|
+
// isInitialized('keccak') === true — alias resolves symmetrically
|
|
254
244
|
```
|
|
255
245
|
|
|
256
|
-
|
|
257
|
-
`sha2.wasm`). You only need to provide the directory URL.
|
|
246
|
+
Or via the subpath directly:
|
|
258
247
|
|
|
259
|
-
|
|
248
|
+
```typescript
|
|
249
|
+
import { keccakInit, SHAKE128, SHA3_256 } from 'leviathan-crypto/keccak'
|
|
250
|
+
import { keccakWasm } from 'leviathan-crypto/keccak/embedded'
|
|
251
|
+
|
|
252
|
+
await keccakInit(keccakWasm)
|
|
253
|
+
```
|
|
260
254
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
255
|
+
### URL-based loading (CDN)
|
|
256
|
+
|
|
257
|
+
Pass a `URL` to fetch and compile the `.wasm` file via streaming compilation.
|
|
258
|
+
The server must respond with `Content-Type: application/wasm`.
|
|
264
259
|
|
|
265
260
|
```typescript
|
|
266
|
-
|
|
261
|
+
await init({ serpent: new URL('https://unpkg.com/leviathan-crypto/dist/serpent.wasm') })
|
|
262
|
+
```
|
|
267
263
|
|
|
268
|
-
|
|
269
|
-
const wasmBinary = await fetch('/my-custom-path/sha2.wasm')
|
|
270
|
-
.then(r => r.arrayBuffer())
|
|
264
|
+
### Pre-compiled module (edge runtimes)
|
|
271
265
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
})
|
|
266
|
+
If you have already compiled the binary, for example from a KV cache, pass the
|
|
267
|
+
`WebAssembly.Module` directly:
|
|
275
268
|
|
|
276
|
-
|
|
269
|
+
```typescript
|
|
270
|
+
const mod = await WebAssembly.compile(bytes)
|
|
271
|
+
await init({ serpent: mod })
|
|
277
272
|
```
|
|
278
273
|
|
|
279
|
-
### Checking
|
|
274
|
+
### Checking initialization state
|
|
280
275
|
|
|
281
276
|
```typescript
|
|
282
277
|
import { isInitialized } from 'leviathan-crypto'
|
|
283
278
|
|
|
284
279
|
if (!isInitialized('sha2')) {
|
|
285
|
-
|
|
280
|
+
// handle accordingly
|
|
286
281
|
}
|
|
287
282
|
```
|
|
288
283
|
|
|
@@ -290,19 +285,18 @@ if (!isInitialized('sha2')) {
|
|
|
290
285
|
|
|
291
286
|
## Error Conditions
|
|
292
287
|
|
|
293
|
-
| Situation
|
|
294
|
-
|
|
295
|
-
| Using a class before calling `init()`
|
|
296
|
-
|
|
|
297
|
-
|
|
|
298
|
-
|
|
|
299
|
-
| Calling `init()` for an already-loaded module | No error. Module is silently skipped (idempotent behavior) |
|
|
288
|
+
| Situation | What happens |
|
|
289
|
+
|---|---|
|
|
290
|
+
| Using a class before calling `init()` | Throws: `"leviathan-crypto: call init({ ${mod}: ... }) before using this class"` |
|
|
291
|
+
| Invalid `WasmSource` (null, number, etc.) | Throws: `TypeError` with a descriptive message |
|
|
292
|
+
| Empty string source | Throws: `"leviathan-crypto: invalid WasmSource — empty string"` |
|
|
293
|
+
| Calling `init()` for an already-loaded module | No error. Module is silently skipped. |
|
|
300
294
|
|
|
301
295
|
---
|
|
302
296
|
|
|
303
297
|
> ## Cross-References
|
|
304
298
|
>
|
|
305
299
|
> - [index](./README.md) — Project Documentation index
|
|
306
|
-
> - [loader](./loader.md) — WASM binary loading strategies (internal details)
|
|
307
300
|
> - [architecture](./architecture.md) — architecture overview, module relationships, buffer layouts, and build pipeline
|
|
301
|
+
> - [loader](./loader.md) — WASM binary loading strategies (internal details)
|
|
308
302
|
> - [wasm](./wasm.md) — WebAssembly primer: modules, instances, memory, and the init gate
|