leviathan-crypto 2.1.0 → 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 (296) hide show
  1. package/CLAUDE.md +86 -443
  2. package/README.md +198 -65
  3. package/dist/aes/aes-cbc.d.ts +40 -0
  4. package/dist/aes/aes-cbc.js +158 -0
  5. package/dist/aes/aes-ctr.d.ts +50 -0
  6. package/dist/aes/aes-ctr.js +141 -0
  7. package/dist/aes/aes-gcm-siv.d.ts +67 -0
  8. package/dist/aes/aes-gcm-siv.js +217 -0
  9. package/dist/aes/aes-gcm.d.ts +61 -0
  10. package/dist/aes/aes-gcm.js +226 -0
  11. package/dist/aes/cipher-suite.d.ts +21 -0
  12. package/dist/aes/cipher-suite.js +179 -0
  13. package/dist/aes/embedded.d.ts +1 -0
  14. package/dist/aes/embedded.js +26 -0
  15. package/dist/aes/generator.d.ts +14 -0
  16. package/dist/aes/generator.js +103 -0
  17. package/dist/aes/index.d.ts +58 -0
  18. package/dist/aes/index.js +125 -0
  19. package/dist/aes/ops.d.ts +60 -0
  20. package/dist/aes/ops.js +164 -0
  21. package/dist/aes/pool-worker.d.ts +1 -0
  22. package/dist/aes/pool-worker.js +92 -0
  23. package/dist/aes/types.d.ts +1 -0
  24. package/dist/aes/types.js +23 -0
  25. package/dist/aes.wasm +0 -0
  26. package/dist/blake3/embedded.d.ts +1 -0
  27. package/dist/blake3/embedded.js +26 -0
  28. package/dist/blake3/index.d.ts +143 -0
  29. package/dist/blake3/index.js +620 -0
  30. package/dist/blake3/types.d.ts +102 -0
  31. package/dist/blake3/types.js +31 -0
  32. package/dist/blake3/validate.d.ts +29 -0
  33. package/dist/blake3/validate.js +80 -0
  34. package/dist/blake3.wasm +0 -0
  35. package/dist/chacha20/cipher-suite.js +47 -25
  36. package/dist/chacha20/generator.d.ts +2 -2
  37. package/dist/chacha20/generator.js +4 -4
  38. package/dist/chacha20/index.d.ts +16 -15
  39. package/dist/chacha20/index.js +52 -46
  40. package/dist/chacha20/ops.d.ts +7 -7
  41. package/dist/chacha20/ops.js +34 -34
  42. package/dist/chacha20/pool-worker.js +5 -3
  43. package/dist/cte-wasm.d.ts +1 -0
  44. package/dist/cte-wasm.js +3 -0
  45. package/dist/curve25519.wasm +0 -0
  46. package/dist/ecdsa/der.d.ts +23 -0
  47. package/dist/ecdsa/der.js +192 -0
  48. package/dist/ecdsa/ecprivatekey-der.d.ts +32 -0
  49. package/dist/ecdsa/ecprivatekey-der.js +230 -0
  50. package/dist/ecdsa/embedded.d.ts +1 -0
  51. package/dist/ecdsa/embedded.js +25 -0
  52. package/dist/ecdsa/index.d.ts +124 -0
  53. package/dist/ecdsa/index.js +366 -0
  54. package/dist/ecdsa/types.d.ts +31 -0
  55. package/dist/ecdsa/types.js +28 -0
  56. package/dist/ecdsa/validate.d.ts +18 -0
  57. package/dist/ecdsa/validate.js +92 -0
  58. package/dist/ed25519/embedded.d.ts +1 -0
  59. package/dist/ed25519/embedded.js +31 -0
  60. package/dist/ed25519/index.d.ts +70 -0
  61. package/dist/ed25519/index.js +308 -0
  62. package/dist/ed25519/types.d.ts +27 -0
  63. package/dist/ed25519/types.js +27 -0
  64. package/dist/ed25519/validate.d.ts +7 -0
  65. package/dist/ed25519/validate.js +77 -0
  66. package/dist/embedded/aes-pool-worker.d.ts +1 -0
  67. package/dist/embedded/aes-pool-worker.js +5 -0
  68. package/dist/embedded/aes.d.ts +1 -0
  69. package/dist/embedded/aes.js +3 -0
  70. package/dist/embedded/blake3.d.ts +1 -0
  71. package/dist/embedded/blake3.js +3 -0
  72. package/dist/embedded/chacha20-pool-worker.d.ts +1 -1
  73. package/dist/embedded/chacha20-pool-worker.js +2 -2
  74. package/dist/embedded/chacha20.d.ts +1 -1
  75. package/dist/embedded/chacha20.js +2 -2
  76. package/dist/embedded/curve25519.d.ts +1 -0
  77. package/dist/embedded/curve25519.js +3 -0
  78. package/dist/embedded/mldsa.d.ts +1 -0
  79. package/dist/embedded/mldsa.js +3 -0
  80. package/dist/embedded/mlkem.d.ts +1 -0
  81. package/dist/embedded/mlkem.js +3 -0
  82. package/dist/embedded/p256.d.ts +1 -0
  83. package/dist/embedded/p256.js +3 -0
  84. package/dist/embedded/serpent-pool-worker.d.ts +1 -1
  85. package/dist/embedded/serpent-pool-worker.js +2 -2
  86. package/dist/embedded/serpent.d.ts +1 -1
  87. package/dist/embedded/serpent.js +2 -2
  88. package/dist/embedded/sha2.d.ts +1 -1
  89. package/dist/embedded/sha2.js +2 -2
  90. package/dist/embedded/sha3.d.ts +1 -1
  91. package/dist/embedded/sha3.js +2 -2
  92. package/dist/embedded/slhdsa.d.ts +1 -0
  93. package/dist/embedded/slhdsa.js +3 -0
  94. package/dist/errors.d.ts +92 -1
  95. package/dist/errors.js +111 -1
  96. package/dist/fortuna.d.ts +5 -5
  97. package/dist/fortuna.js +37 -64
  98. package/dist/index.d.ts +38 -9
  99. package/dist/index.js +63 -19
  100. package/dist/init.d.ts +1 -1
  101. package/dist/init.js +11 -25
  102. package/dist/keccak/embedded.js +1 -1
  103. package/dist/keccak/index.d.ts +2 -0
  104. package/dist/keccak/index.js +4 -2
  105. package/dist/loader.d.ts +1 -24
  106. package/dist/loader.js +13 -16
  107. package/dist/merkle/blake3-tree.d.ts +35 -0
  108. package/dist/merkle/blake3-tree.js +187 -0
  109. package/dist/merkle/checkpoint.d.ts +58 -0
  110. package/dist/merkle/checkpoint.js +217 -0
  111. package/dist/merkle/index.d.ts +19 -0
  112. package/dist/merkle/index.js +37 -0
  113. package/dist/merkle/merkle-log.d.ts +130 -0
  114. package/dist/merkle/merkle-log.js +207 -0
  115. package/dist/merkle/merkle-verifier.d.ts +126 -0
  116. package/dist/merkle/merkle-verifier.js +296 -0
  117. package/dist/merkle/proof.d.ts +70 -0
  118. package/dist/merkle/proof.js +300 -0
  119. package/dist/merkle/sha256-tree.d.ts +33 -0
  120. package/dist/merkle/sha256-tree.js +145 -0
  121. package/dist/merkle/signed-log.d.ts +156 -0
  122. package/dist/merkle/signed-log.js +356 -0
  123. package/dist/merkle/signed-note.d.ts +309 -0
  124. package/dist/merkle/signed-note.js +648 -0
  125. package/dist/merkle/sth.d.ts +31 -0
  126. package/dist/merkle/sth.js +31 -0
  127. package/dist/merkle/storage.d.ts +40 -0
  128. package/dist/merkle/storage.js +71 -0
  129. package/dist/merkle/tree.d.ts +68 -0
  130. package/dist/merkle/tree.js +94 -0
  131. package/dist/mldsa/embedded.d.ts +1 -0
  132. package/dist/{kyber → mldsa}/embedded.js +5 -5
  133. package/dist/mldsa/expand.d.ts +53 -0
  134. package/dist/mldsa/expand.js +188 -0
  135. package/dist/mldsa/format.d.ts +16 -0
  136. package/dist/mldsa/format.js +68 -0
  137. package/dist/mldsa/hashvariant.d.ts +32 -0
  138. package/dist/mldsa/hashvariant.js +248 -0
  139. package/dist/mldsa/index.d.ts +142 -0
  140. package/dist/mldsa/index.js +463 -0
  141. package/dist/mldsa/keygen.d.ts +16 -0
  142. package/dist/mldsa/keygen.js +232 -0
  143. package/dist/mldsa/params.d.ts +21 -0
  144. package/dist/mldsa/params.js +55 -0
  145. package/dist/mldsa/sha3-helpers.d.ts +30 -0
  146. package/dist/mldsa/sha3-helpers.js +124 -0
  147. package/dist/mldsa/sign.d.ts +36 -0
  148. package/dist/mldsa/sign.js +380 -0
  149. package/dist/mldsa/types.d.ts +91 -0
  150. package/dist/mldsa/types.js +25 -0
  151. package/dist/mldsa/validate.d.ts +55 -0
  152. package/dist/mldsa/validate.js +125 -0
  153. package/dist/mldsa/verify.d.ts +29 -0
  154. package/dist/mldsa/verify.js +269 -0
  155. package/dist/mldsa.wasm +0 -0
  156. package/dist/mlkem/embedded.d.ts +1 -0
  157. package/dist/mlkem/embedded.js +27 -0
  158. package/dist/mlkem/indcpa.d.ts +49 -0
  159. package/dist/{kyber → mlkem}/indcpa.js +44 -44
  160. package/dist/mlkem/index.d.ts +37 -0
  161. package/dist/{kyber → mlkem}/index.js +24 -34
  162. package/dist/mlkem/kem.d.ts +21 -0
  163. package/dist/{kyber → mlkem}/kem.js +44 -64
  164. package/dist/{kyber → mlkem}/params.d.ts +4 -4
  165. package/dist/{kyber → mlkem}/params.js +2 -2
  166. package/dist/mlkem/suite.d.ts +12 -0
  167. package/dist/{kyber → mlkem}/suite.js +17 -12
  168. package/dist/{kyber → mlkem}/types.d.ts +3 -3
  169. package/dist/{kyber → mlkem}/types.js +1 -1
  170. package/dist/{kyber → mlkem}/validate.d.ts +7 -7
  171. package/dist/{kyber → mlkem}/validate.js +7 -7
  172. package/dist/{kyber.wasm → mlkem.wasm} +0 -0
  173. package/dist/p256.wasm +0 -0
  174. package/dist/ratchet/index.d.ts +2 -0
  175. package/dist/ratchet/index.js +1 -0
  176. package/dist/ratchet/kdf-chain.js +3 -3
  177. package/dist/ratchet/ratchet-keypair.js +2 -2
  178. package/dist/ratchet/root-kdf.js +7 -7
  179. package/dist/ratchet/skipped-key-store.js +4 -4
  180. package/dist/ratchet/types.d.ts +1 -1
  181. package/dist/serpent/cipher-suite.js +20 -17
  182. package/dist/serpent/generator.d.ts +1 -1
  183. package/dist/serpent/generator.js +2 -2
  184. package/dist/serpent/index.d.ts +8 -7
  185. package/dist/serpent/index.js +18 -27
  186. package/dist/serpent/pool-worker.js +7 -5
  187. package/dist/serpent/serpent-cbc.d.ts +4 -4
  188. package/dist/serpent/serpent-cbc.js +11 -8
  189. package/dist/serpent/shared-ops.d.ts +3 -23
  190. package/dist/serpent/shared-ops.js +50 -85
  191. package/dist/serpent.wasm +0 -0
  192. package/dist/sha2/hkdf.js +5 -5
  193. package/dist/sha2/index.d.ts +21 -1
  194. package/dist/sha2/index.js +65 -10
  195. package/dist/sha2/types.d.ts +41 -2
  196. package/dist/sha2.wasm +0 -0
  197. package/dist/sha3/index.d.ts +72 -3
  198. package/dist/sha3/index.js +240 -14
  199. package/dist/sha3/kmac.d.ts +121 -0
  200. package/dist/sha3/kmac.js +800 -0
  201. package/dist/sha3.wasm +0 -0
  202. package/dist/shared/pkcs7.d.ts +22 -0
  203. package/dist/shared/pkcs7.js +84 -0
  204. package/dist/sign/ctx.d.ts +41 -0
  205. package/dist/sign/ctx.js +102 -0
  206. package/dist/sign/envelope.d.ts +45 -0
  207. package/dist/sign/envelope.js +152 -0
  208. package/dist/sign/hasher.d.ts +9 -0
  209. package/dist/sign/hasher.js +132 -0
  210. package/dist/sign/index.d.ts +11 -0
  211. package/dist/sign/index.js +34 -0
  212. package/dist/sign/sign-stream.d.ts +25 -0
  213. package/dist/sign/sign-stream.js +112 -0
  214. package/dist/sign/suites/ecdsa-p256.d.ts +2 -0
  215. package/dist/sign/suites/ecdsa-p256.js +120 -0
  216. package/dist/sign/suites/ed25519.d.ts +3 -0
  217. package/dist/sign/suites/ed25519.js +165 -0
  218. package/dist/sign/suites/hybrid-classical.d.ts +23 -0
  219. package/dist/sign/suites/hybrid-classical.js +526 -0
  220. package/dist/sign/suites/hybrid-pq.d.ts +4 -0
  221. package/dist/sign/suites/hybrid-pq.js +234 -0
  222. package/dist/sign/suites/mldsa.d.ts +7 -0
  223. package/dist/sign/suites/mldsa.js +161 -0
  224. package/dist/sign/suites/slhdsa.d.ts +7 -0
  225. package/dist/sign/suites/slhdsa.js +176 -0
  226. package/dist/sign/types.d.ts +106 -0
  227. package/dist/sign/types.js +28 -0
  228. package/dist/sign/verify-stream.d.ts +30 -0
  229. package/dist/sign/verify-stream.js +227 -0
  230. package/dist/slhdsa/embedded.d.ts +1 -0
  231. package/dist/slhdsa/embedded.js +26 -0
  232. package/dist/slhdsa/index.d.ts +149 -0
  233. package/dist/slhdsa/index.js +493 -0
  234. package/dist/slhdsa/params.d.ts +26 -0
  235. package/dist/slhdsa/params.js +70 -0
  236. package/dist/slhdsa/prehash.d.ts +68 -0
  237. package/dist/slhdsa/prehash.js +307 -0
  238. package/dist/slhdsa/sign.d.ts +39 -0
  239. package/dist/slhdsa/sign.js +116 -0
  240. package/dist/slhdsa/types.d.ts +129 -0
  241. package/dist/slhdsa/types.js +27 -0
  242. package/dist/slhdsa/validate.d.ts +60 -0
  243. package/dist/slhdsa/validate.js +127 -0
  244. package/dist/slhdsa/verify.d.ts +32 -0
  245. package/dist/slhdsa/verify.js +107 -0
  246. package/dist/slhdsa.wasm +0 -0
  247. package/dist/stream/header.js +3 -3
  248. package/dist/stream/index.d.ts +1 -0
  249. package/dist/stream/index.js +1 -0
  250. package/dist/stream/open-stream.js +31 -10
  251. package/dist/stream/seal-stream-pool.d.ts +1 -0
  252. package/dist/stream/seal-stream-pool.js +63 -26
  253. package/dist/stream/seal-stream.d.ts +1 -1
  254. package/dist/stream/seal-stream.js +20 -9
  255. package/dist/stream/seal.js +6 -6
  256. package/dist/stream/types.d.ts +3 -1
  257. package/dist/stream/types.js +1 -1
  258. package/dist/types.d.ts +1 -1
  259. package/dist/types.js +1 -1
  260. package/dist/utils.d.ts +3 -3
  261. package/dist/utils.js +46 -54
  262. package/dist/wasm-source.d.ts +7 -7
  263. package/dist/wasm-source.js +1 -1
  264. package/dist/x25519/embedded.d.ts +1 -0
  265. package/dist/x25519/embedded.js +31 -0
  266. package/dist/x25519/index.d.ts +43 -0
  267. package/dist/x25519/index.js +159 -0
  268. package/dist/x25519/types.d.ts +25 -0
  269. package/dist/x25519/types.js +27 -0
  270. package/dist/x25519/validate.d.ts +2 -0
  271. package/dist/x25519/validate.js +39 -0
  272. package/package.json +70 -26
  273. package/SECURITY.md +0 -163
  274. package/dist/ct-wasm.d.ts +0 -1
  275. package/dist/ct-wasm.js +0 -3
  276. package/dist/docs/aead.md +0 -363
  277. package/dist/docs/architecture.md +0 -1011
  278. package/dist/docs/argon2id.md +0 -305
  279. package/dist/docs/chacha20.md +0 -781
  280. package/dist/docs/exports.md +0 -277
  281. package/dist/docs/fortuna.md +0 -530
  282. package/dist/docs/init.md +0 -301
  283. package/dist/docs/loader.md +0 -256
  284. package/dist/docs/serpent.md +0 -617
  285. package/dist/docs/sha2.md +0 -671
  286. package/dist/docs/sha3.md +0 -612
  287. package/dist/docs/types.md +0 -416
  288. package/dist/docs/utils.md +0 -457
  289. package/dist/embedded/kyber.d.ts +0 -1
  290. package/dist/embedded/kyber.js +0 -3
  291. package/dist/kyber/embedded.d.ts +0 -1
  292. package/dist/kyber/indcpa.d.ts +0 -49
  293. package/dist/kyber/index.d.ts +0 -38
  294. package/dist/kyber/kem.d.ts +0 -21
  295. package/dist/kyber/suite.d.ts +0 -12
  296. /package/dist/{ct.wasm → cte.wasm} +0 -0
@@ -1,457 +0,0 @@
1
- <img src="https://github.com/xero/leviathan-crypto/raw/main/docs/logo.svg" alt="logo" width="120" align="left" margin="10">
2
-
3
- ### Utilities
4
-
5
- Pure TypeScript utilities that ship alongside the WASM-backed primitives. No `init()` call required; all functions work immediately on import.
6
-
7
- > ### Table of Contents
8
- > - [Security Notes](#security-notes)
9
- > - [API Reference](#api-reference)
10
- > - [Usage Examples](#usage-examples)
11
- > - [Error Conditions](#error-conditions)
12
-
13
- ---
14
-
15
- The module covers encoding (hex, UTF-8, and base64 conversions between strings
16
- and `Uint8Array`), security (constant-time comparison and secure memory
17
- wiping), byte manipulation (XOR and concatenation), and random byte generation.
18
-
19
- ## Security Notes
20
-
21
- **`constantTimeEqual`** runs inside a WASM SIMD module that removes the JS JIT
22
- compiler from the timing picture. Use this function whenever you compare MACs,
23
- hashes, authentication tags, or any secret-derived values. Never use `===`,
24
- `Buffer.equals`, or a manual loop-with-break for security comparisons. Those
25
- leak timing information that attackers can exploit to recover secrets. Inputs
26
- are limited to [`CT_MAX_BYTES`](#ct_max_bytes) (32768 bytes) per side.
27
-
28
- The length check in `constantTimeEqual` is not constant-time, because array
29
- length is non-secret in all standard protocols. If your use case treats length
30
- as secret, pad to equal length before comparing.
31
-
32
- **`wipe`** zeroes a typed array in-place. Call it on keys, plaintext buffers,
33
- and any other sensitive data as soon as you are done with them. JavaScript's
34
- garbage collector does not guarantee timely or complete erasure of memory.
35
-
36
- **`randomBytes`** delegates to `crypto.getRandomValues` (Web Crypto API), which
37
- is cryptographically secure in all modern browsers and Node.js 19+. It does not
38
- fall back to `Math.random` or any insecure source.
39
-
40
- The encoding functions (`hexToBytes`, `bytesToHex`, `utf8ToBytes`,
41
- `bytesToUtf8`, `base64ToBytes`, `bytesToBase64`) perform no security-sensitive
42
- operations.
43
-
44
- ---
45
-
46
- ## API Reference
47
-
48
- ### constantTimeEqual
49
-
50
- ```typescript
51
- constantTimeEqual(a: Uint8Array, b: Uint8Array): boolean
52
- ```
53
-
54
- Returns `true` if `a` and `b` contain identical bytes. Returns `false`
55
- immediately if the arrays differ in length (length is non-secret in all
56
- standard protocols).
57
-
58
- The comparison runs inside a WASM SIMD module, removing the JS JIT compiler
59
- from the timing picture. Speculative optimisation and branch prediction inside
60
- the engine cannot short-circuit the loop. This function requires WebAssembly
61
- SIMD; on runtimes without SIMD support it throws `Error: leviathan-crypto:
62
- constantTimeEqual requires WebAssembly SIMD — this runtime does not support it`
63
- at first call. SIMD has been a baseline feature of all major browsers and
64
- Node.js 16.4+ since 2021, and the library's symmetric and post-quantum
65
- primitives require SIMD already; this function tightens that posture
66
- consistently.
67
-
68
- The WASM module ORs the two 64-bit lanes of the SIMD accumulator into a scalar,
69
- then folds it to 0/1 via `~((diff | -diff) >> 63) & 1`. The only remaining
70
- observable control flow is the outer length check, which operates on non-secret
71
- input.
72
-
73
- **Zero-copy design.** The WASM module has no internal staging buffers. The
74
- wrapper writes `a` into WASM linear memory at offset 0 and `b` immediately
75
- after at offset `a.length`, then passes those two offsets directly to the
76
- `compare` function. No data is duplicated inside the WASM binary; the
77
- comparison reads in-place from the caller-owned positions. This eliminates an
78
- entire class of residual-data risk: there is no intermediate copy that outlives
79
- the operation.
80
-
81
- **Guaranteed memory zeroing.** After every comparison, the wrapper clears both
82
- input regions via `mem.fill(0, 0, a.length * 2)` inside a `finally` block. The
83
- wipe runs whether the comparison succeeds, throws, or is interrupted. Sensitive
84
- material written into WASM linear memory does not persist past the end of the
85
- call.
86
-
87
- WASM SIMD JITs do not guarantee cycle-level constant time; the branch-free tail
88
- is best-effort hardening against branch-prediction side channels. For
89
- defence-in-depth against timing attacks on tag comparisons, pair this primitive
90
- with an authenticated construction (`SerpentCipher`, `XChaCha20Cipher`) that
91
- terminates on mismatch with a generic error message.
92
-
93
- Maximum input size is [`CT_MAX_BYTES`](#ct_max_bytes) (32768 bytes) per side.
94
- Throws `RangeError` if either array exceeds this limit.
95
-
96
- See [asm_ct.md](./asm_ct.md) for the full WASM module reference, including the
97
- SIMD algorithm, reduction technique, instantiation model, and memory layout.
98
-
99
- Use this function when working with lower-level unauthenticated primitives or
100
- building custom authenticated protocols on top of the hashing and KDF APIs.
101
- Common cases:
102
-
103
- - **Encrypt-then-MAC with `SerpentCbc` or `SerpentCtr`.** If you use the
104
- `dangerUnauthenticated` primitive directly and compute your own HMAC-SHA256
105
- tag, compare that tag with `constantTimeEqual`. See the [example
106
- below](#encrypt-then-mac-with-serpentcbc).
107
- - **Argon2id key verification.** When re-deriving an Argon2id hash to verify a
108
- passphrase, the final comparison must be constant-time. See
109
- [argon2id.md](./argon2id.md#password-hashing-and-verification) for the full
110
- example.
111
- - **Custom HMAC protocols.** Any protocol where you derive a MAC with
112
- `HMAC_SHA256` or `HMAC_SHA512` and compare it against a received value. See
113
- [examples.md](./examples.md#hmac-sha256-message-authentication) for a
114
- complete example.
115
-
116
- ---
117
-
118
- ### CT_MAX_BYTES
119
-
120
- ```typescript
121
- const CT_MAX_BYTES: 32768
122
- ```
123
-
124
- Maximum input size accepted by [`constantTimeEqual`](#constanttimeequal) per
125
- side, in bytes. Reflects the physical layout of the WASM comparison module: one
126
- 64 KiB page of linear memory split equally between the two input buffers (32
127
- KiB each).
128
-
129
- In practice the largest comparison performed anywhere in this library is a
130
- 32-byte HMAC-SHA-256 tag. This limit only matters for custom protocols that
131
- compare unusually large values. Use this constant to guard your own inputs
132
- rather than hardcoding the magic number:
133
-
134
- ```typescript
135
- import { constantTimeEqual, CT_MAX_BYTES } from 'leviathan-crypto'
136
-
137
- if (a.length > CT_MAX_BYTES || b.length > CT_MAX_BYTES) {
138
- throw new RangeError(`comparison input exceeds CT_MAX_BYTES (${CT_MAX_BYTES})`)
139
- }
140
- const match = constantTimeEqual(a, b)
141
- ```
142
-
143
- ---
144
-
145
- ### hexToBytes
146
-
147
- ```typescript
148
- hexToBytes(hex: string): Uint8Array
149
- ```
150
-
151
- Converts a hex string to a `Uint8Array`. Accepts lowercase or uppercase
152
- characters. An optional `0x` or `0X` prefix is stripped automatically. Throws
153
- `RangeError` on odd-length or non-hex input.
154
-
155
- ---
156
-
157
- ### bytesToHex
158
-
159
- ```typescript
160
- bytesToHex(bytes: Uint8Array): string
161
- ```
162
-
163
- Converts a `Uint8Array` to a lowercase hex string (no prefix).
164
-
165
- ---
166
-
167
- ### utf8ToBytes
168
-
169
- ```typescript
170
- utf8ToBytes(str: string): Uint8Array
171
- ```
172
-
173
- Encodes a JavaScript string as UTF-8 bytes using the platform `TextEncoder`.
174
-
175
- ---
176
-
177
- ### bytesToUtf8
178
-
179
- ```typescript
180
- bytesToUtf8(bytes: Uint8Array): string
181
- ```
182
-
183
- Decodes UTF-8 bytes to a JavaScript string using the platform `TextDecoder`.
184
-
185
- ---
186
-
187
- ### base64ToBytes
188
-
189
- ```typescript
190
- base64ToBytes(b64: string): Uint8Array
191
- ```
192
-
193
- Decodes a base64 or base64url string to a `Uint8Array`. Handles padded,
194
- unpadded, and legacy `%3d` padding. Unpadded base64url input is accepted (RFC
195
- 4648 §5). Throws `RangeError` if the input is not valid base64 (illegal
196
- characters or `rem=1` length).
197
-
198
- ---
199
-
200
- ### bytesToBase64
201
-
202
- ```typescript
203
- bytesToBase64(bytes: Uint8Array, url?: boolean): string
204
- ```
205
-
206
- Encodes a `Uint8Array` to a base64 string. Pass `url = true` for base64url (RFC
207
- 4648 §5), which uses `-` and `_` instead of `+` and `/` with no padding
208
- characters. Defaults to standard base64.
209
-
210
- ---
211
-
212
- ### wipe
213
-
214
- ```typescript
215
- wipe(data: Uint8Array | Uint16Array | Uint32Array): void
216
- ```
217
-
218
- Zeroes a typed array in-place by calling `fill(0)`. Use this to clear keys,
219
- plaintext, or any sensitive material when you are done with it.
220
-
221
- ---
222
-
223
- ### xor
224
-
225
- ```typescript
226
- xor(a: Uint8Array, b: Uint8Array): Uint8Array
227
- ```
228
-
229
- Returns a new `Uint8Array` where each byte is `a[i] ^ b[i]`. Both arrays must
230
- have the same length. Throws `RangeError` if they differ.
231
-
232
- ---
233
-
234
- ### concat
235
-
236
- ```typescript
237
- concat(...arrays: Uint8Array[]): Uint8Array
238
- ```
239
-
240
- Concatenates one or more `Uint8Array`s into a new array.
241
-
242
- ---
243
-
244
- ### randomBytes
245
-
246
- ```typescript
247
- randomBytes(n: number): Uint8Array
248
- ```
249
-
250
- Returns `n` cryptographically secure random bytes via the Web Crypto API
251
- (`crypto.getRandomValues`).
252
-
253
- ---
254
-
255
- ### hasSIMD
256
-
257
- ```typescript
258
- hasSIMD(): boolean
259
- ```
260
-
261
- Returns `true` if the current runtime supports WebAssembly SIMD (the `v128`
262
- type and associated operations). The result is computed once on first call by
263
- validating a minimal v128 WASM module, then cached for subsequent calls.
264
-
265
- A public utility for consumers who want to feature-detect before calling
266
- `init()`. The library requires SIMD for `serpent`, `chacha20`, and
267
- `constantTimeEqual`; calls into those modules throw a branded error on
268
- non-SIMD runtimes. `sha2` and `sha3` do not require SIMD.
269
-
270
- Supported in all modern browsers and Node.js 16+.
271
-
272
- ---
273
-
274
- ## Usage Examples
275
-
276
- ### Converting between formats
277
-
278
- ```typescript
279
- import { hexToBytes, bytesToHex, utf8ToBytes, bytesToUtf8 } from 'leviathan-crypto'
280
-
281
- // Hex round-trip
282
- const bytes = hexToBytes('deadbeef')
283
- console.log(bytesToHex(bytes)) // "deadbeef"
284
-
285
- // 0x prefix is accepted
286
- const prefixed = hexToBytes('0xCAFE')
287
- console.log(bytesToHex(prefixed)) // "cafe"
288
-
289
- // UTF-8 round-trip
290
- const encoded = utf8ToBytes('hello world')
291
- console.log(bytesToUtf8(encoded)) // "hello world"
292
- ```
293
-
294
- ---
295
-
296
- ### Base64 encoding and decoding
297
-
298
- ```typescript
299
- import { bytesToBase64, base64ToBytes, utf8ToBytes, bytesToUtf8 } from 'leviathan-crypto'
300
-
301
- const data = utf8ToBytes('leviathan-crypto')
302
- const b64 = bytesToBase64(data)
303
- console.log(b64) // "bGV2aWF0aGFuLWNyeXB0bw=="
304
-
305
- // base64url variant (safe for URLs and filenames, no padding)
306
- const b64url = bytesToBase64(data, true)
307
- console.log(b64url) // "bGV2aWF0aGFuLWNyeXB0bw"
308
-
309
- // Decoding (accepts both standard and url variants)
310
- const decoded = base64ToBytes(b64)
311
- console.log(bytesToUtf8(decoded)) // "leviathan-crypto"
312
- ```
313
-
314
- ---
315
-
316
- ### Encrypt-then-MAC with SerpentCbc
317
-
318
- If you use `SerpentCbc` or `SerpentCtr` directly with `{ dangerUnauthenticated:
319
- true }`, you are responsible for authentication. The correct pattern is
320
- Encrypt-then-MAC: encrypt first, then compute HMAC-SHA256 over the ciphertext,
321
- and use `constantTimeEqual` to verify on decrypt.
322
-
323
- ```typescript
324
- import {
325
- init, SerpentCbc, HMAC_SHA256,
326
- constantTimeEqual, randomBytes, wipe, concat,
327
- } from 'leviathan-crypto'
328
- import { serpentWasm } from 'leviathan-crypto/serpent/embedded'
329
- import { sha2Wasm } from 'leviathan-crypto/sha2/embedded'
330
-
331
- await init({ serpent: serpentWasm, sha2: sha2Wasm })
332
-
333
- const encKey = randomBytes(32)
334
- const macKey = randomBytes(32)
335
- const iv = randomBytes(16)
336
-
337
- // ── Encrypt ──────────────────────────────────────────────────────────────────
338
-
339
- const cbc = new SerpentCbc({ dangerUnauthenticated: true })
340
- const ct = cbc.encrypt(encKey, iv, plaintext)
341
- cbc.dispose()
342
-
343
- // MAC covers iv || ct so the IV is authenticated too
344
- const hmac = new HMAC_SHA256()
345
- const tag = hmac.hash(macKey, concat(iv, ct))
346
- hmac.dispose()
347
-
348
- const envelope = concat(iv, ct, tag) // store or transmit this
349
-
350
- // ── Decrypt ──────────────────────────────────────────────────────────────────
351
-
352
- const receivedIv = envelope.subarray(0, 16)
353
- const receivedCt = envelope.subarray(16, envelope.length - 32)
354
- const receivedTag = envelope.subarray(envelope.length - 32)
355
-
356
- const hmac2 = new HMAC_SHA256()
357
- const expectedTag = hmac2.hash(macKey, concat(receivedIv, receivedCt))
358
- hmac2.dispose()
359
-
360
- // Always verify before decrypting — never decrypt unauthenticated ciphertext
361
- if (!constantTimeEqual(expectedTag, receivedTag)) {
362
- wipe(expectedTag)
363
- throw new Error('Authentication failed')
364
- }
365
-
366
- const cbc2 = new SerpentCbc({ dangerUnauthenticated: true })
367
- const pt = cbc2.decrypt(encKey, receivedIv, receivedCt)
368
- cbc2.dispose()
369
- wipe(expectedTag)
370
- ```
371
-
372
- > [!NOTE]
373
- > `Seal` with `SerpentCipher` does all of this for you; key derivation, IV
374
- > handling, Encrypt-then-MAC, and constant-time verification, with no manual
375
- > steps. The pattern above is only relevant if you need direct access to the
376
- > raw `SerpentCbc` primitive.
377
-
378
- ---
379
-
380
- ### Generating random keys and nonces
381
-
382
- ```typescript
383
- import { randomBytes } from 'leviathan-crypto'
384
-
385
- const key = randomBytes(32) // 256-bit symmetric key
386
- const nonce = randomBytes(24) // 192-bit nonce for XChaCha20
387
- const iv = randomBytes(16) // 128-bit IV for Serpent-CBC
388
- ```
389
-
390
- ---
391
-
392
- ### Wiping sensitive data after use
393
-
394
- ```typescript
395
- import { randomBytes, wipe } from 'leviathan-crypto'
396
-
397
- const key = randomBytes(32)
398
-
399
- // ... use the key for encryption / decryption ...
400
-
401
- // When done, zero the key material so it does not linger in memory
402
- wipe(key)
403
- // key is now all zeroes
404
- ```
405
-
406
- ---
407
-
408
- ### XOR and concatenation
409
-
410
- ```typescript
411
- import { xor, concat, randomBytes } from 'leviathan-crypto'
412
-
413
- const a = randomBytes(16)
414
- const b = randomBytes(16)
415
-
416
- // XOR two equal-length arrays
417
- const xored = xor(a, b)
418
-
419
- // Concatenate two arrays
420
- const combined = concat(a, b)
421
- console.log(combined.length) // 32
422
- ```
423
-
424
- ---
425
-
426
- ## Error Conditions
427
-
428
- | Function | Condition | Behavior |
429
- |---|---|---|
430
- | `hexToBytes` | Odd-length string | Throws `RangeError` |
431
- | `hexToBytes` | Invalid hex characters | Throws `RangeError` |
432
- | `base64ToBytes` | Invalid length or characters | Throws `RangeError` |
433
- | `constantTimeEqual` | Arrays differ in length | Returns `false` immediately |
434
- | `constantTimeEqual` | Either array exceeds `CT_MAX_BYTES` | Throws `RangeError` |
435
- | `xor` | Arrays differ in length | Throws `RangeError` |
436
- | `randomBytes` | `crypto` not available | Throws (runtime-dependent) |
437
- | `hasSIMD` | `WebAssembly` not available | Returns `false` |
438
-
439
- ---
440
-
441
-
442
- ## Cross-References
443
-
444
- | Document | Description |
445
- | -------- | ----------- |
446
- | [index](./README.md) | Project Documentation index |
447
- | [architecture](./architecture.md) | architecture overview, module relationships, buffer layouts, and build pipeline |
448
- | [asm_ct](./asm_ct.md) | WASM module reference for `constantTimeEqual`: SIMD algorithm, zero-copy layout, instantiation model, and memory zeroing |
449
- | [serpent](./serpent.md) | Serpent modes consume keys from `randomBytes`; wrappers use `wipe` and `constantTimeEqual` |
450
- | [chacha20](./chacha20.md) | ChaCha20/Poly1305 classes use `randomBytes` for nonce generation |
451
- | [sha2](./sha2.md) | SHA-2 and HMAC classes; output often converted with `bytesToHex` |
452
- | [sha3](./sha3.md) | SHA-3 and SHAKE classes; output often converted with `bytesToHex` |
453
- | [argon2id](./argon2id.md) | passphrase-based encryption; uses `constantTimeEqual` for hash verification |
454
- | [examples](./examples.md) | full HMAC-SHA256 custom protocol example using `constantTimeEqual` |
455
- | [types](./types.md) | public interfaces whose implementations rely on these utilities |
456
- | [test-suite](./test-suite.md) | test suite structure and vector corpus |
457
-
@@ -1 +0,0 @@
1
- export declare const WASM_GZ_BASE64 = "H4sIAAAAAAAAA61aa4xkRRWu5312T/eiCI6Le+4FFcRZHrvLY0GYGnR1ccGNhGh8ZHZ29s44d3pmdrrvtK4oPRsl7g9CglGCr2Q1CAQFg4mPGJEdNSpq/INEY1D4ocYfaqLGyDx62j1V9/bc7unuxQQ2c6vOuedUncdXVaduQyZqc5QQQq/zjhDaOMIaDXKENsgR3sCeaDQMw7yijSMkZdKGFqENfuDtZNB/NpGCMcaktCjlnFLGseWMMc6FoJQKYTmukALZ9rPOAX86Sm5bOLZUiQ4eI2QIqWhuoXri8MR0VCO0NB0lhxcqJ+6oLCRjE7WIsDznjpmPRYQXcpwrCcuTVxGRJ68mMk/uIVae3EvsPLmPOHnyGuLmyWuJlyevI36evJ4UzkvJejTZNr7YxdT2D5U6mVeSYhfnKlLq4lxNyl2cPWRHF2cvOa+Ls4+8qotzDXl1F+dacn5xOkruiKJj756aqkUJeQ06dlttOiUvwIwdnk2pC5G6I6Nei9QtSUoNlzV1uDozF6Ws1+Fs71uYOlydSjk7/Y/MHI/GlqamomqNXIQAeH+UTNTS16+3UwbZZR+dqEVzSxUC3nySjNcmJyoTVRIUZ+brOTrk80lCLrYMl1yyY25hPplemIuqJ8ar0bGlyYi8YejoRLUaJUnGeKOcWsSB31Q4vlA5MZ4sHD2RRDVy6ZAmp6oLc4ZxWVEzJhfmjlejWo28uaTpY1Gbc3mhrTJXmyZv8dIBkRjxM2JhPiG7L9BU6tP4lpXkCjPLdJTML8zUInK1o+mJY8fIHtOtLR0le81oqQf7zAv0+BrzIvX/Wm1iPZpse3Xdjoyz5dj15YzX9mT/eRkr594NfsbEsW8cyqh0sre2GalZN7Xl0fqbX59RmdcTk5N5z0fPzwTmcEdYqo1PfjianCXKr0bx+NL8zNRCdY6MuZPJeD2qzkydILfYk8n45NxCnbzNmtP7BiMFyryfXf92QZT0BbmZ+JKoZdBPoZ+X6Oel+vkW/bxSP/fq53X6eaNvEbV8hujmJ6b5uRmqrInfGd5fTfOSaU5R3TxomkdN8z3T/Fw3p01zxjQv/sY0LxqRvxuRVeoPocmKqNN/phu+nva04w8RIIom6rQT76bEf4hS1gACfIsHdDdloQCGDa+EEuSKOjlVWVEnhyuzqry00ouHWiSkqEVC1ksivoESIECBV8KzRnTrMxC9+PENlPnfodRpKBowtUwDm4+CrdjtYlSRwOGj4Khl9k4xCiykisYBA7rlTGCBDU4cSD4KEpxbxSgQzVE0iUOB7lqVkALtmjbgIICAo8XQNeCzaD8FQ2hnHJzOKVDfBwl21rUVXQps7PoPMOo1VIsETLHA5aPgqmV6SBvu8VHw8obPdhnugAteHAg+CgI8Y7inzeEYYhuIFtAcCzkyDihwoCvozNNfphW1vLxcjtXwknFrBU22wEFbZ1d6OY0CHvrkaUcEuFnXVTQJXOx2mZ7ZhGlXX/ErAQUG5xrZ/wlnTkPcpWjAMaOMjwJTjsko5aNA09FzqAwEUjHmpVkOXKDATHAoCBR1NbSYiYdsEkFCv1mg/+781/wcbX6OBgWQKJ6T9cAFv/kDCoXmI7RZoEVC8n/Nb9Pmk1SVm9+gWvApFHx0sGDzHhr6zftp0xcEJHjgN+8zBFVOHFAdWAai3UXcMOzqcLDB4bCycHQHIh+GFN422N3wtvMRQPQ4YGuAS706NNRx/AFW+s9ZzGvIuxDfXLE0i+LQQLMdpGYzs6U2W6Zmb0HZznvhIkfEgQcWeCvg9Qe3Cw4IA24BogcEO1ySOZeSXOCzFToQiLMpEIu94p/D1VDeEyuF5X00RJgFJZBQglKz8PTthOT/EEUFQgjL/zWfoGoYcdUHdBqRYQEKr9B4zXsMWovgw1DzfjpwPVko9vLWT/Hlr5/BqyVNWjtV8E4x2ix8RXb+0wkRuEWdc1NgPbRfnlM9Ff8/JzNk+q/GU7LrGPQvQhZye2Hf36nf0pVeB6j/KUpFI0U2ApTq2CmqMYlriwNfUaUldXJ4MQ7w1GOKV+JQr1HFjIw+zlOZUO4nBDgIJRKQqtXii8qpV/cTqpmaFvX9hOFEcbpZRNuNwEnkCGEB13PSJBRoEsgRQvBBQ6mcpKpauxZN6SBSo4GbmUW9ii9ys/zDom4Dd6EDegmbLQnaEyYhVyzzOxBYiyjepqWmRZu2NC3btK1pq007mrbbtKvdYEkcevpNR4Sz4CmRqJPFWK3/R1TUzjo6gqaJcwlWMeYenM3DgJHO7nr91Sl4cPYkGKBugdVfnQGeke4AdQec/uo8lyb5/6YmzLstE7VcjNXm91lFva7enbUw70SX6DkSGuYd6FLtnWtZGZzrzkFCX8m+2e4UTbOdz2engGIJ+IrXqyCVnaTZtcyyoFm68tnuUqcJSter4Cgr0enpzG6XOE/AUQzHFfnl5j/FqbVtvZkVnq4FffqNEBJyVVrETUk5sRJ1s6BzGxHmsN75fiBgMPTWCKGBDRbuIQIbHnBsRCD14CKJkSSho3aZucuxku25eRJa2ey2cVHWqz1ErRSZeO2o93xvkIobVAK2svuMInK7l8Do95SSmRTtPZfBK0iEAFdWn1HsTIrXO1/m0/d+ynFT5llYOWYqEO1oOyaRHINjQqAICGBLii7OqpPFxc4B05JUjz2TH1ptGzRd4NmweHugnRsKXQSWVIM83tCUGIQ+fbZmusXMRNs3Etq+JalnvErAgMPZo6jzWOysBv1/4QVTm3uGmHqPJ6EAgvAVsa47zr4bnQ3tMgBXLDGICAXQOHSyDUHEoQWuljZFtaiEHhasnTddO3fXdvCSbYPERlZwB9p2197OmzU3OQluz5u4ALtXAYw36XzcvpDWBVvZ12cXw9OXjRCKZy92mCqbDlcXJtWQqecee+4xuYh5qaf9eCBmEDGKJaGsK74IApEbY3e2P3q+1LbN5EODpdLPuJCpZx76DE1N0t0Yp8z6OetEZh3rsM6qoHW2sY7H2B1g3QV6bztgwFa+UpeY5at8/wbKcgHFZb6FISw+NTKwk10Ec2O+fN37t+k+SxlrsLvaRXBXycvxriFwABCv1F2D412DA3+F7xq5JekRIOWLgZT3+RZ2L/Evp1SXkMBvTZO4zCuxxoabxOVL8yHZLusmRhR1ypflZX9q00IDuPIOiFGtI27VkBOoo48Soc6wShxYigQ8h0qpcRTaudM/X0J4yeNjJ4sfH/vuC78md4/BqbGW/clHAv39ZavUCfOnbm8NV2tsFUP5Y723hg34ecBUJ1IvRa3ogz9YMfRN3eGY8sLJykZXl3d41qSFhbISZNbTygHPRSwNtoKqa/VA6MN7e0wtHdMXMaZ2O6YauZbZemWfkPrJ42PLxY+PPf/NN909tuvUWKukI2rpPaVXRHsquFphK6Bn9+jBCp5W2Kox84HsqeBrhXalibfywQoFrbBVihahOFihqBXsnhVyT4UhsIErH+9cOsppDVqC0kC9sISQkODgfl7KICHBRQjoggkhgTRCgOOHLiyCXOWZalGCj+DxsCjaTyRIKCgbwaXBY2ma1vcT/CBVRNgVlItvcJkMYb1cNLBzNc3r+4nXG2a+/3tJh7avY9Jex7TfOs4Wi42FpAP2CBFoiT1CeOji9EF7GSGT4IOGtrmc2qb4Whax8urmC5reFfystMQKW6+Q3sJ+Vlymi0z0lUuLTK/r1bkWXRYAXwdAL7pC56IrpMDwRogMJHh41LMEWxZa6D92RWgrDx0uLQZFZGAZg60VOphc7Dqhq9xUZggZHqLGGyFuWEKoBGXwDfSQSfBBwx0mjuntYNmJla/98s1W4GVxtBANO/DO01PYy+JY7PGKZ9WwjamgfYcQWcqy7wt95NIafajHq7Q8L5ktkvUdIi3Qy12v+mD7UlMeUGC3pncrF2vc8sXAy/vyNX1oDr5OwfIl5xbpGGV3Wo0YBCF+QmmqERnrT6flPXnz3mF+RKLAylcoqr+GGlV1+iTL1GmqeQV+3sIXHWPog/5mHAdru4BnX/WA619I1PJwVtnvpmRW7Vqqmt9Lct8DF/0HKF5HjQEC7wP6ahZK4IcWcRSw4tDFS6MDLtaO2YLDz+GBhTz8USf95nT2EDo5fDBdQBo9mB9jsZ8Ob6PIYk7GzsmkP6LQWf9GE860GhH6HoNzpTeuWjXIn51jOEKLLj7+ibGbTz3iK8obCn9/0kt2a1Hrj2f4lUrv52DpUhFHW6zhlp1Hz4OMEXWv47OdlKgHHf8UE/g/WlBC/rbuNT+/+aq15+R9chf9BbmzNc8us75DfsRvX79p7QfyrezZNYc26I83viV/uHp3673NVf48O8LWVr9I97T+sPozcS/7XfO//N9rz8q/bL60KthLrTObU80nVuvrd5On5Nc3Hm79c/MmPktqa27r4EZ1c4XvXLu8eYb+dv1rTK4/uf4EvZy9i1+0Ps2HrBnyMH0Xe5Kc3/rD5t7NN1pLltfy+KfFXOu/G7+UDzfHxS9WP8Ue3PgQ/So9SI+1vt26ih8UH2BH2Zvl+to71papWv9o60fimbUHNp4nH1q/Z3V83Vpj68N8eO2xjS9s/JF+tvWrzT/xF/gP+aG1f8kPWiQs1xaWqpPRbRPHj8/MT9/5nkPl3VfMnjgaVXd/ZKI2t3tu4vj/ABUUZQbyIgAA";
@@ -1,3 +0,0 @@
1
- // Generated by scripts/embed-wasm.ts — do not edit
2
- // gzip-compressed WASM binary, base64-encoded. Decoded and decompressed by loadEmbedded().
3
- export const WASM_GZ_BASE64 = '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';
@@ -1 +0,0 @@
1
- export { WASM_GZ_BASE64 as kyberWasm } from '../embedded/kyber.js';
@@ -1,49 +0,0 @@
1
- import type { KyberExports, Sha3Exports } from './types.js';
2
- import type { KyberParams } from './params.js';
3
- /** SHA3-512(msg) → 64 bytes. Resets sha3 state. */
4
- export declare function sha3_512Hash(sx: Sha3Exports, msg: Uint8Array): Uint8Array;
5
- /** SHA3-256(msg) → 32 bytes. Resets sha3 state. */
6
- export declare function sha3_256Hash(sx: Sha3Exports, msg: Uint8Array): Uint8Array;
7
- /**
8
- * SHAKE256(msg, n) → n bytes. Resets sha3 state.
9
- * Used for J function (z || c) and PRF seeding in kem.ts.
10
- */
11
- export declare function shake256Hash(sx: Sha3Exports, msg: Uint8Array, n: number): Uint8Array;
12
- /**
13
- * K-PKE.KeyGen (FIPS 203 Algorithm 12) — deterministic.
14
- *
15
- * Slot map:
16
- * pvec0 — current row of  (overwritten per row)
17
- * pvec1 — ŝ (noise, persistent through dot products)
18
- * pvec2 — ê (noise)
19
- * pvec3 — t̂ = ·ŝ + ê (output)
20
- */
21
- export declare function indcpaKeypairDerand(kx: KyberExports, sx: Sha3Exports, params: KyberParams, d: Uint8Array): {
22
- ekCpa: Uint8Array;
23
- skCpa: Uint8Array;
24
- };
25
- /**
26
- * K-PKE.Encrypt (FIPS 203 Algorithm 13) — deterministic.
27
- *
28
- * Slot map:
29
- * pvec0 — current row of Â^T (transposed, overwritten per row)
30
- * pvec1 — r̂ = NTT(r)
31
- * pvec2 — e₁ (noise)
32
- * pvec3 — u = invNTT(Â^T · r̂) + e₁
33
- * pvec4 — t̂ (unpacked from ek)
34
- * poly1 — e₂ (noise)
35
- * poly2 — v = invNTT(t̂^T · r̂) + e₂ + msg
36
- * poly3 — message polynomial
37
- */
38
- export declare function indcpaEncrypt(kx: KyberExports, sx: Sha3Exports, params: KyberParams, ek: Uint8Array, m: Uint8Array, coins: Uint8Array): Uint8Array;
39
- /**
40
- * K-PKE.Decrypt (FIPS 203 Algorithm 14).
41
- *
42
- * Slot map:
43
- * pvec0 — û (decompressed from ct)
44
- * pvec1 — ŝ (from sk)
45
- * poly0 — v (decompressed from ct)
46
- * poly1 — w = invNTT(ŝ^T · NTT(û))
47
- * poly2 — m' = v - w
48
- */
49
- export declare function indcpaDecrypt(kx: KyberExports, params: KyberParams, skCpa: Uint8Array, ct: Uint8Array): Uint8Array;
@@ -1,38 +0,0 @@
1
- import { isInitialized } from '../init.js';
2
- import type { WasmSource } from '../wasm-source.js';
3
- import type { KyberExports, Sha3Exports, KyberKeyPair, KyberEncapsulation } from './types.js';
4
- import { KyberParams, MLKEM512, MLKEM768, MLKEM1024 } from './params.js';
5
- export declare function kyberInit(source: WasmSource): Promise<void>;
6
- export declare function _kyberReady(): boolean;
7
- export type { WasmSource };
8
- export type { KyberKeyPair, KyberEncapsulation, KyberExports, Sha3Exports };
9
- export { MLKEM512, MLKEM768, MLKEM1024 };
10
- export type { KyberParams };
11
- export { isInitialized };
12
- export { KyberSuite } from './suite.js';
13
- export declare class MlKemBase {
14
- readonly params: KyberParams;
15
- constructor(params: KyberParams);
16
- private get kx();
17
- private get sx();
18
- keygenDerand(d: Uint8Array, z: Uint8Array): KyberKeyPair;
19
- keygen(): KyberKeyPair;
20
- encapsulateDerand(ek: Uint8Array, m: Uint8Array): KyberEncapsulation;
21
- encapsulate(ek: Uint8Array): KyberEncapsulation;
22
- decapsulate(dk: Uint8Array, c: Uint8Array): Uint8Array;
23
- checkEncapsulationKey(ek: Uint8Array): boolean;
24
- checkDecapsulationKey(dk: Uint8Array): boolean;
25
- dispose(): void;
26
- }
27
- /** ML-KEM-512 — k=2, η₁=3, η₂=2, dᵤ=10, dᵥ=4. */
28
- export declare class MlKem512 extends MlKemBase {
29
- constructor();
30
- }
31
- /** ML-KEM-768 — k=3, η₁=2, η₂=2, dᵤ=10, dᵥ=4. */
32
- export declare class MlKem768 extends MlKemBase {
33
- constructor();
34
- }
35
- /** ML-KEM-1024 — k=4, η₁=2, η₂=2, dᵤ=11, dᵥ=5. */
36
- export declare class MlKem1024 extends MlKemBase {
37
- constructor();
38
- }
@@ -1,21 +0,0 @@
1
- import type { KyberExports, Sha3Exports, KyberKeyPair, KyberEncapsulation } from './types.js';
2
- import type { KyberParams } from './params.js';
3
- /**
4
- * ML-KEM.KeyGen_internal (FIPS 203 Algorithm 15).
5
- *
6
- * dk = skCpa || ek || H(ek) || z
7
- */
8
- export declare function kemKeypairDerand(kx: KyberExports, sx: Sha3Exports, params: KyberParams, d: Uint8Array, z: Uint8Array): KyberKeyPair;
9
- /**
10
- * ML-KEM.Encaps_internal (FIPS 203 Algorithm 16).
11
- *
12
- * (K, r) = G(m || H(ek)), c = K-PKE.Encrypt(ek, m, r)
13
- */
14
- export declare function kemEncapsulateDerand(kx: KyberExports, sx: Sha3Exports, params: KyberParams, ek: Uint8Array, m: Uint8Array): KyberEncapsulation;
15
- /**
16
- * ML-KEM.Decaps_internal (FIPS 203 Algorithm 17).
17
- *
18
- * Constant-time: uses ct_verify and ct_cmov from kyber WASM.
19
- * MUST NOT branch on secret data in JS — all comparison via WASM primitives.
20
- */
21
- export declare function kemDecapsulate(kx: KyberExports, sx: Sha3Exports, params: KyberParams, dk: Uint8Array, c: Uint8Array): Uint8Array;
@@ -1,12 +0,0 @@
1
- import type { CipherSuite } from '../stream/types.js';
2
- import type { KyberKeyPair, KyberEncapsulation } from './types.js';
3
- import type { KyberParams } from './params.js';
4
- export interface MlKemLike {
5
- readonly params: KyberParams;
6
- encapsulate(ek: Uint8Array): KyberEncapsulation;
7
- decapsulate(dk: Uint8Array, c: Uint8Array): Uint8Array;
8
- keygen(): KyberKeyPair;
9
- }
10
- export declare function KyberSuite(kem: MlKemLike, inner: CipherSuite): CipherSuite & {
11
- keygen(): KyberKeyPair;
12
- };
File without changes