leviathan-crypto 2.0.1 → 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.
Files changed (312) hide show
  1. package/CLAUDE.md +88 -281
  2. package/LICENSE +4 -0
  3. package/README.md +275 -87
  4. package/dist/aes/aes-cbc.d.ts +40 -0
  5. package/dist/aes/aes-cbc.js +158 -0
  6. package/dist/aes/aes-ctr.d.ts +50 -0
  7. package/dist/aes/aes-ctr.js +141 -0
  8. package/dist/aes/aes-gcm-siv.d.ts +67 -0
  9. package/dist/aes/aes-gcm-siv.js +217 -0
  10. package/dist/aes/aes-gcm.d.ts +61 -0
  11. package/dist/aes/aes-gcm.js +226 -0
  12. package/dist/aes/cipher-suite.d.ts +21 -0
  13. package/dist/aes/cipher-suite.js +179 -0
  14. package/dist/aes/embedded.d.ts +1 -0
  15. package/dist/aes/embedded.js +26 -0
  16. package/dist/aes/generator.d.ts +14 -0
  17. package/dist/aes/generator.js +103 -0
  18. package/dist/aes/index.d.ts +58 -0
  19. package/dist/aes/index.js +125 -0
  20. package/dist/aes/ops.d.ts +60 -0
  21. package/dist/aes/ops.js +164 -0
  22. package/dist/aes/pool-worker.d.ts +1 -0
  23. package/dist/aes/pool-worker.js +92 -0
  24. package/dist/aes/types.d.ts +1 -0
  25. package/dist/aes/types.js +23 -0
  26. package/dist/aes.wasm +0 -0
  27. package/dist/blake3/embedded.d.ts +1 -0
  28. package/dist/blake3/embedded.js +26 -0
  29. package/dist/blake3/index.d.ts +143 -0
  30. package/dist/blake3/index.js +620 -0
  31. package/dist/blake3/types.d.ts +102 -0
  32. package/dist/blake3/types.js +31 -0
  33. package/dist/blake3/validate.d.ts +29 -0
  34. package/dist/blake3/validate.js +80 -0
  35. package/dist/blake3.wasm +0 -0
  36. package/dist/chacha20/cipher-suite.d.ts +10 -0
  37. package/dist/chacha20/cipher-suite.js +98 -13
  38. package/dist/chacha20/generator.d.ts +12 -0
  39. package/dist/chacha20/generator.js +91 -0
  40. package/dist/chacha20/index.d.ts +100 -3
  41. package/dist/chacha20/index.js +169 -35
  42. package/dist/chacha20/ops.d.ts +57 -6
  43. package/dist/chacha20/ops.js +107 -27
  44. package/dist/chacha20/pool-worker.js +14 -0
  45. package/dist/chacha20/types.d.ts +1 -32
  46. package/dist/cte-wasm.d.ts +1 -0
  47. package/dist/cte-wasm.js +3 -0
  48. package/dist/cte.wasm +0 -0
  49. package/dist/curve25519.wasm +0 -0
  50. package/dist/ecdsa/der.d.ts +23 -0
  51. package/dist/ecdsa/der.js +192 -0
  52. package/dist/ecdsa/ecprivatekey-der.d.ts +32 -0
  53. package/dist/ecdsa/ecprivatekey-der.js +230 -0
  54. package/dist/ecdsa/embedded.d.ts +1 -0
  55. package/dist/ecdsa/embedded.js +25 -0
  56. package/dist/ecdsa/index.d.ts +124 -0
  57. package/dist/ecdsa/index.js +366 -0
  58. package/dist/ecdsa/types.d.ts +31 -0
  59. package/dist/ecdsa/types.js +28 -0
  60. package/dist/ecdsa/validate.d.ts +18 -0
  61. package/dist/ecdsa/validate.js +92 -0
  62. package/dist/ed25519/embedded.d.ts +1 -0
  63. package/dist/ed25519/embedded.js +31 -0
  64. package/dist/ed25519/index.d.ts +70 -0
  65. package/dist/ed25519/index.js +308 -0
  66. package/dist/ed25519/types.d.ts +27 -0
  67. package/dist/ed25519/types.js +27 -0
  68. package/dist/ed25519/validate.d.ts +7 -0
  69. package/dist/ed25519/validate.js +77 -0
  70. package/dist/embedded/aes-pool-worker.d.ts +1 -0
  71. package/dist/embedded/aes-pool-worker.js +5 -0
  72. package/dist/embedded/aes.d.ts +1 -0
  73. package/dist/embedded/aes.js +3 -0
  74. package/dist/embedded/blake3.d.ts +1 -0
  75. package/dist/embedded/blake3.js +3 -0
  76. package/dist/embedded/chacha20-pool-worker.d.ts +1 -0
  77. package/dist/embedded/chacha20-pool-worker.js +5 -0
  78. package/dist/embedded/chacha20.d.ts +1 -1
  79. package/dist/embedded/chacha20.js +2 -2
  80. package/dist/embedded/curve25519.d.ts +1 -0
  81. package/dist/embedded/curve25519.js +3 -0
  82. package/dist/embedded/mldsa.d.ts +1 -0
  83. package/dist/embedded/mldsa.js +3 -0
  84. package/dist/embedded/mlkem.d.ts +1 -0
  85. package/dist/embedded/mlkem.js +3 -0
  86. package/dist/embedded/p256.d.ts +1 -0
  87. package/dist/embedded/p256.js +3 -0
  88. package/dist/embedded/serpent-pool-worker.d.ts +1 -0
  89. package/dist/embedded/serpent-pool-worker.js +5 -0
  90. package/dist/embedded/serpent.d.ts +1 -1
  91. package/dist/embedded/serpent.js +2 -2
  92. package/dist/embedded/sha2.d.ts +1 -1
  93. package/dist/embedded/sha2.js +2 -2
  94. package/dist/embedded/sha3.d.ts +1 -1
  95. package/dist/embedded/sha3.js +2 -2
  96. package/dist/embedded/slhdsa.d.ts +1 -0
  97. package/dist/embedded/slhdsa.js +3 -0
  98. package/dist/errors.d.ts +92 -1
  99. package/dist/errors.js +111 -1
  100. package/dist/fortuna.d.ts +18 -12
  101. package/dist/fortuna.js +166 -99
  102. package/dist/index.d.ts +42 -11
  103. package/dist/index.js +65 -20
  104. package/dist/init.d.ts +1 -3
  105. package/dist/init.js +73 -7
  106. package/dist/keccak/embedded.js +1 -1
  107. package/dist/keccak/index.d.ts +2 -0
  108. package/dist/keccak/index.js +4 -2
  109. package/dist/loader.d.ts +1 -19
  110. package/dist/loader.js +26 -32
  111. package/dist/merkle/blake3-tree.d.ts +35 -0
  112. package/dist/merkle/blake3-tree.js +187 -0
  113. package/dist/merkle/checkpoint.d.ts +58 -0
  114. package/dist/merkle/checkpoint.js +217 -0
  115. package/dist/merkle/index.d.ts +19 -0
  116. package/dist/merkle/index.js +37 -0
  117. package/dist/merkle/merkle-log.d.ts +130 -0
  118. package/dist/merkle/merkle-log.js +207 -0
  119. package/dist/merkle/merkle-verifier.d.ts +126 -0
  120. package/dist/merkle/merkle-verifier.js +296 -0
  121. package/dist/merkle/proof.d.ts +70 -0
  122. package/dist/merkle/proof.js +300 -0
  123. package/dist/merkle/sha256-tree.d.ts +33 -0
  124. package/dist/merkle/sha256-tree.js +145 -0
  125. package/dist/merkle/signed-log.d.ts +156 -0
  126. package/dist/merkle/signed-log.js +356 -0
  127. package/dist/merkle/signed-note.d.ts +309 -0
  128. package/dist/merkle/signed-note.js +648 -0
  129. package/dist/merkle/sth.d.ts +31 -0
  130. package/dist/merkle/sth.js +31 -0
  131. package/dist/merkle/storage.d.ts +40 -0
  132. package/dist/merkle/storage.js +71 -0
  133. package/dist/merkle/tree.d.ts +68 -0
  134. package/dist/merkle/tree.js +94 -0
  135. package/dist/mldsa/embedded.d.ts +1 -0
  136. package/dist/{kyber → mldsa}/embedded.js +5 -5
  137. package/dist/mldsa/expand.d.ts +53 -0
  138. package/dist/mldsa/expand.js +188 -0
  139. package/dist/mldsa/format.d.ts +16 -0
  140. package/dist/mldsa/format.js +68 -0
  141. package/dist/mldsa/hashvariant.d.ts +32 -0
  142. package/dist/mldsa/hashvariant.js +248 -0
  143. package/dist/mldsa/index.d.ts +142 -0
  144. package/dist/mldsa/index.js +463 -0
  145. package/dist/mldsa/keygen.d.ts +16 -0
  146. package/dist/mldsa/keygen.js +232 -0
  147. package/dist/mldsa/params.d.ts +21 -0
  148. package/dist/mldsa/params.js +55 -0
  149. package/dist/mldsa/sha3-helpers.d.ts +30 -0
  150. package/dist/mldsa/sha3-helpers.js +124 -0
  151. package/dist/mldsa/sign.d.ts +36 -0
  152. package/dist/mldsa/sign.js +380 -0
  153. package/dist/mldsa/types.d.ts +91 -0
  154. package/dist/mldsa/types.js +25 -0
  155. package/dist/mldsa/validate.d.ts +55 -0
  156. package/dist/mldsa/validate.js +125 -0
  157. package/dist/mldsa/verify.d.ts +29 -0
  158. package/dist/mldsa/verify.js +269 -0
  159. package/dist/mldsa.wasm +0 -0
  160. package/dist/mlkem/embedded.d.ts +1 -0
  161. package/dist/mlkem/embedded.js +27 -0
  162. package/dist/mlkem/indcpa.d.ts +49 -0
  163. package/dist/{kyber → mlkem}/indcpa.js +48 -48
  164. package/dist/mlkem/index.d.ts +37 -0
  165. package/dist/{kyber → mlkem}/index.js +41 -31
  166. package/dist/mlkem/kem.d.ts +21 -0
  167. package/dist/{kyber → mlkem}/kem.js +48 -13
  168. package/dist/{kyber → mlkem}/params.d.ts +4 -4
  169. package/dist/{kyber → mlkem}/params.js +2 -2
  170. package/dist/mlkem/suite.d.ts +12 -0
  171. package/dist/{kyber → mlkem}/suite.js +17 -12
  172. package/dist/{kyber → mlkem}/types.d.ts +4 -3
  173. package/dist/{kyber → mlkem}/types.js +1 -1
  174. package/dist/mlkem/validate.d.ts +23 -0
  175. package/dist/{kyber → mlkem}/validate.js +24 -20
  176. package/dist/{kyber.wasm → mlkem.wasm} +0 -0
  177. package/dist/p256.wasm +0 -0
  178. package/dist/ratchet/index.d.ts +8 -0
  179. package/dist/ratchet/index.js +38 -0
  180. package/dist/ratchet/kdf-chain.d.ts +13 -0
  181. package/dist/ratchet/kdf-chain.js +85 -0
  182. package/dist/ratchet/ratchet-keypair.d.ts +9 -0
  183. package/dist/ratchet/ratchet-keypair.js +61 -0
  184. package/dist/ratchet/root-kdf.d.ts +4 -0
  185. package/dist/ratchet/root-kdf.js +124 -0
  186. package/dist/ratchet/skipped-key-store.d.ts +14 -0
  187. package/dist/ratchet/skipped-key-store.js +154 -0
  188. package/dist/ratchet/types.d.ts +36 -0
  189. package/dist/ratchet/types.js +26 -0
  190. package/dist/serpent/cipher-suite.d.ts +10 -0
  191. package/dist/serpent/cipher-suite.js +144 -56
  192. package/dist/serpent/generator.d.ts +12 -0
  193. package/dist/serpent/generator.js +97 -0
  194. package/dist/serpent/index.d.ts +62 -1
  195. package/dist/serpent/index.js +97 -21
  196. package/dist/serpent/pool-worker.js +28 -102
  197. package/dist/serpent/serpent-cbc.d.ts +16 -6
  198. package/dist/serpent/serpent-cbc.js +58 -37
  199. package/dist/serpent/shared-ops.d.ts +63 -0
  200. package/dist/serpent/shared-ops.js +178 -0
  201. package/dist/serpent/types.d.ts +1 -5
  202. package/dist/serpent.wasm +0 -0
  203. package/dist/sha2/hash.d.ts +2 -0
  204. package/dist/sha2/hash.js +53 -0
  205. package/dist/sha2/hkdf.js +5 -5
  206. package/dist/sha2/index.d.ts +22 -1
  207. package/dist/sha2/index.js +80 -11
  208. package/dist/sha2/types.d.ts +41 -2
  209. package/dist/sha2.wasm +0 -0
  210. package/dist/sha3/hash.d.ts +2 -0
  211. package/dist/sha3/hash.js +53 -0
  212. package/dist/sha3/index.d.ts +87 -3
  213. package/dist/sha3/index.js +317 -19
  214. package/dist/sha3/kmac.d.ts +121 -0
  215. package/dist/sha3/kmac.js +800 -0
  216. package/dist/sha3.wasm +0 -0
  217. package/dist/shared/pkcs7.d.ts +22 -0
  218. package/dist/shared/pkcs7.js +84 -0
  219. package/dist/sign/ctx.d.ts +41 -0
  220. package/dist/sign/ctx.js +102 -0
  221. package/dist/sign/envelope.d.ts +45 -0
  222. package/dist/sign/envelope.js +152 -0
  223. package/dist/sign/hasher.d.ts +9 -0
  224. package/dist/sign/hasher.js +132 -0
  225. package/dist/sign/index.d.ts +11 -0
  226. package/dist/sign/index.js +34 -0
  227. package/dist/sign/sign-stream.d.ts +25 -0
  228. package/dist/sign/sign-stream.js +112 -0
  229. package/dist/sign/suites/ecdsa-p256.d.ts +2 -0
  230. package/dist/sign/suites/ecdsa-p256.js +120 -0
  231. package/dist/sign/suites/ed25519.d.ts +3 -0
  232. package/dist/sign/suites/ed25519.js +165 -0
  233. package/dist/sign/suites/hybrid-classical.d.ts +23 -0
  234. package/dist/sign/suites/hybrid-classical.js +526 -0
  235. package/dist/sign/suites/hybrid-pq.d.ts +4 -0
  236. package/dist/sign/suites/hybrid-pq.js +234 -0
  237. package/dist/sign/suites/mldsa.d.ts +7 -0
  238. package/dist/sign/suites/mldsa.js +161 -0
  239. package/dist/sign/suites/slhdsa.d.ts +7 -0
  240. package/dist/sign/suites/slhdsa.js +176 -0
  241. package/dist/sign/types.d.ts +106 -0
  242. package/dist/sign/types.js +28 -0
  243. package/dist/sign/verify-stream.d.ts +30 -0
  244. package/dist/sign/verify-stream.js +227 -0
  245. package/dist/slhdsa/embedded.d.ts +1 -0
  246. package/dist/slhdsa/embedded.js +26 -0
  247. package/dist/slhdsa/index.d.ts +149 -0
  248. package/dist/slhdsa/index.js +493 -0
  249. package/dist/slhdsa/params.d.ts +26 -0
  250. package/dist/slhdsa/params.js +70 -0
  251. package/dist/slhdsa/prehash.d.ts +68 -0
  252. package/dist/slhdsa/prehash.js +307 -0
  253. package/dist/slhdsa/sign.d.ts +39 -0
  254. package/dist/slhdsa/sign.js +116 -0
  255. package/dist/slhdsa/types.d.ts +129 -0
  256. package/dist/slhdsa/types.js +27 -0
  257. package/dist/slhdsa/validate.d.ts +60 -0
  258. package/dist/slhdsa/validate.js +127 -0
  259. package/dist/slhdsa/verify.d.ts +32 -0
  260. package/dist/slhdsa/verify.js +107 -0
  261. package/dist/slhdsa.wasm +0 -0
  262. package/dist/stream/header.js +8 -8
  263. package/dist/stream/index.d.ts +1 -0
  264. package/dist/stream/index.js +1 -0
  265. package/dist/stream/open-stream.js +65 -22
  266. package/dist/stream/seal-stream-pool.d.ts +2 -0
  267. package/dist/stream/seal-stream-pool.js +100 -33
  268. package/dist/stream/seal-stream.d.ts +1 -1
  269. package/dist/stream/seal-stream.js +48 -19
  270. package/dist/stream/seal.js +6 -6
  271. package/dist/stream/types.d.ts +3 -1
  272. package/dist/stream/types.js +1 -1
  273. package/dist/types.d.ts +22 -1
  274. package/dist/types.js +1 -1
  275. package/dist/utils.d.ts +9 -10
  276. package/dist/utils.js +84 -59
  277. package/dist/wasm-source.d.ts +9 -8
  278. package/dist/wasm-source.js +1 -1
  279. package/dist/x25519/embedded.d.ts +1 -0
  280. package/dist/x25519/embedded.js +31 -0
  281. package/dist/x25519/index.d.ts +43 -0
  282. package/dist/x25519/index.js +159 -0
  283. package/dist/x25519/types.d.ts +25 -0
  284. package/dist/x25519/types.js +27 -0
  285. package/dist/x25519/validate.d.ts +2 -0
  286. package/dist/x25519/validate.js +39 -0
  287. package/package.json +123 -64
  288. package/SECURITY.md +0 -276
  289. package/dist/ct-wasm.d.ts +0 -1
  290. package/dist/ct-wasm.js +0 -3
  291. package/dist/ct.wasm +0 -0
  292. package/dist/docs/aead.md +0 -323
  293. package/dist/docs/architecture.md +0 -932
  294. package/dist/docs/argon2id.md +0 -302
  295. package/dist/docs/chacha20.md +0 -674
  296. package/dist/docs/exports.md +0 -241
  297. package/dist/docs/fortuna.md +0 -313
  298. package/dist/docs/init.md +0 -302
  299. package/dist/docs/loader.md +0 -161
  300. package/dist/docs/serpent.md +0 -519
  301. package/dist/docs/sha2.md +0 -613
  302. package/dist/docs/sha3.md +0 -546
  303. package/dist/docs/types.md +0 -276
  304. package/dist/docs/utils.md +0 -367
  305. package/dist/embedded/kyber.d.ts +0 -1
  306. package/dist/embedded/kyber.js +0 -3
  307. package/dist/kyber/embedded.d.ts +0 -1
  308. package/dist/kyber/indcpa.d.ts +0 -49
  309. package/dist/kyber/index.d.ts +0 -38
  310. package/dist/kyber/kem.d.ts +0 -21
  311. package/dist/kyber/suite.d.ts +0 -13
  312. package/dist/kyber/validate.d.ts +0 -19
package/dist/docs/init.md DELETED
@@ -1,302 +0,0 @@
1
- # Module Initialization and WASM Loading
2
-
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
6
- > available to all wrapper classes.
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
-
17
- ## Overview
18
-
19
- leviathan-crypto runs all cryptographic computation inside WebAssembly modules.
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.
31
-
32
- ---
33
-
34
- ## Security Notes
35
-
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.
49
-
50
- ---
51
-
52
- ## API Reference
53
-
54
- ### Types
55
-
56
- ```typescript
57
- type Module = 'serpent' | 'chacha20' | 'sha2' | 'sha3' | 'keccak' | 'kyber'
58
- ```
59
-
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.
62
-
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) |
73
-
74
- ```typescript
75
- type WasmSource = string | URL | ArrayBuffer | Uint8Array
76
- | WebAssembly.Module | Response | Promise<Response>
77
- ```
78
-
79
- A value that resolves to a WASM binary. The loading strategy is inferred from
80
- the type:
81
-
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`. |
90
-
91
- ---
92
-
93
- ### Functions
94
-
95
- #### init()
96
-
97
- ```typescript
98
- async function init(
99
- sources: Partial<Record<Module, WasmSource>>,
100
- ): Promise<void>
101
- ```
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
-
107
- ---
108
-
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.
113
-
114
- ```typescript
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>
121
- ```
122
-
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
-
130
- The `/embedded` subpath for each module provides the gzip+base64 blob as a
131
- ready-to-use `WasmSource`:
132
-
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` |
141
-
142
- `keccakWasm` and `sha3Wasm` are the same gzip+base64 blob. Both point to `sha3.wasm`.
143
-
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
- ---
151
-
152
- #### isInitialized()
153
-
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.
160
-
161
- > [!NOTE]
162
- > `isInitialized` is a diagnostic indicator, not a control mechanism. Use
163
- > `init()` to load modules. Do not guard calls on this value.
164
-
165
- ---
166
-
167
- #### getInstance()
168
-
169
- ```typescript
170
- function getInstance(mod: Module): WebAssembly.Instance
171
- ```
172
-
173
- Returns the cached WebAssembly instance for a module. Used internally by
174
- wrapper classes. You do not normally need to call this yourself.
175
-
176
- Throws `'leviathan-crypto: call init({ <mod>: ... }) before using this class'`
177
- if the module has not been initialized.
178
-
179
- ---
180
-
181
- #### compileWasm()
182
-
183
- ```typescript
184
- async function compileWasm(source: WasmSource): Promise<WebAssembly.Module>
185
- ```
186
-
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
-
191
- ---
192
-
193
- #### _resetForTesting()
194
-
195
- ```typescript
196
- function _resetForTesting(): void
197
- ```
198
-
199
- Clears all cached WASM instances. Testing utility only. Do not use in
200
- production code.
201
-
202
- ---
203
-
204
- ## Usage Examples
205
-
206
- ### Embedded init (most common)
207
-
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()`.
210
-
211
- ```typescript
212
- import { init } from 'leviathan-crypto'
213
- import { serpentWasm } from 'leviathan-crypto/serpent/embedded'
214
- import { sha2Wasm } from 'leviathan-crypto/sha2/embedded'
215
-
216
- await init({ serpent: serpentWasm, sha2: sha2Wasm })
217
- ```
218
-
219
- ### Per-module init (tree-shaking)
220
-
221
- Use the subpath init function when you need one module and want the smallest
222
- possible bundle:
223
-
224
- ```typescript
225
- import { serpentInit } from 'leviathan-crypto/serpent'
226
- import { serpentWasm } from 'leviathan-crypto/serpent/embedded'
227
-
228
- await serpentInit(serpentWasm)
229
- ```
230
-
231
- ### Keccak alias (for ML-KEM)
232
-
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:
236
-
237
- ```typescript
238
- import { init } from 'leviathan-crypto'
239
- import { keccakWasm } from 'leviathan-crypto/keccak/embedded'
240
-
241
- await init({ keccak: keccakWasm })
242
- // isInitialized('sha3') === true — same slot
243
- // isInitialized('keccak') === true — alias resolves symmetrically
244
- ```
245
-
246
- Or via the subpath directly:
247
-
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
- ```
254
-
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`.
259
-
260
- ```typescript
261
- await init({ serpent: new URL('https://unpkg.com/leviathan-crypto/dist/serpent.wasm') })
262
- ```
263
-
264
- ### Pre-compiled module (edge runtimes)
265
-
266
- If you have already compiled the binary, for example from a KV cache, pass the
267
- `WebAssembly.Module` directly:
268
-
269
- ```typescript
270
- const mod = await WebAssembly.compile(bytes)
271
- await init({ serpent: mod })
272
- ```
273
-
274
- ### Checking initialization state
275
-
276
- ```typescript
277
- import { isInitialized } from 'leviathan-crypto'
278
-
279
- if (!isInitialized('sha2')) {
280
- // handle accordingly
281
- }
282
- ```
283
-
284
- ---
285
-
286
- ## Error Conditions
287
-
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. |
294
-
295
- ---
296
-
297
- > ## Cross-References
298
- >
299
- > - [index](./README.md) — Project Documentation index
300
- > - [architecture](./architecture.md) — architecture overview, module relationships, buffer layouts, and build pipeline
301
- > - [loader](./loader.md) — WASM binary loading strategies (internal details)
302
- > - [wasm](./wasm.md) — WebAssembly primer: modules, instances, memory, and the init gate
@@ -1,161 +0,0 @@
1
- # WASM Binary Loading Strategies
2
-
3
- > [!NOTE]
4
- > Internal module used by `init()` that handles the actual loading and
5
- > instantiation of WebAssembly binaries. You normally do not interact
6
- > with this module directly.
7
-
8
- > ### Table of Contents
9
- > - [Overview](#overview)
10
- > - [Security Notes](#security-notes)
11
- > - [API Reference](#api-reference)
12
- > - [Internal Details](#internal-details)
13
-
14
- ---
15
-
16
- ## Overview
17
-
18
- When you call [`init()`](./init.md), it delegates the work of obtaining and compiling the
19
- WASM binary to the loader. The loading strategy is inferred from the
20
- `WasmSource` type, so no mode string is required:
21
-
22
- **Embedded string.** gzip-compressed, base64-encoded WASM bundled in the package. Decoded and decompressed at [`init()`](./init.md) time using `DecompressionStream`. No network requests. This is the default and simplest option.
23
-
24
- **URL.** Fetches the `.wasm` file and uses the browser's streaming compilation API. The browser can start compiling while still downloading.
25
-
26
- **ArrayBuffer / Uint8Array.** Raw WASM bytes, compiled directly.
27
-
28
- **WebAssembly.Module.** Already compiled. Instantiated immediately. Useful for edge runtimes and KV-cached modules.
29
-
30
- **Response / Promise\<Response\>.** Streaming compilation from an in-flight or deferred fetch.
31
-
32
- All strategies produce the same result: a `WebAssembly.Instance` that the
33
- wrapper classes use to perform cryptographic operations.
34
-
35
- ---
36
-
37
- ## Security Notes
38
-
39
- **Embedded mode requires no network access.** The WASM binary is part of the installed package. This eliminates the risk of a compromised CDN or man-in-the-middle attack altering the binary at load time.
40
-
41
- **URL-based loading requires correct MIME type.** The `.wasm` files must be served with `Content-Type: application/wasm`. This is a browser requirement for `WebAssembly.instantiateStreaming`. If the header is missing or wrong, the browser will reject the response.
42
-
43
- **Raw binary / Module sources place integrity responsibility on you.** The loader instantiates whatever binary you provide. If you supply your own bytes or pre-compiled Module, you are responsible for verifying authenticity.
44
-
45
- **Each module gets its own memory.** Every instantiation creates a fresh `WebAssembly.Memory` with 3 pages (192 KB). Modules cannot share or access each other's memory. Key material in one module's memory space is isolated from all other modules.
46
-
47
- ---
48
-
49
- ## API Reference
50
-
51
- These functions are exported from `loader.ts` and called by `init.ts`. They
52
- are not part of the public API. They are documented here for completeness and for contributors working on the internals.
53
-
54
- ### `loadWasm(source)`
55
- ```typescript
56
- async function loadWasm(source: WasmSource): Promise<WebAssembly.Instance>
57
- ```
58
-
59
- Loads and instantiates a WASM module from any accepted source type. Each
60
- instance receives a fresh 3-page `WebAssembly.Memory`.
61
-
62
- **Source type handling:**
63
-
64
- | Source type | Loading path |
65
- |--------------------------------|----------------------------------------------------------------------|
66
- | `string` | Decoded from gzip+base64 via `decodeWasm()`, then `WebAssembly.instantiate()`. |
67
- | `URL` | `WebAssembly.instantiateStreaming(fetch(url))`. |
68
- | `ArrayBuffer` | `WebAssembly.instantiate()`. |
69
- | `Uint8Array` | `WebAssembly.instantiate()`. |
70
- | `WebAssembly.Module` | `WebAssembly.instantiate(module, imports)`. |
71
- | `Response` / `Promise<Response>` | `WebAssembly.instantiateStreaming()`. |
72
-
73
- **Throws:**
74
-
75
- - `TypeError` if `source` is null, numeric, or otherwise unrecognised.
76
- - `TypeError` with `"empty string"` if `source` is an empty string.
77
-
78
- **Runtime guards:** `Response` and `Promise` checks are guarded with
79
- `typeof Response !== 'undefined'` to avoid `ReferenceError` in runtimes
80
- where these globals do not exist (Node < 18).
81
-
82
- ---
83
-
84
- ### `compileWasm(source)`
85
- ```typescript
86
- async function compileWasm(source: WasmSource): Promise<WebAssembly.Module>
87
- ```
88
-
89
- Compiles a `WasmSource` to a `WebAssembly.Module` without instantiating it.
90
- Used by pool infrastructure to send a compiled module to workers. Each worker receives the `Module` and instantiates it with their own isolated memory.
91
-
92
- **Source type handling:** Same dispatch table as `loadWasm()`, but calls
93
- `WebAssembly.compile()` / `WebAssembly.compileStreaming()` instead of the
94
- `instantiate` variants. `WebAssembly.Module` sources are returned as-is.
95
-
96
- **Throws:** Same as `loadWasm()`.
97
-
98
- ---
99
-
100
- ### `decodeWasm(b64)`
101
- ```typescript
102
- async function decodeWasm(b64: string): Promise<Uint8Array>
103
- ```
104
-
105
- Decodes a gzip-compressed, base64-encoded WASM string to raw bytes.
106
-
107
- 1. Base64-decodes the string using the shared `base64ToBytes` utility.
108
- 2. Decompresses the result using `DecompressionStream('gzip')`.
109
-
110
- **Throws:**
111
-
112
- - `Error` if `DecompressionStream` is not available in the runtime.
113
- The error message directs the user to provide a URL, ArrayBuffer, or
114
- WebAssembly.Module source instead.
115
- - `Error` if base64 decoding fails (corrupt embedded blob).
116
-
117
- Exported for use by pool worker launchers that need to decode blobs
118
- before spawning threads.
119
-
120
- ---
121
-
122
- ## Internal Details
123
-
124
- ### Embedded binary structure
125
-
126
- Each module provides two paths to its embedded blob:
127
-
128
- | Path | Export | Used by |
129
- |----------------------------------------|-----------------|-----------------------------|
130
- | `src/ts/embedded/serpent.ts` | (raw blob) | Build artifact, gitignored |
131
- | `src/ts/serpent/embedded.ts` | `serpentWasm` | Consumer import |
132
-
133
- The per-module `embedded.ts` re-exports the generated blob as a named
134
- export. Consumers import from the `/embedded` subpath:
135
- ```typescript
136
- import { serpentWasm } from 'leviathan-crypto/serpent/embedded'
137
- ```
138
-
139
- The `src/ts/embedded/` directory is generated by `scripts/embed-wasm.ts`
140
- and is gitignored. These files are not meant to be created or edited by hand.
141
-
142
- ### Embedded compression
143
-
144
- The embedded files contain gzip-compressed WASM encoded as base64.
145
- Compression reduces the embedded footprint from ~198 KB to ~33 KB across
146
- all four modules, with Serpent alone shrinking from ~167 KB to ~20 KB.
147
-
148
- ### Memory allocation
149
-
150
- Every WASM instance receives a `WebAssembly.Memory` with exactly 3 pages
151
- (192 KB total). The memory size is fixed; modules do not grow their memory at runtime. This is a deliberate design choice: fixed memory prevents
152
- unexpected allocations and makes the memory layout predictable and auditable.
153
-
154
- ---
155
-
156
- > ## Cross-References
157
- >
158
- > - [index](./README.md) — Project Documentation index
159
- > - [architecture](./architecture.md) — architecture overview, module relationships, buffer layouts, and build pipeline
160
- > - [init](./init.md) — the public `init()` API that uses this loader
161
- > - [wasm](./wasm.md) — WebAssembly primer: modules, instances, and memory model