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
package/CLAUDE.md
CHANGED
|
@@ -1,7 +1,19 @@
|
|
|
1
1
|
# leviathan-crypto — AI Assistant Guide
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
Full API documentation is in the `docs/` directory alongside this file.
|
|
3
|
+
> [!NOTE]
|
|
4
|
+
> This file ships with the package to help AI assistants use this library correctly. Full API documentation is in the `docs/` directory alongside this file.
|
|
5
|
+
|
|
6
|
+
> ### Table of Contents
|
|
7
|
+
> - [What This Library Is](#what-this-library-is)
|
|
8
|
+
> - [Critical: `init()` is required](#critical-init-is-required)
|
|
9
|
+
> - [Critical: call `dispose()` after use](#critical-call-dispose-after-use)
|
|
10
|
+
> - [Critical: `decrypt()` throws on authentication failure](#critical-decrypt-throws-on-authentication-failure--never-returns-null)
|
|
11
|
+
> - [Critical: subpath init function names](#critical-subpath-init-function-names)
|
|
12
|
+
> - [Which module does each class require?](#which-module-does-each-class-require)
|
|
13
|
+
> - [Recommended patterns](#recommended-patterns)
|
|
14
|
+
> - [`SerpentCbc` arg order](#serpentcbc-arg-order)
|
|
15
|
+
> - [Utilities (no `init()` required)](#utilities-no-init-required)
|
|
16
|
+
> - [Full documentation](#full-documentation)
|
|
5
17
|
|
|
6
18
|
---
|
|
7
19
|
|
|
@@ -9,7 +21,7 @@ Full API documentation is in the `docs/` directory alongside this file.
|
|
|
9
21
|
|
|
10
22
|
`leviathan-crypto` is a zero-dependency WebAssembly cryptography library for
|
|
11
23
|
TypeScript and JavaScript. All cryptographic computation runs in WASM, outside
|
|
12
|
-
the JavaScript JIT. The TypeScript layer provides the public API
|
|
24
|
+
the JavaScript JIT. The TypeScript layer provides the public API: input
|
|
13
25
|
validation, type safety, and ergonomics. It never implements cryptographic
|
|
14
26
|
algorithms itself.
|
|
15
27
|
|
|
@@ -22,24 +34,31 @@ module is loaded throws immediately with a clear error. Call `init()` once at
|
|
|
22
34
|
startup, before any cryptographic operations.
|
|
23
35
|
|
|
24
36
|
```typescript
|
|
25
|
-
import { init,
|
|
37
|
+
import { init, Serpent } from 'leviathan-crypto'
|
|
38
|
+
import { serpentWasm } from 'leviathan-crypto/serpent/embedded'
|
|
39
|
+
import { sha2Wasm } from 'leviathan-crypto/sha2/embedded'
|
|
26
40
|
|
|
27
|
-
await init(
|
|
41
|
+
await init({ serpent: serpentWasm, sha2: sha2Wasm })
|
|
28
42
|
```
|
|
29
43
|
|
|
30
|
-
|
|
44
|
+
`init()` accepts a `Partial<Record<Module, WasmSource>>`. Each value is a
|
|
45
|
+
`WasmSource`: a gzip+base64 string, `URL`, `ArrayBuffer`, `Uint8Array`,
|
|
46
|
+
pre-compiled `WebAssembly.Module`, `Response`, or `Promise<Response>`.
|
|
47
|
+
|
|
48
|
+
The `/embedded` subpath exports are the simplest WasmSource: they are the
|
|
49
|
+
gzip+base64 blobs for each module, bundled with the package.
|
|
31
50
|
|
|
32
51
|
---
|
|
33
52
|
|
|
34
53
|
## Critical: call `dispose()` after use
|
|
35
54
|
|
|
36
55
|
Every class holds WASM memory containing key material. Call `dispose()` when
|
|
37
|
-
done
|
|
56
|
+
done; it zeroes that memory. Not calling `dispose()` leaks key material.
|
|
38
57
|
|
|
39
58
|
```typescript
|
|
40
|
-
const cipher = new
|
|
59
|
+
const cipher = new XChaCha20Poly1305()
|
|
41
60
|
try {
|
|
42
|
-
return cipher.encrypt(key, plaintext)
|
|
61
|
+
return cipher.encrypt(key, nonce, plaintext)
|
|
43
62
|
} finally {
|
|
44
63
|
cipher.dispose()
|
|
45
64
|
}
|
|
@@ -50,7 +69,7 @@ try {
|
|
|
50
69
|
## Critical: `decrypt()` throws on authentication failure — never returns null
|
|
51
70
|
|
|
52
71
|
All AEAD `decrypt()` methods throw if authentication fails. Do not check for a
|
|
53
|
-
null return
|
|
72
|
+
null return; catch the exception.
|
|
54
73
|
|
|
55
74
|
```typescript
|
|
56
75
|
try {
|
|
@@ -64,34 +83,44 @@ try {
|
|
|
64
83
|
|
|
65
84
|
## Critical: subpath init function names
|
|
66
85
|
|
|
67
|
-
Each subpath export has its own module-specific init function
|
|
86
|
+
Each subpath export has its own module-specific init function, not `init()`.
|
|
68
87
|
These are only needed for tree-shakeable imports. The root barrel `init()` is
|
|
69
88
|
the normal path.
|
|
70
89
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
|
75
|
-
|
|
76
|
-
| `leviathan-crypto/
|
|
90
|
+
Each init function takes a single `WasmSource` argument. Use the module's
|
|
91
|
+
`/embedded` subpath to get the bundled blob as a ready-to-use WasmSource.
|
|
92
|
+
|
|
93
|
+
| Subpath | Init function | Embedded blob |
|
|
94
|
+
|---------|---------------|---------------|
|
|
95
|
+
| `leviathan-crypto/serpent` | `serpentInit(source)` | `leviathan-crypto/serpent/embedded` → `serpentWasm` |
|
|
96
|
+
| `leviathan-crypto/chacha20` | `chacha20Init(source)` | `leviathan-crypto/chacha20/embedded` → `chacha20Wasm` |
|
|
97
|
+
| `leviathan-crypto/sha2` | `sha2Init(source)` | `leviathan-crypto/sha2/embedded` → `sha2Wasm` |
|
|
98
|
+
| `leviathan-crypto/sha3` | `sha3Init(source)` | `leviathan-crypto/sha3/embedded` → `sha3Wasm` |
|
|
99
|
+
| `leviathan-crypto/keccak` | `keccakInit(source)` | `leviathan-crypto/keccak/embedded` → `keccakWasm` |
|
|
100
|
+
| `leviathan-crypto/kyber` | `kyberInit(source)` | `leviathan-crypto/kyber/embedded` → `kyberWasm` |
|
|
77
101
|
|
|
78
102
|
```typescript
|
|
79
103
|
// Tree-shakeable — loads only serpent WASM
|
|
80
|
-
import { serpentInit,
|
|
81
|
-
|
|
104
|
+
import { serpentInit, Serpent } from 'leviathan-crypto/serpent'
|
|
105
|
+
import { serpentWasm } from 'leviathan-crypto/serpent/embedded'
|
|
106
|
+
await serpentInit(serpentWasm)
|
|
82
107
|
```
|
|
83
108
|
|
|
84
109
|
---
|
|
85
110
|
|
|
86
111
|
## Which module does each class require?
|
|
87
112
|
|
|
88
|
-
| Classes |
|
|
89
|
-
|
|
90
|
-
| `
|
|
91
|
-
| `
|
|
92
|
-
| `
|
|
93
|
-
| `
|
|
94
|
-
| `
|
|
113
|
+
| Classes | Required modules |
|
|
114
|
+
|---------|-----------------|
|
|
115
|
+
| `Serpent`, `SerpentCtr`, `SerpentCbc`, `SerpentCipher` | `init({ serpent: serpentWasm, sha2: sha2Wasm })` |
|
|
116
|
+
| `SealStream`, `OpenStream`, `SerpentCipher` (when using SerpentCipher) | `init({ serpent: serpentWasm, sha2: sha2Wasm })` |
|
|
117
|
+
| `SealStream`, `OpenStream`, `XChaCha20Cipher` (when using XChaCha20Cipher) | `init({ chacha20: chacha20Wasm, sha2: sha2Wasm })` |
|
|
118
|
+
| `SealStreamPool` | depends on cipher: same modules as the cipher suite + `sha2` |
|
|
119
|
+
| `ChaCha20`, `Poly1305`, `ChaCha20Poly1305`, `XChaCha20Poly1305` | `init({ chacha20: chacha20Wasm })` |
|
|
120
|
+
| `SHA256`, `SHA384`, `SHA512`, `HMAC_SHA256`, `HMAC_SHA384`, `HMAC_SHA512`, `HKDF_SHA256`, `HKDF_SHA512` | `init({ sha2: sha2Wasm })` |
|
|
121
|
+
| `SHA3_224`, `SHA3_256`, `SHA3_384`, `SHA3_512`, `SHAKE128`, `SHAKE256` | `init({ sha3: sha3Wasm })` or `init({ keccak: keccakWasm })` — `'keccak'` is an alias for `'sha3'` |
|
|
122
|
+
| `MlKem512`, `MlKem768`, `MlKem1024` | `init({ kyber: kyberWasm, sha3: sha3Wasm })` — both modules required |
|
|
123
|
+
| `Fortuna` | `init({ serpent: serpentWasm, sha2: sha2Wasm })` |
|
|
95
124
|
|
|
96
125
|
---
|
|
97
126
|
|
|
@@ -100,15 +129,15 @@ await serpentInit()
|
|
|
100
129
|
### Authenticated encryption (recommended default)
|
|
101
130
|
|
|
102
131
|
```typescript
|
|
103
|
-
import { init,
|
|
132
|
+
import { init, Seal, SerpentCipher, randomBytes } from 'leviathan-crypto'
|
|
133
|
+
import { serpentWasm } from 'leviathan-crypto/serpent/embedded'
|
|
134
|
+
import { sha2Wasm } from 'leviathan-crypto/sha2/embedded'
|
|
104
135
|
|
|
105
|
-
await init(
|
|
136
|
+
await init({ serpent: serpentWasm, sha2: sha2Wasm })
|
|
106
137
|
|
|
107
|
-
const key
|
|
108
|
-
const
|
|
109
|
-
const
|
|
110
|
-
const decrypted = seal.decrypt(key, ciphertext) // throws on tamper
|
|
111
|
-
seal.dispose()
|
|
138
|
+
const key = SerpentCipher.keygen()
|
|
139
|
+
const blob = Seal.encrypt(SerpentCipher, key, plaintext)
|
|
140
|
+
const decrypted = Seal.decrypt(SerpentCipher, key, blob)
|
|
112
141
|
```
|
|
113
142
|
|
|
114
143
|
### Incremental streaming AEAD
|
|
@@ -116,50 +145,42 @@ seal.dispose()
|
|
|
116
145
|
Use when you cannot buffer the full message before encrypting.
|
|
117
146
|
|
|
118
147
|
```typescript
|
|
119
|
-
import { init,
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
const
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
const
|
|
148
|
+
import { init, SealStream, OpenStream, SerpentCipher, randomBytes } from 'leviathan-crypto'
|
|
149
|
+
import { serpentWasm } from 'leviathan-crypto/serpent/embedded'
|
|
150
|
+
import { sha2Wasm } from 'leviathan-crypto/sha2/embedded'
|
|
151
|
+
|
|
152
|
+
await init({ serpent: serpentWasm, sha2: sha2Wasm })
|
|
153
|
+
|
|
154
|
+
const key = randomBytes(32)
|
|
155
|
+
const sealer = new SealStream(SerpentCipher, key)
|
|
156
|
+
const preamble = sealer.preamble // 20 bytes — send first
|
|
157
|
+
const ct0 = sealer.push(chunk0)
|
|
158
|
+
const ct1 = sealer.push(chunk1)
|
|
159
|
+
const ctLast = sealer.finalize(lastChunk)
|
|
160
|
+
|
|
161
|
+
const opener = new OpenStream(SerpentCipher, key, preamble)
|
|
162
|
+
const pt0 = opener.pull(ct0)
|
|
163
|
+
const pt1 = opener.pull(ct1)
|
|
164
|
+
const ptLast = opener.finalize(ctLast)
|
|
133
165
|
```
|
|
134
166
|
|
|
135
167
|
### Length-prefixed streaming (for files and buffered transports)
|
|
136
168
|
|
|
137
|
-
Pass `{ framed: true }` to `
|
|
138
|
-
|
|
139
|
-
|
|
169
|
+
Pass `{ framed: true }` to `SealStream` for self-delimiting `u32be` length-prefixed
|
|
170
|
+
framing. Use when chunks will be concatenated into a flat byte stream. Omit when the
|
|
171
|
+
transport frames messages itself (WebSocket, IPC).
|
|
140
172
|
|
|
141
173
|
```typescript
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
await init(['serpent', 'sha2'])
|
|
145
|
-
|
|
146
|
-
const key = randomBytes(64)
|
|
147
|
-
const sealer = new SerpentStreamSealer(key, 65536, { framed: true })
|
|
148
|
-
const header = sealer.header()
|
|
149
|
-
|
|
150
|
-
const frame0 = sealer.seal(data0) // u32be(len) || sealed chunk
|
|
151
|
-
const last = sealer.final(tail)
|
|
152
|
-
|
|
153
|
-
const opener = new SerpentStreamOpener(key, header, { framed: true })
|
|
154
|
-
const chunks = opener.feed(frame0) // Uint8Array[] — throws on auth failure
|
|
174
|
+
const sealer = new SealStream(SerpentCipher, key, { framed: true })
|
|
155
175
|
```
|
|
156
176
|
|
|
157
177
|
### XChaCha20-Poly1305
|
|
158
178
|
|
|
159
179
|
```typescript
|
|
160
180
|
import { init, XChaCha20Poly1305, randomBytes } from 'leviathan-crypto'
|
|
181
|
+
import { chacha20Wasm } from 'leviathan-crypto/chacha20/embedded'
|
|
161
182
|
|
|
162
|
-
await init(
|
|
183
|
+
await init({ chacha20: chacha20Wasm })
|
|
163
184
|
|
|
164
185
|
const aead = new XChaCha20Poly1305()
|
|
165
186
|
const key = randomBytes(32)
|
|
@@ -170,14 +191,15 @@ aead.dispose()
|
|
|
170
191
|
```
|
|
171
192
|
|
|
172
193
|
Note: `encrypt()` returns ciphertext with the 16-byte Poly1305 tag appended.
|
|
173
|
-
`decrypt()` expects the same concatenated format
|
|
194
|
+
`decrypt()` expects the same concatenated format, not separate ciphertext and tag.
|
|
174
195
|
|
|
175
196
|
### Hashing
|
|
176
197
|
|
|
177
198
|
```typescript
|
|
178
199
|
import { init, SHA256, HMAC_SHA256 } from 'leviathan-crypto'
|
|
200
|
+
import { sha2Wasm } from 'leviathan-crypto/sha2/embedded'
|
|
179
201
|
|
|
180
|
-
await init(
|
|
202
|
+
await init({ sha2: sha2Wasm })
|
|
181
203
|
|
|
182
204
|
const hasher = new SHA256()
|
|
183
205
|
const digest = hasher.hash(data) // returns Uint8Array
|
|
@@ -192,8 +214,9 @@ mac.dispose()
|
|
|
192
214
|
|
|
193
215
|
```typescript
|
|
194
216
|
import { init, SHAKE128 } from 'leviathan-crypto'
|
|
217
|
+
import { sha3Wasm } from 'leviathan-crypto/sha3/embedded'
|
|
195
218
|
|
|
196
|
-
await init(
|
|
219
|
+
await init({ sha3: sha3Wasm })
|
|
197
220
|
|
|
198
221
|
const xof = new SHAKE128()
|
|
199
222
|
xof.absorb(data)
|
|
@@ -202,12 +225,39 @@ const out2 = xof.squeeze(32) // next 32 bytes — contiguous XOF stream
|
|
|
202
225
|
xof.dispose()
|
|
203
226
|
```
|
|
204
227
|
|
|
228
|
+
### ML-KEM post-quantum key encapsulation
|
|
229
|
+
|
|
230
|
+
```typescript
|
|
231
|
+
import { init, MlKem768 } from 'leviathan-crypto'
|
|
232
|
+
import { kyberWasm } from 'leviathan-crypto/kyber/embedded'
|
|
233
|
+
import { sha3Wasm } from 'leviathan-crypto/sha3/embedded'
|
|
234
|
+
|
|
235
|
+
await init({ kyber: kyberWasm, sha3: sha3Wasm })
|
|
236
|
+
|
|
237
|
+
const kem = new MlKem768()
|
|
238
|
+
const { encapsulationKey, decapsulationKey } = kem.keygen()
|
|
239
|
+
|
|
240
|
+
// Encapsulation (sender — public encapsulationKey only)
|
|
241
|
+
const { ciphertext, sharedSecret: senderSecret } = kem.encapsulate(encapsulationKey)
|
|
242
|
+
|
|
243
|
+
// Decapsulation (recipient — private decapsulationKey)
|
|
244
|
+
const recipientSecret = kem.decapsulate(decapsulationKey, ciphertext)
|
|
245
|
+
|
|
246
|
+
// senderSecret === recipientSecret (32 bytes)
|
|
247
|
+
kem.dispose()
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Kyber classes require **both** `kyber` and `sha3` initialized. ML-KEM produces
|
|
251
|
+
a 32-byte shared secret suitable for use as a symmetric key.
|
|
252
|
+
|
|
205
253
|
### Fortuna CSPRNG
|
|
206
254
|
|
|
207
255
|
```typescript
|
|
208
256
|
import { init, Fortuna } from 'leviathan-crypto'
|
|
257
|
+
import { serpentWasm } from 'leviathan-crypto/serpent/embedded'
|
|
258
|
+
import { sha2Wasm } from 'leviathan-crypto/sha2/embedded'
|
|
209
259
|
|
|
210
|
-
await init(
|
|
260
|
+
await init({ serpent: serpentWasm, sha2: sha2Wasm })
|
|
211
261
|
|
|
212
262
|
const fortuna = await Fortuna.create() // static factory — not new Fortuna()
|
|
213
263
|
const bytes = fortuna.get(32)
|
|
@@ -226,7 +276,7 @@ cipher.decrypt(key, iv, ciphertext) // correct
|
|
|
226
276
|
```
|
|
227
277
|
|
|
228
278
|
`SerpentCbc` is unauthenticated. Always pair with `HMAC_SHA256`
|
|
229
|
-
(Encrypt-then-MAC) or use `
|
|
279
|
+
(Encrypt-then-MAC) or use `Seal` with `SerpentCipher` instead.
|
|
230
280
|
|
|
231
281
|
---
|
|
232
282
|
|
|
@@ -243,10 +293,11 @@ const safe = constantTimeEqual(a, b) // constant-time equality — never use =
|
|
|
243
293
|
wipe(key) // zero a Uint8Array in place
|
|
244
294
|
```
|
|
245
295
|
|
|
246
|
-
`hasSIMD()` returns `true` if the runtime supports WebAssembly SIMD.
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
296
|
+
`hasSIMD()` returns `true` if the runtime supports WebAssembly SIMD.
|
|
297
|
+
Serpent, ChaCha20, and Kyber modules all require SIMD; `init()` throws
|
|
298
|
+
a clear error on runtimes without support. SIMD has been a baseline
|
|
299
|
+
feature of all major browsers and runtimes since 2021. SHA-2 and SHA-3
|
|
300
|
+
modules run on any WASM-capable runtime.
|
|
250
301
|
|
|
251
302
|
---
|
|
252
303
|
|
|
@@ -256,12 +307,14 @@ The complete API reference ships in `docs/` alongside this file:
|
|
|
256
307
|
|
|
257
308
|
| File | Contents |
|
|
258
309
|
|------|----------|
|
|
259
|
-
| `docs/serpent.md` | `
|
|
260
|
-
| `docs/chacha20.md` | `ChaCha20`, `Poly1305`, `ChaCha20Poly1305`, `XChaCha20Poly1305`, `
|
|
310
|
+
| `docs/serpent.md` | `SerpentCipher`, `Serpent`, `SerpentCtr`, `SerpentCbc` |
|
|
311
|
+
| `docs/chacha20.md` | `ChaCha20`, `Poly1305`, `ChaCha20Poly1305`, `XChaCha20Poly1305`, `XChaCha20Cipher` |
|
|
261
312
|
| `docs/sha2.md` | `SHA256`, `SHA384`, `SHA512`, `HMAC_SHA256`, `HMAC_SHA384`, `HMAC_SHA512`, `HKDF_SHA256`, `HKDF_SHA512` |
|
|
262
313
|
| `docs/sha3.md` | `SHA3_224`, `SHA3_256`, `SHA3_384`, `SHA3_512`, `SHAKE128`, `SHAKE256` |
|
|
314
|
+
| `docs/aead.md` | `Seal`, `SealStream`, `OpenStream`, `SealStreamPool`, `CipherSuite` |
|
|
315
|
+
| `docs/kyber.md` | `MlKem512`, `MlKem768`, `MlKem1024`, `KyberSuite` — ML-KEM (FIPS 203) API reference |
|
|
263
316
|
| `docs/fortuna.md` | `Fortuna` CSPRNG |
|
|
264
317
|
| `docs/init.md` | `init()` API, loading modes, subpath imports |
|
|
265
318
|
| `docs/utils.md` | Encoding helpers, `constantTimeEqual`, `wipe`, `randomBytes` |
|
|
266
|
-
| `docs/types.md` | `Hash`, `KeyedHash`, `Blockcipher`, `Streamcipher`, `AEAD` interfaces |
|
|
319
|
+
| `docs/types.md` | `Hash`, `KeyedHash`, `Blockcipher`, `Streamcipher`, `AEAD` interfaces; `CipherSuite`, `DerivedKeys`, `SealStreamOpts`, `PoolOpts`, `WasmSource` |
|
|
267
320
|
| `docs/architecture.md` | Module structure, WASM layer, three-tier design |
|