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/sha3.md DELETED
@@ -1,546 +0,0 @@
1
- # SHA3 TypeScript API Reference
2
-
3
- > [!NOTE]
4
- > Covers the SHA-3 hash functions (SHA3-224 through SHA3-512) and the SHAKE extendable-output functions (SHAKE128, SHAKE256). See [SHA-3 implementation audit](./sha3_audit.md) for algorithm correctness verifications.
5
-
6
- > ### Table of Contents
7
- > - [Overview](#overview)
8
- > - [Security Notes](#security-notes)
9
- > - [Module Init](#module-init)
10
- > - [API Reference](#api-reference)
11
- > - [Incremental XOF API](#incremental-xof-api-absorb--squeeze--reset)
12
- > - [Usage Examples](#usage-examples)
13
- > - [Error Conditions](#error-conditions)
14
-
15
- ---
16
-
17
- ## Overview
18
-
19
- The SHA-3 family provides six hash functions standardized in **FIPS 202**: four
20
- fixed-output hash functions (SHA3-224, SHA3-256, SHA3-384, SHA3-512) and two
21
- extendable-output functions, or XOFs (SHAKE128, SHAKE256). All six are built on
22
- the **Keccak sponge construction**, a fundamentally different design from the
23
- Merkle-Damgard structure used by SHA-2.
24
-
25
- SHA-3 is **not** a replacement for SHA-2. Both are considered secure, and both are
26
- standardized by NIST. SHA-3 exists to provide **defense-in-depth**: if a flaw is
27
- ever discovered in SHA-2, SHA-3 is completely unaffected because it uses a different
28
- mathematical foundation. You may never need that insurance, but if you do, you will be
29
- very glad it is there.
30
-
31
- The SHAKE XOFs are particularly flexible. Unlike SHA3-256, which always produces
32
- exactly 32 bytes, SHAKE128 and SHAKE256 can produce variable-length output. You
33
- tell them how many bytes you want, making them useful for key derivation, generating
34
- nonces, or any situation where you need more (or fewer) bytes than a standard hash
35
- provides.
36
-
37
- One key advantage of SHA-3 over SHA-2: **SHA-3 is immune to length extension
38
- attacks.** With SHA-2, if you know `SHA256(secret + message)` but not the secret,
39
- you can compute `SHA256(secret + message + padding + extra)` without knowing the
40
- secret. SHA-3's sponge construction makes this impossible.
41
-
42
- ---
43
-
44
- ## Security Notes
45
-
46
- > [!IMPORTANT]
47
- > Read these before using the API. Misusing hash functions is one of the most
48
- > common sources of security vulnerabilities.
49
-
50
- - **Length extension immunity.** Unlike SHA-2, the SHA-3 sponge construction does
51
- not leak enough internal state for length extension attacks. Computing
52
- `SHA3(secret + message)` does not let an attacker forge `SHA3(secret + message + extra)`.
53
- That said, **HMAC is still the correct way to build a MAC** — do not use raw
54
- `SHA3(key + message)` as a MAC construction, even though it is not vulnerable to
55
- length extension. HMAC provides a formally proven security reduction.
56
-
57
- - **SHAKE output is unbounded.** SHAKE128 and SHAKE256 are full XOFs — output
58
- length is unbounded. Request any number of bytes via `hash()`, or drive the
59
- sponge directly with `absorb()` / `squeeze()`. The only constraint is
60
- `outputLength >= 1`.
61
-
62
- - **Not for password hashing.** SHA-3 is a fast hash, which is the opposite of
63
- what you want for password storage. Passwords must be hashed with a slow,
64
- memory-hardened algorithm like **Argon2id**. See [argon2id.md](./argon2id.md) for
65
- usage patterns including passphrase-based encryption with leviathan primitives.
66
-
67
- - **Call `dispose()` when finished.** Every SHA-3 class wraps a WASM module that
68
- stores Keccak state in linear memory. Calling `dispose()` zeroes all internal
69
- state (the 200-byte lane matrix, input buffer, output buffer, and metadata).
70
- If you skip `dispose()`, key material or intermediate hash state may persist
71
- in memory.
72
-
73
- ---
74
-
75
- ## Module Init
76
-
77
- Each module subpath exports its own init function for consumers who want
78
- tree-shakeable imports.
79
-
80
- ### `sha3Init(source)`
81
-
82
- Initializes only the sha3 WASM binary. Equivalent to calling the
83
- root `init({ sha3: source })` but without pulling the other three
84
- modules into the bundle.
85
-
86
- **Signature:**
87
-
88
- ```typescript
89
- async function sha3Init(source: WasmSource): Promise<void>
90
- ```
91
-
92
- **Usage:**
93
-
94
- ```typescript
95
- import { sha3Init, SHA3_256 } from 'leviathan-crypto/sha3'
96
- import { sha3Wasm } from 'leviathan-crypto/sha3/embedded'
97
-
98
- await sha3Init(sha3Wasm)
99
- const sha3 = new SHA3_256()
100
- ```
101
-
102
- ### keccakInit() Alias
103
-
104
- `'keccak'` is an alias for `'sha3'`. Same WASM binary, same instance slot.
105
- `keccakInit()` and `sha3Init()` are interchangeable.
106
-
107
- ```typescript
108
- import { keccakInit, SHAKE256, SHA3_256 } from 'leviathan-crypto/keccak'
109
- import { keccakWasm } from 'leviathan-crypto/keccak/embedded'
110
-
111
- await keccakInit(keccakWasm)
112
- // isInitialized('sha3') === true — same slot
113
- ```
114
-
115
- Use the `keccak` subpath when the consuming context (such as ML-KEM) makes the
116
- Keccak primitive name semantically clearer. See [init.md](./init.md#keccak-alias-for-ml-kem)
117
- for full details.
118
-
119
- ---
120
-
121
- ## API Reference
122
-
123
- All SHA-3 classes require initialization before use. Either the root `init()`:
124
-
125
- ```typescript
126
- import { init } from 'leviathan-crypto'
127
- import { sha3Wasm } from 'leviathan-crypto/sha3/embedded'
128
-
129
- await init({ sha3: sha3Wasm })
130
- ```
131
-
132
- Or the subpath `sha3Init()`:
133
-
134
- ```typescript
135
- import { sha3Init } from 'leviathan-crypto/sha3'
136
- import { sha3Wasm } from 'leviathan-crypto/sha3/embedded'
137
-
138
- await sha3Init(sha3Wasm)
139
- ```
140
-
141
- If you use SHA-3 classes without calling `init()` first, the constructor
142
- will throw an error.
143
-
144
- ---
145
-
146
- ### SHA3_224
147
-
148
- Fixed-output hash function. Produces a **28-byte** (224-bit) digest.
149
-
150
- ```typescript
151
- class SHA3_224 {
152
- constructor()
153
- hash(msg: Uint8Array): Uint8Array // returns 28 bytes
154
- dispose(): void
155
- }
156
- ```
157
-
158
- ---
159
-
160
- ### SHA3_256
161
-
162
- Fixed-output hash function. Produces a **32-byte** (256-bit) digest. This is the
163
- most commonly used SHA-3 variant; 256-bit security is suitable for most
164
- applications.
165
-
166
- ```typescript
167
- class SHA3_256 {
168
- constructor()
169
- hash(msg: Uint8Array): Uint8Array // returns 32 bytes
170
- dispose(): void
171
- }
172
- ```
173
-
174
- ---
175
-
176
- ### SHA3_384
177
-
178
- Fixed-output hash function. Produces a **48-byte** (384-bit) digest.
179
-
180
- ```typescript
181
- class SHA3_384 {
182
- constructor()
183
- hash(msg: Uint8Array): Uint8Array // returns 48 bytes
184
- dispose(): void
185
- }
186
- ```
187
-
188
- ---
189
-
190
- ### SHA3_512
191
-
192
- Fixed-output hash function. Produces a **64-byte** (512-bit) digest. Use this when
193
- you need the highest security margin.
194
-
195
- ```typescript
196
- class SHA3_512 {
197
- constructor()
198
- hash(msg: Uint8Array): Uint8Array // returns 64 bytes
199
- dispose(): void
200
- }
201
- ```
202
-
203
- ---
204
-
205
- ### SHAKE128
206
-
207
- Extendable-output function (XOF). Produces **variable-length** output — any
208
- number of bytes you request. 128-bit security level.
209
-
210
- ```typescript
211
- class SHAKE128 {
212
- constructor()
213
- hash(msg: Uint8Array, outputLength: number): Uint8Array
214
- absorb(msg: Uint8Array): this
215
- squeeze(n: number): Uint8Array
216
- reset(): this
217
- dispose(): void
218
- }
219
- ```
220
-
221
- | Method | Description |
222
- |--------|-------------|
223
- | `hash(msg, outputLength)` | One-shot: reset, absorb, squeeze. Safe on a dirty instance. |
224
- | `absorb(msg)` | Feed data into the sponge. Chainable. Throws if called after `squeeze()`. |
225
- | `squeeze(n)` | Pull `n` bytes of XOF output. Output is contiguous — `squeeze(a)` followed by `squeeze(b)` yields bytes `[0, a)` and `[a, a+b)` of the XOF stream. |
226
- | `reset()` | Return to a fresh, zeroed state. Chainable. Safe at any point. |
227
- | `dispose()` | Zero all WASM state and the TS-side block buffer. |
228
-
229
- **`outputLength`** / **`n`** must be `>= 1`. Values below 1 throw a `RangeError`.
230
-
231
- ---
232
-
233
- ### SHAKE256
234
-
235
- Extendable-output function (XOF). Produces **variable-length** output — any
236
- number of bytes you request. 256-bit security level.
237
-
238
- ```typescript
239
- class SHAKE256 {
240
- constructor()
241
- hash(msg: Uint8Array, outputLength: number): Uint8Array
242
- absorb(msg: Uint8Array): this
243
- squeeze(n: number): Uint8Array
244
- reset(): this
245
- dispose(): void
246
- }
247
- ```
248
-
249
- | Method | Description |
250
- |--------|-------------|
251
- | `hash(msg, outputLength)` | One-shot: reset, absorb, squeeze. Safe on a dirty instance. |
252
- | `absorb(msg)` | Feed data into the sponge. Chainable. Throws if called after `squeeze()`. |
253
- | `squeeze(n)` | Pull `n` bytes of XOF output. Output is contiguous — `squeeze(a)` followed by `squeeze(b)` yields bytes `[0, a)` and `[a, a+b)` of the XOF stream. |
254
- | `reset()` | Return to a fresh, zeroed state. Chainable. Safe at any point. |
255
- | `dispose()` | Zero all WASM state and the TS-side block buffer. |
256
-
257
- **`outputLength`** / **`n`** must be `>= 1`. Values below 1 throw a `RangeError`.
258
-
259
- ---
260
-
261
- ## Incremental XOF API (`absorb` / `squeeze` / `reset`)
262
-
263
- For use cases where you need to pull output in multiple steps — key derivation,
264
- mask generation, protocol-specific domain separation — the SHAKE classes expose
265
- a streaming interface alongside the one-shot `hash()`.
266
-
267
- ### State machine
268
-
269
- | State | Valid calls |
270
- |-------------|---------------------------------|
271
- | fresh | `absorb()`, `hash()`, `reset()` |
272
- | absorbing | `absorb()`, `squeeze()`, `hash()`, `reset()` |
273
- | squeezing | `squeeze()`, `hash()`, `reset()` |
274
-
275
- Calling `absorb()` while squeezing throws:
276
- `"SHAKE128: cannot absorb after squeeze — call reset() first"`
277
-
278
- `hash()` always resets before running — safe to call on a dirty instance.
279
-
280
- ### Example
281
-
282
- ```typescript
283
- import { init, SHAKE256 } from 'leviathan-crypto'
284
- import { sha3Wasm } from 'leviathan-crypto/sha3/embedded'
285
-
286
- await init({ sha3: sha3Wasm })
287
-
288
- const xof = new SHAKE256()
289
- xof.absorb(ikm) // input key material
290
- xof.absorb(salt) // additional context
291
-
292
- const encKey = xof.squeeze(32) // 256-bit encryption key
293
- const macKey = xof.squeeze(32) // 256-bit MAC key
294
- const nonce = xof.squeeze(12) // 96-bit nonce
295
-
296
- xof.dispose()
297
- ```
298
-
299
- ---
300
-
301
- ## Usage Examples
302
-
303
- ### Example 1: Hash a string with SHA3-256
304
-
305
- The most common use case: hash some data and get a hex digest.
306
-
307
- ```typescript
308
- import { init, SHA3_256, bytesToHex, utf8ToBytes } from 'leviathan-crypto'
309
- import { sha3Wasm } from 'leviathan-crypto/sha3/embedded'
310
-
311
- // Initialize the SHA-3 WASM module (once, at startup)
312
- await init({ sha3: sha3Wasm })
313
-
314
- // Create a hasher
315
- const sha3 = new SHA3_256()
316
-
317
- // Hash a UTF-8 string
318
- const message = utf8ToBytes('Hello, world!')
319
- const digest = sha3.hash(message)
320
-
321
- console.log(bytesToHex(digest))
322
- // 32 bytes (64 hex characters) of SHA3-256 output
323
-
324
- // Clean up -- zeroes all WASM state
325
- sha3.dispose()
326
- ```
327
-
328
- ---
329
-
330
- ### Example 2: Hash binary data with SHA3-512
331
-
332
- ```typescript
333
- import { init, SHA3_512, bytesToHex } from 'leviathan-crypto'
334
- import { sha3Wasm } from 'leviathan-crypto/sha3/embedded'
335
-
336
- await init({ sha3: sha3Wasm })
337
-
338
- const sha3 = new SHA3_512()
339
-
340
- // Hash raw bytes (e.g., a file, a key, a nonce)
341
- const data = new Uint8Array([0x01, 0x02, 0x03, 0x04])
342
- const digest = sha3.hash(data)
343
-
344
- console.log(bytesToHex(digest))
345
- // 64 bytes (128 hex characters) of SHA3-512 output
346
-
347
- sha3.dispose()
348
- ```
349
-
350
- ---
351
-
352
- ### Example 3: Hash multiple messages
353
-
354
- Each call to `hash()` is independent; the internal state resets automatically.
355
- You can reuse the same class instance for multiple hashes.
356
-
357
- ```typescript
358
- import { init, SHA3_256, bytesToHex, utf8ToBytes } from 'leviathan-crypto'
359
- import { sha3Wasm } from 'leviathan-crypto/sha3/embedded'
360
-
361
- await init({ sha3: sha3Wasm })
362
-
363
- const sha3 = new SHA3_256()
364
-
365
- const hash1 = sha3.hash(utf8ToBytes('first message'))
366
- const hash2 = sha3.hash(utf8ToBytes('second message'))
367
- const hash3 = sha3.hash(utf8ToBytes('first message'))
368
-
369
- // hash1 and hash3 are identical -- same input, same output
370
- console.log(bytesToHex(hash1) === bytesToHex(hash3)) // true
371
-
372
- // hash2 is different -- different input
373
- console.log(bytesToHex(hash1) === bytesToHex(hash2)) // false
374
-
375
- sha3.dispose()
376
- ```
377
-
378
- ---
379
-
380
- ### Example 4: SHAKE128 variable-length output
381
-
382
- SHAKE lets you choose exactly how many bytes of output you need. This is useful
383
- for key derivation or generating fixed-size tokens.
384
-
385
- ```typescript
386
- import { init, SHAKE128, bytesToHex, utf8ToBytes } from 'leviathan-crypto'
387
- import { sha3Wasm } from 'leviathan-crypto/sha3/embedded'
388
-
389
- await init({ sha3: sha3Wasm })
390
-
391
- const shake = new SHAKE128()
392
-
393
- const seed = utf8ToBytes('my-application-seed')
394
-
395
- // Derive a 16-byte key (128 bits)
396
- const key128 = shake.hash(seed, 16)
397
- console.log('16-byte key:', bytesToHex(key128))
398
-
399
- // Derive a 32-byte key (256 bits) from the same seed
400
- const key256 = shake.hash(seed, 32)
401
- console.log('32-byte key:', bytesToHex(key256))
402
-
403
- // The 16-byte output is NOT a prefix of the 32-byte output --
404
- // each call resets state, re-absorbs, and squeezes independently.
405
- // However, for SHAKE, the first 16 bytes of the 32-byte output
406
- // ARE identical to the 16-byte output (this is how XOFs work).
407
-
408
- shake.dispose()
409
- ```
410
-
411
- ---
412
-
413
- ### Example 5: SHAKE256 for key derivation
414
-
415
- ```typescript
416
- import { init, SHAKE256, bytesToHex } from 'leviathan-crypto'
417
- import { sha3Wasm } from 'leviathan-crypto/sha3/embedded'
418
-
419
- await init({ sha3: sha3Wasm })
420
-
421
- const shake = new SHAKE256()
422
-
423
- // Derive a 48-byte key from raw entropy
424
- const entropy = crypto.getRandomValues(new Uint8Array(32))
425
- const derivedKey = shake.hash(entropy, 48)
426
-
427
- console.log('Derived key:', bytesToHex(derivedKey))
428
- // 48 bytes (96 hex characters) of SHAKE256 output
429
-
430
- shake.dispose()
431
- ```
432
-
433
- ---
434
-
435
- ### Example 6: SHA-256 vs SHA3-256
436
-
437
- SHA-256 (from the SHA-2 family) and SHA3-256 are completely different algorithms.
438
- They produce different output for the same input. Both are secure; SHA3-256 adds defense-in-depth.
439
-
440
- ```typescript
441
- import { init, SHA256, SHA3_256, bytesToHex, utf8ToBytes } from 'leviathan-crypto'
442
- import { sha2Wasm } from 'leviathan-crypto/sha2/embedded'
443
- import { sha3Wasm } from 'leviathan-crypto/sha3/embedded'
444
-
445
- // Initialize both modules
446
- await init({ sha2: sha2Wasm, sha3: sha3Wasm })
447
-
448
- const sha2 = new SHA256()
449
- const sha3 = new SHA3_256()
450
-
451
- const message = utf8ToBytes('abc')
452
-
453
- const sha2Digest = sha2.hash(message)
454
- const sha3Digest = sha3.hash(message)
455
-
456
- console.log('SHA-256: ', bytesToHex(sha2Digest))
457
- console.log('SHA3-256: ', bytesToHex(sha3Digest))
458
- // These are completely different values -- different algorithms
459
-
460
- sha2.dispose()
461
- sha3.dispose()
462
- ```
463
-
464
- ---
465
-
466
- ### Example 7: Hashing empty input
467
-
468
- All hash functions accept empty input. This is well-defined and produces a
469
- deterministic output.
470
-
471
- ```typescript
472
- import { init, SHA3_256, bytesToHex } from 'leviathan-crypto'
473
- import { sha3Wasm } from 'leviathan-crypto/sha3/embedded'
474
-
475
- await init({ sha3: sha3Wasm })
476
-
477
- const sha3 = new SHA3_256()
478
- const digest = sha3.hash(new Uint8Array(0))
479
-
480
- console.log(bytesToHex(digest))
481
- // The SHA3-256 hash of empty input -- a fixed, known value
482
-
483
- sha3.dispose()
484
- ```
485
-
486
- ---
487
-
488
- ## Error Conditions
489
-
490
- ### SHA-3 module not initialized
491
-
492
- If you construct a SHA-3 class before initializing the module, the constructor
493
- throws immediately:
494
-
495
- ```
496
- Error: leviathan-crypto: call init({ sha3: ... }) before using this class
497
- ```
498
-
499
- **Fix:** Call `await init({ sha3: sha3Wasm })` once at application startup, before creating
500
- any SHA-3 class instances.
501
-
502
- ---
503
-
504
- ### SHAKE output length out of range
505
-
506
- SHAKE128 and SHAKE256 require `outputLength >= 1`. Passing 0 or a negative number
507
- throws a `RangeError`:
508
-
509
- ```
510
- RangeError: outputLength must be >= 1 (got 0)
511
- ```
512
-
513
- **Fix:** Request at least 1 byte.
514
-
515
- ---
516
-
517
- ### SHAKE absorb after squeeze
518
-
519
- Calling `absorb()` after `squeeze()` has been called throws an `Error`. The sponge
520
- has been padded and finalized — further absorption is not meaningful.
521
-
522
- ```
523
- Error: SHAKE128: cannot absorb after squeeze — call reset() first
524
- ```
525
-
526
- **Fix:** Call `reset()` to return the instance to a fresh state before absorbing
527
- new data.
528
-
529
- ---
530
-
531
- ### Empty input
532
-
533
- Passing an empty `Uint8Array` (length 0) is **not** an error. All SHA-3 and SHAKE
534
- functions produce valid, deterministic output for empty input. The sponge simply
535
- absorbs zero bytes and then squeezes.
536
-
537
- ---
538
-
539
- > ## Cross-References
540
- >
541
- > - [index](./README.md) — Project Documentation index
542
- > - [asm_sha3](./asm_sha3.md): WASM implementation details (buffer layout, Keccak internals, variant parameters)
543
- > - [sha2](./sha2.md): Alternative: SHA-2 family (SHA-256, SHA-384, SHA-512) and HMAC
544
- > - [utils](./utils.md): Encoding utilities: `bytesToHex`, `hexToBytes`, `utf8ToBytes`
545
- > - [architecture](./architecture.md) — architecture overview, module relationships, buffer layouts, and build pipeline
546
- > - [sha3_audit.md](./sha3_audit.md) — SHA-3 / Keccak implementation audit