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
@@ -22,7 +22,7 @@
22
22
  // src/ts/chacha20/index.ts
23
23
  //
24
24
  // Public API classes for the ChaCha20 WASM module.
25
- // Uses the init() module cache call chacha20Init(source) before constructing.
25
+ // Uses the init() module cache, call chacha20Init(source) before constructing.
26
26
  import { getInstance, initModule, _acquireModule, _releaseModule, _assertNotOwned } from '../init.js';
27
27
  import { aeadEncrypt, aeadDecrypt, xcEncrypt, xcDecrypt } from './ops.js';
28
28
  import { AuthenticationError } from '../errors.js';
@@ -30,12 +30,13 @@ export { AuthenticationError };
30
30
  /**
31
31
  * Load and initialise the ChaCha20 WASM module from `source`.
32
32
  * Must be called before constructing any ChaCha20 class.
33
- * @param source WASM binary gzip+base64 string, URL, ArrayBuffer, Uint8Array,
33
+ * @param source WASM binary, gzip+base64 string, URL, ArrayBuffer, Uint8Array,
34
34
  * pre-compiled WebAssembly.Module, Response, or Promise<Response>
35
35
  */
36
36
  export async function chacha20Init(source) {
37
37
  return initModule('chacha20', source);
38
38
  }
39
+ export { isInitialized } from '../init.js';
39
40
  /** Returns the raw chacha20 WASM export object. @internal */
40
41
  function getExports() {
41
42
  return getInstance('chacha20').exports;
@@ -59,7 +60,7 @@ export class ChaCha20 {
59
60
  * Load key and nonce into WASM state and set the block counter to 1.
60
61
  * Must be called before each message (RFC 8439 §2.4).
61
62
  * @param key 32 bytes
62
- * @param nonce 12 bytes must be unique per (key, message)
63
+ * @param nonce 12 bytes, must be unique per (key, message)
63
64
  */
64
65
  beginEncrypt(key, nonce) {
65
66
  if (this._tok === undefined)
@@ -76,7 +77,7 @@ export class ChaCha20 {
76
77
  }
77
78
  /**
78
79
  * XOR `chunk` with the next keystream block(s). Counter advances automatically.
79
- * @param chunk Plaintext chunk must not exceed WASM CHUNK_SIZE
80
+ * @param chunk Plaintext chunk, must not exceed WASM CHUNK_SIZE
80
81
  * @returns Ciphertext of the same length
81
82
  */
82
83
  encryptChunk(chunk) {
@@ -84,7 +85,7 @@ export class ChaCha20 {
84
85
  throw new Error('ChaCha20: instance has been disposed');
85
86
  const maxChunk = this.x.getChunkSize();
86
87
  if (chunk.length > maxChunk)
87
- throw new RangeError(`chunk exceeds maximum size of ${maxChunk} bytes split into smaller chunks`);
88
+ throw new RangeError(`chunk exceeds maximum size of ${maxChunk} bytes, split into smaller chunks`);
88
89
  const mem = new Uint8Array(this.x.memory.buffer);
89
90
  const ptOff = this.x.getChunkPtOffset();
90
91
  const ctOff = this.x.getChunkCtOffset();
@@ -93,15 +94,15 @@ export class ChaCha20 {
93
94
  return mem.slice(ctOff, ctOff + chunk.length);
94
95
  }
95
96
  /**
96
- * Alias for `beginEncrypt` ChaCha20 is a stream cipher (symmetric).
97
+ * Alias for `beginEncrypt`, ChaCha20 is a stream cipher (symmetric).
97
98
  * @param key 32 bytes
98
- * @param nonce 12 bytes must match the value used to encrypt
99
+ * @param nonce 12 bytes, must match the value used to encrypt
99
100
  */
100
101
  beginDecrypt(key, nonce) {
101
102
  this.beginEncrypt(key, nonce);
102
103
  }
103
104
  /**
104
- * Alias for `encryptChunk` ChaCha20 is a stream cipher (symmetric).
105
+ * Alias for `encryptChunk`, ChaCha20 is a stream cipher (symmetric).
105
106
  * @param chunk Ciphertext chunk
106
107
  * @returns Plaintext of the same length
107
108
  */
@@ -137,7 +138,7 @@ export class Poly1305 {
137
138
  }
138
139
  /**
139
140
  * Compute a 16-byte Poly1305 MAC for `msg` using `key`.
140
- * @param key 32-byte one-time key must not be reused across messages
141
+ * @param key 32-byte one-time key, must not be reused across messages
141
142
  * @param msg Message to authenticate
142
143
  * @returns 16-byte Poly1305 tag
143
144
  */
@@ -177,7 +178,7 @@ export class Poly1305 {
177
178
  * Single-use encrypt guard: `encrypt()` may only be called once per instance.
178
179
  * Create a new instance for each encryption to prevent nonce reuse.
179
180
  *
180
- * `decrypt()` uses constant-time tag comparison XOR-accumulate pattern,
181
+ * `decrypt()` uses constant-time tag comparison, XOR-accumulate pattern,
181
182
  * no early return on mismatch. Plaintext is never returned on failure.
182
183
  */
183
184
  export class ChaCha20Poly1305 {
@@ -190,10 +191,10 @@ export class ChaCha20Poly1305 {
190
191
  * Encrypt and authenticate `plaintext` with ChaCha20-Poly1305 (RFC 8439 §2.8).
191
192
  *
192
193
  * **Single-use guard:** `encrypt()` may only be called once per instance.
193
- * Any throw including validation errors permanently locks this instance.
194
+ * Any throw, including validation errors, permanently locks this instance.
194
195
  * Always create a new `ChaCha20Poly1305` per message.
195
196
  * @param key 32 bytes
196
- * @param nonce 12 bytes must be unique per (key, message)
197
+ * @param nonce 12 bytes, must be unique per (key, message)
197
198
  * @param plaintext Data to encrypt
198
199
  * @param aad Additional authenticated data (optional)
199
200
  * @returns Ciphertext || 16-byte Poly1305 tag
@@ -203,24 +204,29 @@ export class ChaCha20Poly1305 {
203
204
  throw new Error('leviathan-crypto: encrypt() already called on this instance. '
204
205
  + 'Create a new instance for each encryption to prevent nonce reuse.');
205
206
  // Strict single-use: lock FIRST, before anything else. Any subsequent
206
- // throw including validation errors terminates the instance.
207
+ // throw, including validation errors, terminates the instance.
207
208
  this._used = true;
208
209
  _assertNotOwned('chacha20');
209
210
  if (key.length !== 32)
210
211
  throw new RangeError(`key must be 32 bytes (got ${key.length})`);
211
212
  if (nonce.length !== 12)
212
213
  throw new RangeError(`nonce must be 12 bytes (got ${nonce.length})`);
213
- const { ciphertext, tag } = aeadEncrypt(this.x, key, nonce, plaintext, aad);
214
- const out = new Uint8Array(ciphertext.length + 16);
215
- out.set(ciphertext);
216
- out.set(tag, ciphertext.length);
217
- return out;
214
+ try {
215
+ const { ciphertext, tag } = aeadEncrypt(this.x, key, nonce, plaintext, aad);
216
+ const out = new Uint8Array(ciphertext.length + 16);
217
+ out.set(ciphertext);
218
+ out.set(tag, ciphertext.length);
219
+ return out;
220
+ }
221
+ finally {
222
+ this.x.wipeBuffers();
223
+ }
218
224
  }
219
225
  /**
220
226
  * Verify and decrypt a ChaCha20-Poly1305 ciphertext (RFC 8439 §2.8).
221
227
  * Throws `AuthenticationError` if the tag does not match.
222
228
  * @param key 32 bytes
223
- * @param nonce 12 bytes must match the value used to encrypt
229
+ * @param nonce 12 bytes, must match the value used to encrypt
224
230
  * @param ciphertext Ciphertext || 16-byte tag (combined format from `encrypt`)
225
231
  * @param aad Additional authenticated data (optional)
226
232
  * @returns Plaintext
@@ -233,10 +239,15 @@ export class ChaCha20Poly1305 {
233
239
  if (nonce.length !== 12)
234
240
  throw new RangeError(`nonce must be 12 bytes (got ${nonce.length})`);
235
241
  if (ciphertext.length < 16)
236
- throw new RangeError(`ciphertext too short must include 16-byte tag (got ${ciphertext.length})`);
237
- const ct = ciphertext.subarray(0, ciphertext.length - 16);
238
- const tag = ciphertext.subarray(ciphertext.length - 16);
239
- return aeadDecrypt(this.x, key, nonce, ct, tag, aad);
242
+ throw new RangeError(`ciphertext too short, must include 16-byte tag (got ${ciphertext.length})`);
243
+ try {
244
+ const ct = ciphertext.subarray(0, ciphertext.length - 16);
245
+ const tag = ciphertext.subarray(ciphertext.length - 16);
246
+ return aeadDecrypt(this.x, key, nonce, ct, tag, aad);
247
+ }
248
+ finally {
249
+ this.x.wipeBuffers();
250
+ }
240
251
  }
241
252
  /** Wipe WASM cipher and MAC state. */
242
253
  dispose() {
@@ -249,7 +260,7 @@ export class ChaCha20Poly1305 {
249
260
  * XChaCha20-Poly1305 AEAD (IETF draft-irtf-cfrg-xchacha).
250
261
  *
251
262
  * Recommended authenticated encryption primitive for most use cases.
252
- * Uses a 24-byte nonce safe for random generation via crypto.getRandomValues.
263
+ * Uses a 24-byte nonce, safe for random generation via crypto.getRandomValues.
253
264
  *
254
265
  * Single-use encrypt guard: `encrypt()` may only be called once per instance.
255
266
  * Create a new instance for each encryption to prevent nonce reuse.
@@ -267,10 +278,10 @@ export class XChaCha20Poly1305 {
267
278
  * (draft-irtf-cfrg-xchacha). Recommended for general-purpose AEAD.
268
279
  *
269
280
  * **Single-use guard:** `encrypt()` may only be called once per instance.
270
- * Any throw including validation errors permanently locks this instance.
281
+ * Any throw, including validation errors, permanently locks this instance.
271
282
  * Always create a new `XChaCha20Poly1305` per message to prevent nonce reuse.
272
283
  * @param key 32 bytes
273
- * @param nonce 24 bytes safe to generate randomly via `randomBytes(24)`
284
+ * @param nonce 24 bytes, safe to generate randomly via `randomBytes(24)`
274
285
  * @param plaintext Data to encrypt
275
286
  * @param aad Additional authenticated data (optional)
276
287
  * @returns Ciphertext || 16-byte Poly1305 tag
@@ -280,20 +291,25 @@ export class XChaCha20Poly1305 {
280
291
  throw new Error('leviathan-crypto: encrypt() already called on this instance. '
281
292
  + 'Create a new instance for each encryption to prevent nonce reuse.');
282
293
  // Strict single-use: lock FIRST, before anything else. Any subsequent
283
- // throw including validation errors terminates the instance.
294
+ // throw, including validation errors, terminates the instance.
284
295
  this._used = true;
285
296
  _assertNotOwned('chacha20');
286
297
  if (key.length !== 32)
287
298
  throw new RangeError(`key must be 32 bytes (got ${key.length})`);
288
299
  if (nonce.length !== 24)
289
300
  throw new RangeError(`XChaCha20 nonce must be 24 bytes (got ${nonce.length})`);
290
- return xcEncrypt(this.x, key, nonce, plaintext, aad);
301
+ try {
302
+ return xcEncrypt(this.x, key, nonce, plaintext, aad);
303
+ }
304
+ finally {
305
+ this.x.wipeBuffers();
306
+ }
291
307
  }
292
308
  /**
293
309
  * Verify and decrypt an XChaCha20-Poly1305 ciphertext.
294
310
  * Throws `AuthenticationError` if the tag does not match.
295
311
  * @param key 32 bytes
296
- * @param nonce 24 bytes must match the value used to encrypt
312
+ * @param nonce 24 bytes, must match the value used to encrypt
297
313
  * @param ciphertext Ciphertext || 16-byte tag (combined format from `encrypt`)
298
314
  * @param aad Additional authenticated data (optional)
299
315
  * @returns Plaintext
@@ -305,8 +321,13 @@ export class XChaCha20Poly1305 {
305
321
  if (nonce.length !== 24)
306
322
  throw new RangeError(`XChaCha20 nonce must be 24 bytes (got ${nonce.length})`);
307
323
  if (ciphertext.length < 16)
308
- throw new RangeError(`ciphertext too short must include 16-byte tag (got ${ciphertext.length})`);
309
- return xcDecrypt(this.x, key, nonce, ciphertext, aad);
324
+ throw new RangeError(`ciphertext too short, must include 16-byte tag (got ${ciphertext.length})`);
325
+ try {
326
+ return xcDecrypt(this.x, key, nonce, ciphertext, aad);
327
+ }
328
+ finally {
329
+ this.x.wipeBuffers();
330
+ }
310
331
  }
311
332
  /** Wipe WASM cipher and MAC state. */
312
333
  dispose() {
@@ -317,18 +338,3 @@ export class XChaCha20Poly1305 {
317
338
  export { XChaCha20Cipher } from './cipher-suite.js';
318
339
  // ── ChaCha20Generator ───────────────────────────────────────────────────────
319
340
  export { ChaCha20Generator } from './generator.js';
320
- // ── Ready check ─────────────────────────────────────────────────────────────
321
- /**
322
- * Returns `true` if the chacha20 WASM module has been initialised.
323
- * Used by tests and internal guards; not part of the public API.
324
- * @internal
325
- */
326
- export function _chachaReady() {
327
- try {
328
- getInstance('chacha20');
329
- return true;
330
- }
331
- catch {
332
- return false;
333
- }
334
- }
@@ -3,10 +3,10 @@ import type { ChaChaExports } from './types.js';
3
3
  * ChaCha20-Poly1305 AEAD encrypt (RFC 8439 §2.8).
4
4
  * @param x ChaCha20 WASM exports
5
5
  * @param key 32-byte key
6
- * @param nonce 12-byte nonce must be unique per (key, message)
6
+ * @param nonce 12-byte nonce, must be unique per (key, message)
7
7
  * @param plaintext Data to encrypt (must be ≤ WASM CHUNK_SIZE)
8
8
  * @param aad Additional authenticated data
9
- * @returns `{ ciphertext, tag }` tag is 16 bytes
9
+ * @returns `{ ciphertext, tag }`, tag is 16 bytes
10
10
  */
11
11
  export declare function aeadEncrypt(x: ChaChaExports, key: Uint8Array, nonce: Uint8Array, plaintext: Uint8Array, aad: Uint8Array): {
12
12
  ciphertext: Uint8Array;
@@ -17,7 +17,7 @@ export declare function aeadEncrypt(x: ChaChaExports, key: Uint8Array, nonce: Ui
17
17
  * Throws `AuthenticationError` on tag mismatch; never returns plaintext on failure.
18
18
  * @param x ChaCha20 WASM exports
19
19
  * @param key 32-byte key
20
- * @param nonce 12-byte nonce must match the value used to encrypt
20
+ * @param nonce 12-byte nonce, must match the value used to encrypt
21
21
  * @param ciphertext Ciphertext bytes (must be ≤ WASM CHUNK_SIZE)
22
22
  * @param tag 16-byte Poly1305 tag
23
23
  * @param aad Additional authenticated data
@@ -30,15 +30,15 @@ export declare function aeadDecrypt(x: ChaChaExports, key: Uint8Array, nonce: Ui
30
30
  * Used as the inner key for XChaCha20-Poly1305 (draft-irtf-cfrg-xchacha §2.3).
31
31
  * @param x ChaCha20 WASM exports
32
32
  * @param key 32-byte master key
33
- * @param nonce 24-byte XChaCha20 nonce (only bytes 015 are used)
33
+ * @param nonce 24-byte XChaCha20 nonce (only bytes 0-15 are used)
34
34
  * @returns 32-byte HChaCha20 subkey
35
35
  */
36
36
  export declare function deriveSubkey(x: ChaChaExports, key: Uint8Array, nonce: Uint8Array): Uint8Array;
37
37
  /**
38
- * Build the inner 12-byte ChaCha20 nonce for XChaCha20 from bytes 1623 of the
38
+ * Build the inner 12-byte ChaCha20 nonce for XChaCha20 from bytes 16-23 of the
39
39
  * 24-byte XChaCha nonce (draft-irtf-cfrg-xchacha §2.3).
40
40
  * @param nonce 24-byte XChaCha20 nonce
41
- * @returns 12-byte inner nonce (bytes 03 are zero, bytes 411 are nonce[16:24])
41
+ * @returns 12-byte inner nonce (bytes 0-3 are zero, bytes 4-11 are nonce[16:24])
42
42
  */
43
43
  export declare function innerNonce(nonce: Uint8Array): Uint8Array;
44
44
  /**
@@ -59,7 +59,7 @@ export declare function xcEncrypt(x: ChaChaExports, key: Uint8Array, nonce: Uint
59
59
  * Throws `AuthenticationError` on tag mismatch.
60
60
  * @param x ChaCha20 WASM exports
61
61
  * @param key 32-byte key
62
- * @param nonce 24-byte nonce must match the value used to encrypt
62
+ * @param nonce 24-byte nonce, must match the value used to encrypt
63
63
  * @param ciphertext Ciphertext || 16-byte tag (combined format from `xcEncrypt`)
64
64
  * @param aad Additional authenticated data
65
65
  * @returns Plaintext
@@ -1,9 +1,9 @@
1
1
  // src/ts/chacha20/ops.ts
2
2
  //
3
- // Raw XChaCha20-Poly1305 operations standalone functions that take
3
+ // Raw XChaCha20-Poly1305 operations, standalone functions that take
4
4
  // ChaChaExports explicitly. Used by both the class wrappers (index.ts)
5
5
  // and the pool worker (pool.worker.ts), eliminating duplication.
6
- import { constantTimeEqual } from '../utils.js';
6
+ import { constantTimeEqual, wipe } from '../utils.js';
7
7
  import { AuthenticationError } from '../errors.js';
8
8
  // ── Module-private helpers ──────────────────────────────────────────────────
9
9
  /**
@@ -37,8 +37,8 @@ function polyFeed(x, data) {
37
37
  function lenBlock(aadLen, ctLen) {
38
38
  const b = new Uint8Array(16);
39
39
  const dv = new DataView(b.buffer);
40
- // RFC 8439 §2.8 64-bit LE lengths.
41
- // JS numbers are f64 write low 32 bits directly, high bits via
40
+ // RFC 8439 §2.8, 64-bit LE lengths.
41
+ // JS numbers are f64, write low 32 bits directly, high bits via
42
42
  // Math.floor(n / 2^32). Safe for n ≤ Number.MAX_SAFE_INTEGER.
43
43
  dv.setUint32(0, aadLen >>> 0, true);
44
44
  dv.setUint32(4, Math.floor(aadLen / 0x100000000) >>> 0, true);
@@ -51,15 +51,15 @@ function lenBlock(aadLen, ctLen) {
51
51
  * ChaCha20-Poly1305 AEAD encrypt (RFC 8439 §2.8).
52
52
  * @param x ChaCha20 WASM exports
53
53
  * @param key 32-byte key
54
- * @param nonce 12-byte nonce must be unique per (key, message)
54
+ * @param nonce 12-byte nonce, must be unique per (key, message)
55
55
  * @param plaintext Data to encrypt (must be ≤ WASM CHUNK_SIZE)
56
56
  * @param aad Additional authenticated data
57
- * @returns `{ ciphertext, tag }` tag is 16 bytes
57
+ * @returns `{ ciphertext, tag }`, tag is 16 bytes
58
58
  */
59
59
  export function aeadEncrypt(x, key, nonce, plaintext, aad) {
60
60
  const maxChunk = x.getChunkSize();
61
61
  if (plaintext.length > maxChunk)
62
- throw new RangeError(`plaintext exceeds ${maxChunk} bytes split into smaller chunks`);
62
+ throw new RangeError(`plaintext exceeds ${maxChunk} bytes, split into smaller chunks`);
63
63
  const mem = new Uint8Array(x.memory.buffer);
64
64
  // Step 1: Generate Poly1305 one-time key at counter=0 (RFC 8439 §2.6)
65
65
  mem.set(key, x.getKeyOffset());
@@ -73,12 +73,7 @@ export function aeadEncrypt(x, key, nonce, plaintext, aad) {
73
73
  const aadPad = (16 - aad.length % 16) % 16;
74
74
  if (aadPad > 0)
75
75
  polyFeed(x, new Uint8Array(aadPad));
76
- // Step 4: Re-init ChaCha20 at counter=1.
77
- // `chachaGenPolyKey` mutated CHACHA_STATE + 48 (the counter word) to 0 but
78
- // left every other state word intact (constants, key, nonce). Writing
79
- // counter=1 via `chachaSetCounter` restores the state for encryption —
80
- // no second `chachaLoadKey()` is needed (the key/nonce buffers and the
81
- // non-counter state words are already correct).
76
+ // Step 4: counter=1 (state intact from chachaGenPolyKey; no reload needed).
82
77
  x.chachaSetCounter(1);
83
78
  // Step 5: Encrypt
84
79
  mem.set(plaintext, x.getChunkPtOffset());
@@ -103,7 +98,7 @@ export function aeadEncrypt(x, key, nonce, plaintext, aad) {
103
98
  * Throws `AuthenticationError` on tag mismatch; never returns plaintext on failure.
104
99
  * @param x ChaCha20 WASM exports
105
100
  * @param key 32-byte key
106
- * @param nonce 12-byte nonce must match the value used to encrypt
101
+ * @param nonce 12-byte nonce, must match the value used to encrypt
107
102
  * @param ciphertext Ciphertext bytes (must be ≤ WASM CHUNK_SIZE)
108
103
  * @param tag 16-byte Poly1305 tag
109
104
  * @param aad Additional authenticated data
@@ -113,7 +108,7 @@ export function aeadEncrypt(x, key, nonce, plaintext, aad) {
113
108
  export function aeadDecrypt(x, key, nonce, ciphertext, tag, aad, cipherName = 'chacha20-poly1305') {
114
109
  const maxChunk = x.getChunkSize();
115
110
  if (ciphertext.length > maxChunk)
116
- throw new RangeError(`ciphertext exceeds ${maxChunk} bytes split into smaller chunks`);
111
+ throw new RangeError(`ciphertext exceeds ${maxChunk} bytes, split into smaller chunks`);
117
112
  const mem = new Uint8Array(x.memory.buffer);
118
113
  // Compute expected tag
119
114
  mem.set(key, x.getKeyOffset());
@@ -135,17 +130,12 @@ export function aeadDecrypt(x, key, nonce, ciphertext, tag, aad, cipherName = 'c
135
130
  const tagOff = x.getPolyTagOffset();
136
131
  const expectedTag = new Uint8Array(x.memory.buffer).slice(tagOff, tagOff + 16);
137
132
  if (!constantTimeEqual(expectedTag, tag)) {
138
- // Wipe the full chunk output buffer defense-in-depth before throwing.
133
+ // Defense-in-depth wipe on auth fail: chunk ct, chacha block (keystream),
134
+ // Poly1305 one-time subkey copy at POLY_KEY_OFFSET.
139
135
  const ctOff = x.getChunkCtOffset();
140
136
  mem.fill(0, ctOff, ctOff + maxChunk);
141
- // Also zero the 64-byte chacha block buffer — it holds keystream bytes
142
- // generated by chachaGenPolyKey() that would otherwise persist until
143
- // the next op or dispose().
144
137
  const blockOff = x.getChachaBlockOffset();
145
138
  mem.fill(0, blockOff, blockOff + 64);
146
- // And the 32-byte Poly1305 one-time subkey copy at POLY_KEY_OFFSET.
147
- // chachaGenPolyKey copies keystream[0..32] here; wiping CHACHA_BLOCK
148
- // zeroes the source but not this copy.
149
139
  const polyKeyOff = x.getPolyKeyOffset();
150
140
  mem.fill(0, polyKeyOff, polyKeyOff + 32);
151
141
  throw new AuthenticationError(cipherName);
@@ -164,7 +154,7 @@ export function aeadDecrypt(x, key, nonce, ciphertext, tag, aad, cipherName = 'c
164
154
  * Used as the inner key for XChaCha20-Poly1305 (draft-irtf-cfrg-xchacha §2.3).
165
155
  * @param x ChaCha20 WASM exports
166
156
  * @param key 32-byte master key
167
- * @param nonce 24-byte XChaCha20 nonce (only bytes 015 are used)
157
+ * @param nonce 24-byte XChaCha20 nonce (only bytes 0-15 are used)
168
158
  * @returns 32-byte HChaCha20 subkey
169
159
  */
170
160
  export function deriveSubkey(x, key, nonce) {
@@ -176,10 +166,10 @@ export function deriveSubkey(x, key, nonce) {
176
166
  return new Uint8Array(x.memory.buffer).slice(off, off + 32);
177
167
  }
178
168
  /**
179
- * Build the inner 12-byte ChaCha20 nonce for XChaCha20 from bytes 1623 of the
169
+ * Build the inner 12-byte ChaCha20 nonce for XChaCha20 from bytes 16-23 of the
180
170
  * 24-byte XChaCha nonce (draft-irtf-cfrg-xchacha §2.3).
181
171
  * @param nonce 24-byte XChaCha20 nonce
182
- * @returns 12-byte inner nonce (bytes 03 are zero, bytes 411 are nonce[16:24])
172
+ * @returns 12-byte inner nonce (bytes 0-3 are zero, bytes 4-11 are nonce[16:24])
183
173
  */
184
174
  export function innerNonce(nonce) {
185
175
  const n = new Uint8Array(12);
@@ -200,12 +190,17 @@ export function innerNonce(nonce) {
200
190
  */
201
191
  export function xcEncrypt(x, key, nonce, plaintext, aad) {
202
192
  const subkey = deriveSubkey(x, key, nonce);
203
- const inner = innerNonce(nonce);
204
- const { ciphertext, tag } = aeadEncrypt(x, subkey, inner, plaintext, aad);
205
- const result = new Uint8Array(ciphertext.length + 16);
206
- result.set(ciphertext);
207
- result.set(tag, ciphertext.length);
208
- return result;
193
+ try {
194
+ const inner = innerNonce(nonce);
195
+ const { ciphertext, tag } = aeadEncrypt(x, subkey, inner, plaintext, aad);
196
+ const result = new Uint8Array(ciphertext.length + 16);
197
+ result.set(ciphertext);
198
+ result.set(tag, ciphertext.length);
199
+ return result;
200
+ }
201
+ finally {
202
+ wipe(subkey);
203
+ }
209
204
  }
210
205
  /**
211
206
  * XChaCha20-Poly1305 decrypt (draft-irtf-cfrg-xchacha).
@@ -213,7 +208,7 @@ export function xcEncrypt(x, key, nonce, plaintext, aad) {
213
208
  * Throws `AuthenticationError` on tag mismatch.
214
209
  * @param x ChaCha20 WASM exports
215
210
  * @param key 32-byte key
216
- * @param nonce 24-byte nonce must match the value used to encrypt
211
+ * @param nonce 24-byte nonce, must match the value used to encrypt
217
212
  * @param ciphertext Ciphertext || 16-byte tag (combined format from `xcEncrypt`)
218
213
  * @param aad Additional authenticated data
219
214
  * @returns Plaintext
@@ -222,6 +217,11 @@ export function xcDecrypt(x, key, nonce, ciphertext, aad) {
222
217
  const ct = ciphertext.subarray(0, ciphertext.length - 16);
223
218
  const tag = ciphertext.subarray(ciphertext.length - 16);
224
219
  const subkey = deriveSubkey(x, key, nonce);
225
- const inner = innerNonce(nonce);
226
- return aeadDecrypt(x, subkey, inner, ct, tag, aad, 'xchacha20-poly1305');
220
+ try {
221
+ const inner = innerNonce(nonce);
222
+ return aeadDecrypt(x, subkey, inner, ct, tag, aad, 'xchacha20-poly1305');
223
+ }
224
+ finally {
225
+ wipe(subkey);
226
+ }
227
227
  }
@@ -12,9 +12,9 @@ let subkey;
12
12
  * Message handler for the XChaCha20 pool worker.
13
13
  *
14
14
  * Accepts three message types:
15
- * - `'init'` instantiate the chacha20 WASM module and store the derived subkey
16
- * - `'wipe'` zero subkey and WASM buffers, then post `{ type: 'wiped' }`
17
- * - `{ op: 'seal' | 'open', ... }` encrypt or decrypt one chunk
15
+ * - `'init'` , instantiate the chacha20 WASM module and store the derived subkey
16
+ * - `'wipe'` , zero subkey and WASM buffers, then post `{ type: 'wiped' }`
17
+ * - `{ op: 'seal' | 'open', ... }`, encrypt or decrypt one chunk
18
18
  *
19
19
  * Replies with `{ type: 'result', id, data }` on success or
20
20
  * `{ type: 'error', id, message, isAuthError }` on failure.
@@ -34,6 +34,8 @@ self.onmessage = async (e) => {
34
34
  self.postMessage({ type: 'ready' });
35
35
  }
36
36
  catch (err) {
37
+ if (msg.derivedKeyBytes)
38
+ msg.derivedKeyBytes.fill(0);
37
39
  self.postMessage({ type: 'error', id: -1, message: err.message, isAuthError: false });
38
40
  }
39
41
  return;
@@ -0,0 +1 @@
1
+ export declare const CTE_WASM: Uint8Array<ArrayBuffer>;
@@ -0,0 +1,3 @@
1
+ // auto-generated, do not edit
2
+ // raw WASM bytes for constant-time equality comparison module
3
+ export const CTE_WASM = new Uint8Array([0, 97, 115, 109, 1, 0, 0, 0, 1, 8, 1, 96, 3, 127, 127, 127, 1, 127, 3, 2, 1, 0, 5, 4, 1, 1, 1, 1, 7, 20, 2, 7, 99, 111, 109, 112, 97, 114, 101, 0, 0, 6, 109, 101, 109, 111, 114, 121, 2, 0, 10, 133, 1, 1, 130, 1, 3, 2, 127, 1, 126, 1, 123, 3, 64, 32, 3, 65, 16, 106, 34, 4, 32, 2, 76, 4, 64, 32, 6, 32, 0, 32, 3, 106, 253, 0, 4, 0, 32, 1, 32, 3, 106, 253, 0, 4, 0, 253, 81, 253, 80, 33, 6, 32, 4, 33, 3, 12, 1, 11, 11, 3, 64, 32, 2, 32, 3, 74, 4, 64, 32, 5, 32, 0, 32, 3, 106, 49, 0, 0, 32, 1, 32, 3, 106, 49, 0, 0, 133, 132, 33, 5, 32, 3, 65, 1, 106, 33, 3, 12, 1, 11, 11, 66, 0, 32, 5, 32, 6, 253, 29, 0, 32, 6, 253, 29, 1, 132, 132, 34, 5, 125, 32, 5, 132, 66, 63, 135, 66, 127, 133, 167, 65, 1, 113, 11]);
Binary file
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Convert a 64-byte raw r || s signature to DER per RFC 3279 §2.2.3.
3
+ * Output length is variable: 8 bytes minimum (r = s = 1 byte each, no
4
+ * sign-pad), 72 bytes maximum (both components 32 bytes with high bit
5
+ * set, each picking up a 0x00 sign-pad).
6
+ *
7
+ * @throws TypeError if `sig` is not a Uint8Array
8
+ * @throws RangeError if `sig.length !== 64`
9
+ */
10
+ export declare function ecdsaSignatureToDer(sig: Uint8Array): Uint8Array;
11
+ /**
12
+ * Convert a DER ECDSA-P256 signature to 64-byte raw r || s. Rejects
13
+ * any DER syntax violation via SigningError('sig-malformed-input'):
14
+ * see the file-level header for the rejection rules.
15
+ *
16
+ * Semantic value rejections (r = 0, s = 0, high-s, off-range) are
17
+ * deferred to the WASM verify path; this function only enforces DER
18
+ * structure.
19
+ *
20
+ * @throws TypeError if `der` is not a Uint8Array
21
+ * @throws SigningError('sig-malformed-input') on any DER syntax error
22
+ */
23
+ export declare function ecdsaSignatureFromDer(der: Uint8Array): Uint8Array;