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
@@ -0,0 +1,25 @@
1
+ import type { StreamableSignatureSuite } from './types.js';
2
+ export declare class SignStream {
3
+ private readonly suite;
4
+ private readonly sk;
5
+ private readonly ctx;
6
+ private hasher;
7
+ private finalized;
8
+ private disposed;
9
+ constructor(suite: StreamableSignatureSuite, sk: Uint8Array, ctx: Uint8Array);
10
+ /**
11
+ * Build the wire-format preamble for `payloadLength`. Available at
12
+ * any point in the stream lifecycle. See
13
+ * docs/signing.md#attached-envelope.
14
+ */
15
+ buildPreamble(payloadLength: number): Uint8Array;
16
+ /** Feed a chunk to the running prehash. */
17
+ update(chunk: Uint8Array): void;
18
+ /**
19
+ * Finalize the running prehash and sign. Returns the signature bytes.
20
+ * Caller writes these as the last segment of the output stream.
21
+ */
22
+ finalize(): Uint8Array;
23
+ /** Wipe lib-owned state. Idempotent. */
24
+ dispose(): void;
25
+ }
@@ -0,0 +1,112 @@
1
+ // ▄▄▄▄▄▄▄▄▄▄
2
+ // ▄████████████████████▄▄ ▒ ▄▀▀ ▒ ▒ █ ▄▀▄ ▀█▀ █ ▒ ▄▀▄ █▀▄
3
+ // ▄██████████████████████ ▀████▄ ▓ ▓▀ ▓ ▓ ▓ ▓▄▓ ▓ ▓▀▓ ▓▄▓ ▓ ▓
4
+ // ▄█████████▀▀▀ ▀███████▄▄███████▌ ▀▄ ▀▄▄ ▀▄▀ ▒ ▒ ▒ ▒ ▒ █ ▒ ▒ ▒ █
5
+ // ▐████████▀ ▄▄▄▄ ▀████████▀██▀█▌
6
+ // ████████ ███▀▀ ████▀ █▀ █▀ Leviathan Crypto Library
7
+ // ███████▌ ▀██▀ ███
8
+ // ███████ ▀███ ▀██ ▀█▄ Repository & Mirror:
9
+ // ▀██████ ▄▄██ ▀▀ ██▄ github.com/xero/leviathan-crypto
10
+ // ▀█████▄ ▄██▄ ▄▀▄▀ unpkg.com/leviathan-crypto
11
+ // ▀████▄ ▄██▄
12
+ // ▐████ ▐███ Author: xero (https://x-e.ro)
13
+ // ▄▄██████████ ▐███ ▄▄ License: MIT
14
+ // ▄██▀▀▀▀▀▀▀▀▀▀ ▄████ ▄██▀
15
+ // ▄▀ ▄▄█████████▄▄ ▀▀▀▀▀ ▄███ This file is provided completely
16
+ // ▄██████▀▀▀▀▀▀██████▄ ▀▄▄▄▄████▀ free, "as is", and without
17
+ // ████▀ ▄▄▄▄▄▄▄ ▀████▄ ▀█████▀ ▄▄▄▄ warranty of any kind. The author
18
+ // █████▄▄█████▀▀▀▀▀▀▄ ▀███▄ ▄████ assumes absolutely no liability
19
+ // ▀██████▀ ▀████▄▄▄████▀ for its {ab,mis,}use.
20
+ // ▀█████▀▀
21
+ //
22
+ // src/ts/sign/sign-stream.ts
23
+ //
24
+ // SignStream class, streaming signature production for StreamableSignatureSuite.
25
+ // Sender writes: preamble + payload bytes + sig (from finalize). Wire format
26
+ // is identical to Sign.sign output.
27
+ import { SigningError } from '../errors.js';
28
+ import { wipe } from '../utils.js';
29
+ import { USER_CTX_MAX } from './ctx.js';
30
+ import { createRunningHash } from './hasher.js';
31
+ export class SignStream {
32
+ suite;
33
+ sk;
34
+ ctx;
35
+ hasher;
36
+ finalized = false;
37
+ disposed = false;
38
+ constructor(suite, sk, ctx) {
39
+ this.suite = suite;
40
+ this.sk = sk;
41
+ if (ctx.length > USER_CTX_MAX)
42
+ throw new SigningError('sig-ctx-too-long', `user_ctx length ${ctx.length} > ${USER_CTX_MAX}`);
43
+ // Copy ctx so a later caller-side mutation cannot retroactively
44
+ // change the bytes the preamble emits.
45
+ this.ctx = new Uint8Array(ctx);
46
+ this.hasher = createRunningHash(suite.prehashAlgorithm);
47
+ }
48
+ /**
49
+ * Build the wire-format preamble for `payloadLength`. Available at
50
+ * any point in the stream lifecycle. See
51
+ * docs/signing.md#attached-envelope.
52
+ */
53
+ buildPreamble(payloadLength) {
54
+ if (!Number.isInteger(payloadLength) || payloadLength < 0)
55
+ throw new SigningError('sig-malformed-input', `payloadLength must be a non-negative integer, got ${payloadLength}`);
56
+ if (payloadLength > 0xFFFFFFFF)
57
+ throw new SigningError('sig-malformed-input', `payloadLength ${payloadLength} > 2^32 - 1 (wire format payload_len is u32)`);
58
+ const out = new Uint8Array(2 + this.ctx.length + 4);
59
+ let pos = 0;
60
+ out[pos++] = this.suite.formatEnum;
61
+ out[pos++] = this.ctx.length;
62
+ out.set(this.ctx, pos);
63
+ pos += this.ctx.length;
64
+ out[pos++] = (payloadLength >>> 24) & 0xFF;
65
+ out[pos++] = (payloadLength >>> 16) & 0xFF;
66
+ out[pos++] = (payloadLength >>> 8) & 0xFF;
67
+ out[pos] = payloadLength & 0xFF;
68
+ return out;
69
+ }
70
+ /** Feed a chunk to the running prehash. */
71
+ update(chunk) {
72
+ if (this.disposed)
73
+ throw new SigningError('sig-stream-disposed');
74
+ if (this.finalized)
75
+ throw new SigningError('sig-stream-finalized');
76
+ this.hasher.update(chunk);
77
+ }
78
+ /**
79
+ * Finalize the running prehash and sign. Returns the signature bytes.
80
+ * Caller writes these as the last segment of the output stream.
81
+ */
82
+ finalize() {
83
+ if (this.disposed)
84
+ throw new SigningError('sig-stream-disposed');
85
+ if (this.finalized)
86
+ throw new SigningError('sig-stream-finalized');
87
+ this.finalized = true;
88
+ const h = this.hasher;
89
+ let digest;
90
+ try {
91
+ digest = h.finalize();
92
+ return this.suite.signPrehashed(this.sk, digest, this.ctx);
93
+ }
94
+ finally {
95
+ if (digest !== undefined)
96
+ wipe(digest);
97
+ h.dispose();
98
+ this.hasher = undefined;
99
+ }
100
+ }
101
+ /** Wipe lib-owned state. Idempotent. */
102
+ dispose() {
103
+ if (this.disposed)
104
+ return;
105
+ this.disposed = true;
106
+ if (this.hasher !== undefined) {
107
+ this.hasher.dispose();
108
+ this.hasher = undefined;
109
+ }
110
+ wipe(this.ctx);
111
+ }
112
+ }
@@ -0,0 +1,2 @@
1
+ import type { StreamableSignatureSuite } from '../types.js';
2
+ export declare const EcdsaP256Suite: StreamableSignatureSuite;
@@ -0,0 +1,120 @@
1
+ // ▄▄▄▄▄▄▄▄▄▄
2
+ // ▄████████████████████▄▄ ▒ ▄▀▀ ▒ ▒ █ ▄▀▄ ▀█▀ █ ▒ ▄▀▄ █▀▄
3
+ // ▄██████████████████████ ▀████▄ ▓ ▓▀ ▓ ▓ ▓ ▓▄▓ ▓ ▓▀▓ ▓▄▓ ▓ ▓
4
+ // ▄█████████▀▀▀ ▀███████▄▄███████▌ ▀▄ ▀▄▄ ▀▄▀ ▒ ▒ ▒ ▒ ▒ █ ▒ ▒ ▒ █
5
+ // ▐████████▀ ▄▄▄▄ ▀████████▀██▀█▌
6
+ // ████████ ███▀▀ ████▀ █▀ █▀ Leviathan Crypto Library
7
+ // ███████▌ ▀██▀ ███
8
+ // ███████ ▀███ ▀██ ▀█▄ Repository & Mirror:
9
+ // ▀██████ ▄▄██ ▀▀ ██▄ github.com/xero/leviathan-crypto
10
+ // ▀█████▄ ▄██▄ ▄▀▄▀ unpkg.com/leviathan-crypto
11
+ // ▀████▄ ▄██▄
12
+ // ▐████ ▐███ Author: xero (https://x-e.ro)
13
+ // ▄▄██████████ ▐███ ▄▄ License: MIT
14
+ // ▄██▀▀▀▀▀▀▀▀▀▀ ▄████ ▄██▀
15
+ // ▄▀ ▄▄█████████▄▄ ▀▀▀▀▀ ▄███ This file is provided completely
16
+ // ▄██████▀▀▀▀▀▀██████▄ ▀▄▄▄▄████▀ free, "as is", and without
17
+ // ████▀ ▄▄▄▄▄▄▄ ▀████▄ ▀█████▀ ▄▄▄▄ warranty of any kind. The author
18
+ // █████▄▄█████▀▀▀▀▀▀▄ ▀███▄ ▄████ assumes absolutely no liability
19
+ // ▀██████▀ ▀████▄▄▄████▀ for its {ab,mis,}use.
20
+ // ▀█████▀▀
21
+ //
22
+ // src/ts/sign/suites/ecdsa-p256.ts
23
+ //
24
+ // EcdsaP256Suite (0x02, FIPS 186-5 §6.4 over SHA-256). Hedged-by-default
25
+ // per draft-irtf-cfrg-det-sigs-with-noise-05.
26
+ //
27
+ // Catalog + sizes: docs/signaturesuite.md. Suite reference: docs/ecdsa-p256.md.
28
+ import { SigningError } from '../../errors.js';
29
+ import { EcdsaP256 } from '../../ecdsa/index.js';
30
+ import { randomBytes, utf8ToBytes, wipe } from '../../utils.js';
31
+ import { CTX_DOMAIN_MAX } from '../ctx.js';
32
+ import { sha256OneShot } from '../hasher.js';
33
+ function EcdsaP256SuiteFactory(formatEnum, formatName, ctxDomain) {
34
+ if (utf8ToBytes(ctxDomain).length > CTX_DOMAIN_MAX)
35
+ throw new Error(`leviathan-crypto: ctxDomain '${ctxDomain}' too long for ${formatName}`);
36
+ const wasmModules = Object.freeze(['p256', 'sha2']);
37
+ const prehashAlgorithm = 'sha-256';
38
+ const prehashSize = 32;
39
+ function rejectCtx(ctx) {
40
+ if (ctx.length > 0)
41
+ throw new SigningError('sig-ctx-unsupported', `${formatName} does not support user context; ECDSA-P256 has `
42
+ + 'no native ctx parameter in FIPS 186-5 §6.4. Use the '
43
+ + 'classical+PQ hybrid suites (catalog 0x22 / 0x23) for '
44
+ + 'context-bound ECDSA-P256 signatures.');
45
+ }
46
+ return {
47
+ formatEnum,
48
+ formatName,
49
+ ctxDomain,
50
+ pkSize: 33,
51
+ skSize: 32,
52
+ sigMaxSize: 64,
53
+ wasmModules,
54
+ prehashAlgorithm,
55
+ prehashSize,
56
+ sign(sk, msg, ctx) {
57
+ rejectCtx(ctx);
58
+ const digest = sha256OneShot(msg);
59
+ const rnd = randomBytes(32);
60
+ const inst = new EcdsaP256();
61
+ try {
62
+ return inst._signInternalPk(sk, digest, rnd);
63
+ }
64
+ finally {
65
+ wipe(rnd);
66
+ wipe(digest);
67
+ inst.dispose();
68
+ }
69
+ },
70
+ verify(pk, msg, sig, ctx) {
71
+ rejectCtx(ctx);
72
+ const digest = sha256OneShot(msg);
73
+ const inst = new EcdsaP256();
74
+ try {
75
+ return inst.verify(pk, digest, sig);
76
+ }
77
+ finally {
78
+ inst.dispose();
79
+ wipe(digest);
80
+ }
81
+ },
82
+ keygen() {
83
+ const inst = new EcdsaP256();
84
+ try {
85
+ const kp = inst.keygen();
86
+ return { pk: kp.publicKey, sk: kp.secretKey };
87
+ }
88
+ finally {
89
+ inst.dispose();
90
+ }
91
+ },
92
+ signPrehashed(sk, digest, ctx) {
93
+ rejectCtx(ctx);
94
+ if (digest.length !== prehashSize)
95
+ throw new SigningError('sig-malformed-input', `digest length ${digest.length} != expected ${prehashSize} for ${formatName}`);
96
+ const rnd = randomBytes(32);
97
+ const inst = new EcdsaP256();
98
+ try {
99
+ return inst._signInternalPk(sk, digest, rnd);
100
+ }
101
+ finally {
102
+ wipe(rnd);
103
+ inst.dispose();
104
+ }
105
+ },
106
+ verifyPrehashed(pk, digest, sig, ctx) {
107
+ rejectCtx(ctx);
108
+ if (digest.length !== prehashSize)
109
+ throw new SigningError('sig-malformed-input', `digest length ${digest.length} != expected ${prehashSize} for ${formatName}`);
110
+ const inst = new EcdsaP256();
111
+ try {
112
+ return inst.verify(pk, digest, sig);
113
+ }
114
+ finally {
115
+ inst.dispose();
116
+ }
117
+ },
118
+ };
119
+ }
120
+ export const EcdsaP256Suite = EcdsaP256SuiteFactory(0x02, 'ecdsa-p256', 'ecdsa-p256-envelope-v3');
@@ -0,0 +1,3 @@
1
+ import type { SignatureSuite, StreamableSignatureSuite } from '../types.js';
2
+ export declare const Ed25519Suite: SignatureSuite;
3
+ export declare const Ed25519PreHashSuite: StreamableSignatureSuite;
@@ -0,0 +1,165 @@
1
+ // ▄▄▄▄▄▄▄▄▄▄
2
+ // ▄████████████████████▄▄ ▒ ▄▀▀ ▒ ▒ █ ▄▀▄ ▀█▀ █ ▒ ▄▀▄ █▀▄
3
+ // ▄██████████████████████ ▀████▄ ▓ ▓▀ ▓ ▓ ▓ ▓▄▓ ▓ ▓▀▓ ▓▄▓ ▓ ▓
4
+ // ▄█████████▀▀▀ ▀███████▄▄███████▌ ▀▄ ▀▄▄ ▀▄▀ ▒ ▒ ▒ ▒ ▒ █ ▒ ▒ ▒ █
5
+ // ▐████████▀ ▄▄▄▄ ▀████████▀██▀█▌
6
+ // ████████ ███▀▀ ████▀ █▀ █▀ Leviathan Crypto Library
7
+ // ███████▌ ▀██▀ ███
8
+ // ███████ ▀███ ▀██ ▀█▄ Repository & Mirror:
9
+ // ▀██████ ▄▄██ ▀▀ ██▄ github.com/xero/leviathan-crypto
10
+ // ▀█████▄ ▄██▄ ▄▀▄▀ unpkg.com/leviathan-crypto
11
+ // ▀████▄ ▄██▄
12
+ // ▐████ ▐███ Author: xero (https://x-e.ro)
13
+ // ▄▄██████████ ▐███ ▄▄ License: MIT
14
+ // ▄██▀▀▀▀▀▀▀▀▀▀ ▄████ ▄██▀
15
+ // ▄▀ ▄▄█████████▄▄ ▀▀▀▀▀ ▄███ This file is provided completely
16
+ // ▄██████▀▀▀▀▀▀██████▄ ▀▄▄▄▄████▀ free, "as is", and without
17
+ // ████▀ ▄▄▄▄▄▄▄ ▀████▄ ▀█████▀ ▄▄▄▄ warranty of any kind. The author
18
+ // █████▄▄█████▀▀▀▀▀▀▄ ▀███▄ ▄████ assumes absolutely no liability
19
+ // ▀██████▀ ▀████▄▄▄████▀ for its {ab,mis,}use.
20
+ // ▀█████▀▀
21
+ //
22
+ // src/ts/sign/suites/ed25519.ts
23
+ //
24
+ // Ed25519Suite (0x01, RFC 8032 §5.1.6) and Ed25519PreHashSuite
25
+ // (0x11, Ed25519ph, RFC 8032 §5.1.7).
26
+ //
27
+ // Catalog + sizes: docs/signaturesuite.md. Suite reference: docs/ed25519.md.
28
+ import { utf8ToBytes, wipe } from '../../utils.js';
29
+ import { SigningError } from '../../errors.js';
30
+ import { Ed25519 } from '../../ed25519/index.js';
31
+ import { buildEffectiveCtx, CTX_DOMAIN_MAX, } from '../ctx.js';
32
+ import { sha512OneShot } from '../hasher.js';
33
+ // ── Pure-mode factory ───────────────────────────────────────────────────────
34
+ function Ed25519PureSuite(formatEnum, formatName, ctxDomain) {
35
+ if (utf8ToBytes(ctxDomain).length > CTX_DOMAIN_MAX)
36
+ throw new Error(`leviathan-crypto: ctxDomain '${ctxDomain}' too long for ${formatName}`);
37
+ const wasmModules = Object.freeze(['curve25519']);
38
+ return {
39
+ formatEnum,
40
+ formatName,
41
+ ctxDomain,
42
+ pkSize: 32,
43
+ skSize: 32,
44
+ sigMaxSize: 64,
45
+ wasmModules,
46
+ sign(sk, msg, ctx) {
47
+ if (ctx.length > 0)
48
+ throw new SigningError('sig-ctx-unsupported', `${formatName} (pure Ed25519) does not support user context; `
49
+ + 'use Ed25519PreHashSuite (formatEnum 0x11) for context-bound signatures');
50
+ const inst = new Ed25519();
51
+ try {
52
+ return inst._signInternalPk(sk, msg);
53
+ }
54
+ finally {
55
+ inst.dispose();
56
+ }
57
+ },
58
+ verify(pk, msg, sig, ctx) {
59
+ if (ctx.length > 0)
60
+ throw new SigningError('sig-ctx-unsupported', `${formatName} (pure Ed25519) does not support user context; `
61
+ + 'use Ed25519PreHashSuite (formatEnum 0x11) for context-bound signatures');
62
+ const inst = new Ed25519();
63
+ try {
64
+ return inst.verify(pk, msg, sig);
65
+ }
66
+ finally {
67
+ inst.dispose();
68
+ }
69
+ },
70
+ keygen() {
71
+ const inst = new Ed25519();
72
+ try {
73
+ const kp = inst.keygen();
74
+ return { pk: kp.publicKey, sk: kp.secretKey };
75
+ }
76
+ finally {
77
+ inst.dispose();
78
+ }
79
+ },
80
+ };
81
+ }
82
+ // ── Prehash-mode factory ────────────────────────────────────────────────────
83
+ function Ed25519PrehashSuite(formatEnum, formatName, ctxDomain) {
84
+ if (utf8ToBytes(ctxDomain).length > CTX_DOMAIN_MAX)
85
+ throw new Error(`leviathan-crypto: ctxDomain '${ctxDomain}' too long for ${formatName}`);
86
+ const wasmModules = Object.freeze(['curve25519', 'sha2']);
87
+ const prehashAlgorithm = 'sha-512';
88
+ const prehashSize = 64;
89
+ return {
90
+ formatEnum,
91
+ formatName,
92
+ ctxDomain,
93
+ pkSize: 32,
94
+ skSize: 32,
95
+ sigMaxSize: 64,
96
+ wasmModules,
97
+ prehashAlgorithm,
98
+ prehashSize,
99
+ sign(sk, msg, ctx) {
100
+ const effectiveCtx = buildEffectiveCtx(ctxDomain, ctx);
101
+ const digest = sha512OneShot(msg);
102
+ const inst = new Ed25519();
103
+ try {
104
+ return inst._signPrehashedInternalPk(sk, digest, effectiveCtx);
105
+ }
106
+ finally {
107
+ inst.dispose();
108
+ wipe(digest);
109
+ wipe(effectiveCtx);
110
+ }
111
+ },
112
+ verify(pk, msg, sig, ctx) {
113
+ const effectiveCtx = buildEffectiveCtx(ctxDomain, ctx);
114
+ const digest = sha512OneShot(msg);
115
+ const inst = new Ed25519();
116
+ try {
117
+ return inst.verifyPrehashed(pk, digest, effectiveCtx, sig);
118
+ }
119
+ finally {
120
+ inst.dispose();
121
+ wipe(digest);
122
+ wipe(effectiveCtx);
123
+ }
124
+ },
125
+ keygen() {
126
+ const inst = new Ed25519();
127
+ try {
128
+ const kp = inst.keygen();
129
+ return { pk: kp.publicKey, sk: kp.secretKey };
130
+ }
131
+ finally {
132
+ inst.dispose();
133
+ }
134
+ },
135
+ signPrehashed(sk, digest, ctx) {
136
+ if (digest.length !== prehashSize)
137
+ throw new SigningError('sig-malformed-input', `digest length ${digest.length} != expected ${prehashSize} for ${formatName}`);
138
+ const effectiveCtx = buildEffectiveCtx(ctxDomain, ctx);
139
+ const inst = new Ed25519();
140
+ try {
141
+ return inst._signPrehashedInternalPk(sk, digest, effectiveCtx);
142
+ }
143
+ finally {
144
+ inst.dispose();
145
+ wipe(effectiveCtx);
146
+ }
147
+ },
148
+ verifyPrehashed(pk, digest, sig, ctx) {
149
+ if (digest.length !== prehashSize)
150
+ throw new SigningError('sig-malformed-input', `digest length ${digest.length} != expected ${prehashSize} for ${formatName}`);
151
+ const effectiveCtx = buildEffectiveCtx(ctxDomain, ctx);
152
+ const inst = new Ed25519();
153
+ try {
154
+ return inst.verifyPrehashed(pk, digest, effectiveCtx, sig);
155
+ }
156
+ finally {
157
+ inst.dispose();
158
+ wipe(effectiveCtx);
159
+ }
160
+ },
161
+ };
162
+ }
163
+ // ── Exported suite consts ───────────────────────────────────────────────────
164
+ export const Ed25519Suite = Ed25519PureSuite(0x01, 'ed25519', 'ed25519-envelope-v3');
165
+ export const Ed25519PreHashSuite = Ed25519PrehashSuite(0x11, 'ed25519-prehash', 'ed25519-prehash-envelope-v3');
@@ -0,0 +1,23 @@
1
+ import type { StreamableSignatureSuite } from '../types.js';
2
+ /**
3
+ * Composite ML-DSA-44 + Ed25519 with SHA-512 prehash.
4
+ * composite-sigs §6, id-MLDSA44-Ed25519-SHA512 (OID 1.3.6.1.5.5.7.6.39).
5
+ */
6
+ export declare const MlDsa44Ed25519Suite: StreamableSignatureSuite;
7
+ /**
8
+ * Composite ML-DSA-65 + Ed25519 with SHA-512 prehash.
9
+ * composite-sigs §6, id-MLDSA65-Ed25519-SHA512 (OID 1.3.6.1.5.5.7.6.48).
10
+ */
11
+ export declare const MlDsa65Ed25519Suite: StreamableSignatureSuite;
12
+ /**
13
+ * Composite ML-DSA-44 + ECDSA-P256 with SHA-256 prehash.
14
+ * composite-sigs §6, id-MLDSA44-ECDSA-P256-SHA256 (OID 1.3.6.1.5.5.7.6.40).
15
+ */
16
+ export declare const MlDsa44EcdsaP256Suite: StreamableSignatureSuite;
17
+ /**
18
+ * Composite ML-DSA-65 + ECDSA-P256 with SHA-512 prehash on the composite
19
+ * layer; the ECDSA half still hashes M' with SHA-256 per composite-sigs §6
20
+ * `ecdsa-with-SHA256` and §10.1 (deployment-fit rationale).
21
+ * composite-sigs §6, id-MLDSA65-ECDSA-P256-SHA512 (OID 1.3.6.1.5.5.7.6.45).
22
+ */
23
+ export declare const MlDsa65EcdsaP256Suite: StreamableSignatureSuite;