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
@@ -22,23 +22,15 @@
22
22
  // src/ts/sha3/index.ts
23
23
  //
24
24
  // Public API classes for the SHA-3 WASM module.
25
- // Uses the init() module cache call sha3Init(source) before constructing.
26
- import { getInstance, initModule } from '../init.js';
25
+ // Uses the init() module cache, call sha3Init(source) before constructing.
26
+ import { getInstance, initModule, _acquireModule, _releaseModule, _assertNotOwned } from '../init.js';
27
27
  export async function sha3Init(source) {
28
28
  return initModule('sha3', source);
29
29
  }
30
+ export { isInitialized } from '../init.js';
30
31
  function getExports() {
31
32
  return getInstance('sha3').exports;
32
33
  }
33
- export function _sha3Ready() {
34
- try {
35
- getInstance('sha3');
36
- return true;
37
- }
38
- catch {
39
- return false;
40
- }
41
- }
42
34
  // Write msg into INPUT_OFFSET in chunks of 168 bytes (max rate)
43
35
  function absorb(x, msg) {
44
36
  const mem = new Uint8Array(x.memory.buffer);
@@ -58,6 +50,7 @@ export class SHA3_256 {
58
50
  this.x = getExports();
59
51
  }
60
52
  hash(msg) {
53
+ _assertNotOwned('sha3');
61
54
  this.x.sha3_256Init();
62
55
  absorb(this.x, msg);
63
56
  this.x.sha3_256Final();
@@ -65,6 +58,7 @@ export class SHA3_256 {
65
58
  return mem.slice(this.x.getOutOffset(), this.x.getOutOffset() + 32);
66
59
  }
67
60
  dispose() {
61
+ _assertNotOwned('sha3');
68
62
  this.x.wipeBuffers();
69
63
  }
70
64
  }
@@ -75,6 +69,7 @@ export class SHA3_512 {
75
69
  this.x = getExports();
76
70
  }
77
71
  hash(msg) {
72
+ _assertNotOwned('sha3');
78
73
  this.x.sha3_512Init();
79
74
  absorb(this.x, msg);
80
75
  this.x.sha3_512Final();
@@ -82,6 +77,7 @@ export class SHA3_512 {
82
77
  return mem.slice(this.x.getOutOffset(), this.x.getOutOffset() + 64);
83
78
  }
84
79
  dispose() {
80
+ _assertNotOwned('sha3');
85
81
  this.x.wipeBuffers();
86
82
  }
87
83
  }
@@ -92,6 +88,7 @@ export class SHA3_384 {
92
88
  this.x = getExports();
93
89
  }
94
90
  hash(msg) {
91
+ _assertNotOwned('sha3');
95
92
  this.x.sha3_384Init();
96
93
  absorb(this.x, msg);
97
94
  this.x.sha3_384Final();
@@ -99,6 +96,7 @@ export class SHA3_384 {
99
96
  return mem.slice(this.x.getOutOffset(), this.x.getOutOffset() + 48);
100
97
  }
101
98
  dispose() {
99
+ _assertNotOwned('sha3');
102
100
  this.x.wipeBuffers();
103
101
  }
104
102
  }
@@ -109,6 +107,7 @@ export class SHA3_224 {
109
107
  this.x = getExports();
110
108
  }
111
109
  hash(msg) {
110
+ _assertNotOwned('sha3');
112
111
  this.x.sha3_224Init();
113
112
  absorb(this.x, msg);
114
113
  this.x.sha3_224Final();
@@ -116,22 +115,40 @@ export class SHA3_224 {
116
115
  return mem.slice(this.x.getOutOffset(), this.x.getOutOffset() + 28);
117
116
  }
118
117
  dispose() {
118
+ _assertNotOwned('sha3');
119
119
  this.x.wipeBuffers();
120
120
  }
121
121
  }
122
122
  // ── SHAKE128 ────────────────────────────────────────────────────────────────
123
- /** SHAKE128 XOF — extendable output, multi-squeeze capable. */
123
+ /**
124
+ * SHAKE128 XOF, extendable output, multi-squeeze capable.
125
+ *
126
+ * Holds exclusive access to the `sha3` WASM module from construction until
127
+ * `dispose()`. Constructing a second SHAKE128/SHAKE256 or any other sha3
128
+ * user while this instance is live throws. Call `dispose()` when done.
129
+ */
124
130
  export class SHAKE128 {
125
131
  x;
126
132
  _rate = 168;
127
133
  _squeezing = false;
128
134
  _block = new Uint8Array(168);
129
135
  _blockPos = 168;
136
+ _tok;
130
137
  constructor() {
131
138
  this.x = getExports();
132
- this.x.shake128Init();
139
+ this._tok = _acquireModule('sha3');
140
+ try {
141
+ this.x.shake128Init();
142
+ }
143
+ catch (e) {
144
+ _releaseModule('sha3', this._tok);
145
+ this._tok = undefined;
146
+ throw e;
147
+ }
133
148
  }
134
149
  reset() {
150
+ if (this._tok === undefined)
151
+ throw new Error('SHAKE128: instance has been disposed');
135
152
  this.x.shake128Init();
136
153
  this._squeezing = false;
137
154
  this._block.fill(0);
@@ -139,12 +156,16 @@ export class SHAKE128 {
139
156
  return this;
140
157
  }
141
158
  absorb(msg) {
159
+ if (this._tok === undefined)
160
+ throw new Error('SHAKE128: instance has been disposed');
142
161
  if (this._squeezing)
143
- throw new Error('SHAKE128: cannot absorb after squeeze call reset() first');
162
+ throw new Error('SHAKE128: cannot absorb after squeeze, call reset() first');
144
163
  absorb(this.x, msg);
145
164
  return this;
146
165
  }
147
166
  squeeze(n) {
167
+ if (this._tok === undefined)
168
+ throw new Error('SHAKE128: instance has been disposed');
148
169
  if (n < 1)
149
170
  throw new RangeError(`squeeze length must be >= 1 (got ${n})`);
150
171
  if (!this._squeezing) {
@@ -170,6 +191,8 @@ export class SHAKE128 {
170
191
  return out;
171
192
  }
172
193
  hash(msg, outputLength) {
194
+ if (this._tok === undefined)
195
+ throw new Error('SHAKE128: instance has been disposed');
173
196
  if (outputLength < 1)
174
197
  throw new RangeError(`outputLength must be >= 1 (got ${outputLength})`);
175
198
  this.reset();
@@ -177,23 +200,48 @@ export class SHAKE128 {
177
200
  return this.squeeze(outputLength);
178
201
  }
179
202
  dispose() {
203
+ if (this._tok === undefined)
204
+ return;
180
205
  this._block.fill(0);
181
- this.x.wipeBuffers();
206
+ try {
207
+ this.x.wipeBuffers();
208
+ }
209
+ finally {
210
+ _releaseModule('sha3', this._tok);
211
+ this._tok = undefined;
212
+ }
182
213
  }
183
214
  }
184
215
  // ── SHAKE256 ────────────────────────────────────────────────────────────────
185
- /** SHAKE256 XOF — extendable output, multi-squeeze capable. */
216
+ /**
217
+ * SHAKE256 XOF, extendable output, multi-squeeze capable.
218
+ *
219
+ * Holds exclusive access to the `sha3` WASM module from construction until
220
+ * `dispose()`. Constructing a second SHAKE128/SHAKE256 or any other sha3
221
+ * user while this instance is live throws. Call `dispose()` when done.
222
+ */
186
223
  export class SHAKE256 {
187
224
  x;
188
225
  _rate = 136;
189
226
  _squeezing = false;
190
227
  _block = new Uint8Array(136);
191
228
  _blockPos = 136;
229
+ _tok;
192
230
  constructor() {
193
231
  this.x = getExports();
194
- this.x.shake256Init();
232
+ this._tok = _acquireModule('sha3');
233
+ try {
234
+ this.x.shake256Init();
235
+ }
236
+ catch (e) {
237
+ _releaseModule('sha3', this._tok);
238
+ this._tok = undefined;
239
+ throw e;
240
+ }
195
241
  }
196
242
  reset() {
243
+ if (this._tok === undefined)
244
+ throw new Error('SHAKE256: instance has been disposed');
197
245
  this.x.shake256Init();
198
246
  this._squeezing = false;
199
247
  this._block.fill(0);
@@ -201,12 +249,16 @@ export class SHAKE256 {
201
249
  return this;
202
250
  }
203
251
  absorb(msg) {
252
+ if (this._tok === undefined)
253
+ throw new Error('SHAKE256: instance has been disposed');
204
254
  if (this._squeezing)
205
- throw new Error('SHAKE256: cannot absorb after squeeze call reset() first');
255
+ throw new Error('SHAKE256: cannot absorb after squeeze, call reset() first');
206
256
  absorb(this.x, msg);
207
257
  return this;
208
258
  }
209
259
  squeeze(n) {
260
+ if (this._tok === undefined)
261
+ throw new Error('SHAKE256: instance has been disposed');
210
262
  if (n < 1)
211
263
  throw new RangeError(`squeeze length must be >= 1 (got ${n})`);
212
264
  if (!this._squeezing) {
@@ -232,6 +284,8 @@ export class SHAKE256 {
232
284
  return out;
233
285
  }
234
286
  hash(msg, outputLength) {
287
+ if (this._tok === undefined)
288
+ throw new Error('SHAKE256: instance has been disposed');
235
289
  if (outputLength < 1)
236
290
  throw new RangeError(`outputLength must be >= 1 (got ${outputLength})`);
237
291
  this.reset();
@@ -239,7 +293,251 @@ export class SHAKE256 {
239
293
  return this.squeeze(outputLength);
240
294
  }
241
295
  dispose() {
296
+ if (this._tok === undefined)
297
+ return;
242
298
  this._block.fill(0);
243
- this.x.wipeBuffers();
299
+ try {
300
+ this.x.wipeBuffers();
301
+ }
302
+ finally {
303
+ _releaseModule('sha3', this._tok);
304
+ this._tok = undefined;
305
+ }
306
+ }
307
+ }
308
+ // ── SHA3_256Stream ──────────────────────────────────────────────────────────
309
+ /**
310
+ * Incremental SHA3-256. Construct, `update()` chunks (any size), `finalize()`
311
+ * to get the 32-byte digest. Finalize disposes the instance.
312
+ *
313
+ * Holds exclusive access to the `sha3` WASM module from construction until
314
+ * `dispose()` or `finalize()`. Mirrors SHAKE128 lifecycle.
315
+ */
316
+ export class SHA3_256Stream {
317
+ x;
318
+ _tok;
319
+ constructor() {
320
+ this.x = getExports();
321
+ this._tok = _acquireModule('sha3');
322
+ try {
323
+ this.x.sha3_256Init();
324
+ }
325
+ catch (e) {
326
+ _releaseModule('sha3', this._tok);
327
+ this._tok = undefined;
328
+ throw e;
329
+ }
330
+ }
331
+ update(chunk) {
332
+ if (this._tok === undefined)
333
+ throw new Error('SHA3_256Stream: instance has been disposed');
334
+ absorb(this.x, chunk);
335
+ return this;
336
+ }
337
+ finalize() {
338
+ if (this._tok === undefined)
339
+ throw new Error('SHA3_256Stream: instance has been disposed');
340
+ this.x.sha3_256Final();
341
+ const mem = new Uint8Array(this.x.memory.buffer);
342
+ const off = this.x.getOutOffset();
343
+ const out = mem.slice(off, off + 32);
344
+ this.dispose();
345
+ return out;
346
+ }
347
+ dispose() {
348
+ if (this._tok === undefined)
349
+ return;
350
+ try {
351
+ this.x.wipeBuffers();
352
+ }
353
+ finally {
354
+ _releaseModule('sha3', this._tok);
355
+ this._tok = undefined;
356
+ }
357
+ }
358
+ }
359
+ // ── SHA3_512Stream ──────────────────────────────────────────────────────────
360
+ /**
361
+ * Incremental SHA3-512. Construct, `update()` chunks (any size), `finalize()`
362
+ * to get the 64-byte digest. Finalize disposes the instance.
363
+ *
364
+ * Holds exclusive access to the `sha3` WASM module from construction until
365
+ * `dispose()` or `finalize()`. Mirrors SHAKE128 lifecycle.
366
+ */
367
+ export class SHA3_512Stream {
368
+ x;
369
+ _tok;
370
+ constructor() {
371
+ this.x = getExports();
372
+ this._tok = _acquireModule('sha3');
373
+ try {
374
+ this.x.sha3_512Init();
375
+ }
376
+ catch (e) {
377
+ _releaseModule('sha3', this._tok);
378
+ this._tok = undefined;
379
+ throw e;
380
+ }
381
+ }
382
+ update(chunk) {
383
+ if (this._tok === undefined)
384
+ throw new Error('SHA3_512Stream: instance has been disposed');
385
+ absorb(this.x, chunk);
386
+ return this;
387
+ }
388
+ finalize() {
389
+ if (this._tok === undefined)
390
+ throw new Error('SHA3_512Stream: instance has been disposed');
391
+ this.x.sha3_512Final();
392
+ const mem = new Uint8Array(this.x.memory.buffer);
393
+ const off = this.x.getOutOffset();
394
+ const out = mem.slice(off, off + 64);
395
+ this.dispose();
396
+ return out;
397
+ }
398
+ dispose() {
399
+ if (this._tok === undefined)
400
+ return;
401
+ try {
402
+ this.x.wipeBuffers();
403
+ }
404
+ finally {
405
+ _releaseModule('sha3', this._tok);
406
+ this._tok = undefined;
407
+ }
408
+ }
409
+ }
410
+ // ── SHAKE128Stream ──────────────────────────────────────────────────────────
411
+ /**
412
+ * Single-shot streaming SHAKE128. `outputLen` is bound at construction;
413
+ * `update()` absorbs chunks of any size, `finalize()` pads and squeezes
414
+ * exactly `outputLen` bytes, then disposes the instance.
415
+ *
416
+ * Used by `createRunningHash` in the sign layer: each StreamableSignatureSuite
417
+ * with `prehashAlgorithm: 'shake-128'` declares its `prehashSize` and that
418
+ * value is passed in here at construction time. The multi-squeeze
419
+ * `SHAKE128` class above remains for the XOF surface; this class is the
420
+ * fixed-output cousin that matches the RunningHash contract.
421
+ *
422
+ * Holds exclusive access to the `sha3` WASM module from construction until
423
+ * `dispose()` or `finalize()`. Mirrors `SHA3_256Stream` lifecycle.
424
+ */
425
+ export class SHAKE128Stream {
426
+ x;
427
+ _rate = 168;
428
+ outputLen;
429
+ _tok;
430
+ constructor(outputLen) {
431
+ if (outputLen < 1)
432
+ throw new RangeError(`outputLen must be >= 1 (got ${outputLen})`);
433
+ this.outputLen = outputLen;
434
+ this.x = getExports();
435
+ this._tok = _acquireModule('sha3');
436
+ try {
437
+ this.x.shake128Init();
438
+ }
439
+ catch (e) {
440
+ _releaseModule('sha3', this._tok);
441
+ this._tok = undefined;
442
+ throw e;
443
+ }
444
+ }
445
+ update(chunk) {
446
+ if (this._tok === undefined)
447
+ throw new Error('SHAKE128Stream: instance has been disposed');
448
+ absorb(this.x, chunk);
449
+ return this;
450
+ }
451
+ finalize() {
452
+ if (this._tok === undefined)
453
+ throw new Error('SHAKE128Stream: instance has been disposed');
454
+ this.x.shakePad();
455
+ const out = new Uint8Array(this.outputLen);
456
+ const mem = new Uint8Array(this.x.memory.buffer);
457
+ const off = this.x.getOutOffset();
458
+ let pos = 0;
459
+ while (pos < this.outputLen) {
460
+ this.x.shakeSqueezeBlock();
461
+ const take = Math.min(this.outputLen - pos, this._rate);
462
+ out.set(mem.subarray(off, off + take), pos);
463
+ pos += take;
464
+ }
465
+ this.dispose();
466
+ return out;
467
+ }
468
+ dispose() {
469
+ if (this._tok === undefined)
470
+ return;
471
+ try {
472
+ this.x.wipeBuffers();
473
+ }
474
+ finally {
475
+ _releaseModule('sha3', this._tok);
476
+ this._tok = undefined;
477
+ }
478
+ }
479
+ }
480
+ // ── SHAKE256Stream ──────────────────────────────────────────────────────────
481
+ /**
482
+ * Single-shot streaming SHAKE256. `outputLen` is bound at construction;
483
+ * mirrors `SHAKE128Stream`. See that class for usage notes.
484
+ */
485
+ export class SHAKE256Stream {
486
+ x;
487
+ _rate = 136;
488
+ outputLen;
489
+ _tok;
490
+ constructor(outputLen) {
491
+ if (outputLen < 1)
492
+ throw new RangeError(`outputLen must be >= 1 (got ${outputLen})`);
493
+ this.outputLen = outputLen;
494
+ this.x = getExports();
495
+ this._tok = _acquireModule('sha3');
496
+ try {
497
+ this.x.shake256Init();
498
+ }
499
+ catch (e) {
500
+ _releaseModule('sha3', this._tok);
501
+ this._tok = undefined;
502
+ throw e;
503
+ }
504
+ }
505
+ update(chunk) {
506
+ if (this._tok === undefined)
507
+ throw new Error('SHAKE256Stream: instance has been disposed');
508
+ absorb(this.x, chunk);
509
+ return this;
510
+ }
511
+ finalize() {
512
+ if (this._tok === undefined)
513
+ throw new Error('SHAKE256Stream: instance has been disposed');
514
+ this.x.shakePad();
515
+ const out = new Uint8Array(this.outputLen);
516
+ const mem = new Uint8Array(this.x.memory.buffer);
517
+ const off = this.x.getOutOffset();
518
+ let pos = 0;
519
+ while (pos < this.outputLen) {
520
+ this.x.shakeSqueezeBlock();
521
+ const take = Math.min(this.outputLen - pos, this._rate);
522
+ out.set(mem.subarray(off, off + take), pos);
523
+ pos += take;
524
+ }
525
+ this.dispose();
526
+ return out;
527
+ }
528
+ dispose() {
529
+ if (this._tok === undefined)
530
+ return;
531
+ try {
532
+ this.x.wipeBuffers();
533
+ }
534
+ finally {
535
+ _releaseModule('sha3', this._tok);
536
+ this._tok = undefined;
537
+ }
244
538
  }
245
539
  }
540
+ // ── SHA3_256Hash ────────────────────────────────────────────────────────────
541
+ export { SHA3_256Hash } from './hash.js';
542
+ // ── cSHAKE / KMAC (SP 800-185) ──────────────────────────────────────────────
543
+ export { CSHAKE128, CSHAKE256, KMAC128, KMAC256, KMACXOF128, KMACXOF256 } from './kmac.js';
@@ -0,0 +1,121 @@
1
+ /**
2
+ * cSHAKE128, customizable SHAKE128 (SP 800-185 §3).
3
+ *
4
+ * Holds exclusive access to the `sha3` WASM module from construction until
5
+ * `dispose()`. Constructing any other sha3 user (SHAKE128/256, SHA3_*,
6
+ * KMAC*, CSHAKE*) while this instance is live throws.
7
+ */
8
+ export declare class CSHAKE128 {
9
+ private readonly x;
10
+ private readonly _rate;
11
+ private readonly _prefix;
12
+ private _squeezing;
13
+ private _block;
14
+ private _blockPos;
15
+ private _tok;
16
+ constructor(customization: Uint8Array);
17
+ reset(): this;
18
+ absorb(msg: Uint8Array): this;
19
+ squeeze(n: number): Uint8Array;
20
+ hash(msg: Uint8Array, outputLength: number): Uint8Array;
21
+ dispose(): void;
22
+ }
23
+ /**
24
+ * cSHAKE256, customizable SHAKE256 (SP 800-185 §3).
25
+ *
26
+ * Holds exclusive access to the `sha3` WASM module from construction until
27
+ * `dispose()`.
28
+ */
29
+ export declare class CSHAKE256 {
30
+ private readonly x;
31
+ private readonly _rate;
32
+ private readonly _prefix;
33
+ private _squeezing;
34
+ private _block;
35
+ private _blockPos;
36
+ private _tok;
37
+ constructor(customization: Uint8Array);
38
+ reset(): this;
39
+ absorb(msg: Uint8Array): this;
40
+ squeeze(n: number): Uint8Array;
41
+ hash(msg: Uint8Array, outputLength: number): Uint8Array;
42
+ dispose(): void;
43
+ }
44
+ /**
45
+ * KMAC128, keyed Keccak MAC, fixed-output (SP 800-185 §4).
46
+ *
47
+ * Bound to a specific output length at construction (the spec's right_encode(L)
48
+ * suffix is a function of L). Use `KMACXOF128` for arbitrary-length output.
49
+ *
50
+ * Holds exclusive access to the `sha3` WASM module from construction until
51
+ * `dispose()`.
52
+ */
53
+ export declare class KMAC128 {
54
+ private readonly x;
55
+ private readonly _rate;
56
+ private readonly _outLen;
57
+ private _finalized;
58
+ private _tok;
59
+ constructor(key: Uint8Array, outLen: number, customization: Uint8Array);
60
+ update(chunk: Uint8Array): this;
61
+ finalize(): Uint8Array;
62
+ mac(msg: Uint8Array): Uint8Array;
63
+ dispose(): void;
64
+ /**
65
+ * Constant-time tag verification. Throws `AuthenticationError('kmac128')`
66
+ * on mismatch (matches the lib's AEAD pattern). Returns `true` on success.
67
+ *
68
+ * Atomic, does not hold the sha3 module beyond the internal compute.
69
+ */
70
+ static verify(tag: Uint8Array, key: Uint8Array, msg: Uint8Array, customization: Uint8Array): true;
71
+ }
72
+ /**
73
+ * KMAC256, 256-bit-strength keyed Keccak MAC, fixed-output (SP 800-185 §4).
74
+ */
75
+ export declare class KMAC256 {
76
+ private readonly x;
77
+ private readonly _rate;
78
+ private readonly _outLen;
79
+ private _finalized;
80
+ private _tok;
81
+ constructor(key: Uint8Array, outLen: number, customization: Uint8Array);
82
+ update(chunk: Uint8Array): this;
83
+ finalize(): Uint8Array;
84
+ mac(msg: Uint8Array): Uint8Array;
85
+ dispose(): void;
86
+ static verify(tag: Uint8Array, key: Uint8Array, msg: Uint8Array, customization: Uint8Array): true;
87
+ }
88
+ /**
89
+ * KMACXOF128, XOF variant of KMAC128 (SP 800-185 §4.3.1). Output length
90
+ * is caller-chosen per squeeze; the spec's right_encode(0) suffix marks the
91
+ * XOF mode.
92
+ */
93
+ export declare class KMACXOF128 {
94
+ private readonly x;
95
+ private readonly _rate;
96
+ private _squeezing;
97
+ private _block;
98
+ private _blockPos;
99
+ private _tok;
100
+ constructor(key: Uint8Array, customization: Uint8Array);
101
+ update(chunk: Uint8Array): this;
102
+ squeeze(n: number): Uint8Array;
103
+ mac(msg: Uint8Array, outLen: number): Uint8Array;
104
+ dispose(): void;
105
+ }
106
+ /**
107
+ * KMACXOF256, XOF variant of KMAC256 (SP 800-185 §4.3.1).
108
+ */
109
+ export declare class KMACXOF256 {
110
+ private readonly x;
111
+ private readonly _rate;
112
+ private _squeezing;
113
+ private _block;
114
+ private _blockPos;
115
+ private _tok;
116
+ constructor(key: Uint8Array, customization: Uint8Array);
117
+ update(chunk: Uint8Array): this;
118
+ squeeze(n: number): Uint8Array;
119
+ mac(msg: Uint8Array, outLen: number): Uint8Array;
120
+ dispose(): void;
121
+ }