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.
- package/CLAUDE.md +88 -281
- package/LICENSE +4 -0
- package/README.md +275 -87
- package/dist/aes/aes-cbc.d.ts +40 -0
- package/dist/aes/aes-cbc.js +158 -0
- package/dist/aes/aes-ctr.d.ts +50 -0
- package/dist/aes/aes-ctr.js +141 -0
- package/dist/aes/aes-gcm-siv.d.ts +67 -0
- package/dist/aes/aes-gcm-siv.js +217 -0
- package/dist/aes/aes-gcm.d.ts +61 -0
- package/dist/aes/aes-gcm.js +226 -0
- package/dist/aes/cipher-suite.d.ts +21 -0
- package/dist/aes/cipher-suite.js +179 -0
- package/dist/aes/embedded.d.ts +1 -0
- package/dist/aes/embedded.js +26 -0
- package/dist/aes/generator.d.ts +14 -0
- package/dist/aes/generator.js +103 -0
- package/dist/aes/index.d.ts +58 -0
- package/dist/aes/index.js +125 -0
- package/dist/aes/ops.d.ts +60 -0
- package/dist/aes/ops.js +164 -0
- package/dist/aes/pool-worker.d.ts +1 -0
- package/dist/aes/pool-worker.js +92 -0
- package/dist/aes/types.d.ts +1 -0
- package/dist/aes/types.js +23 -0
- package/dist/aes.wasm +0 -0
- package/dist/blake3/embedded.d.ts +1 -0
- package/dist/blake3/embedded.js +26 -0
- package/dist/blake3/index.d.ts +143 -0
- package/dist/blake3/index.js +620 -0
- package/dist/blake3/types.d.ts +102 -0
- package/dist/blake3/types.js +31 -0
- package/dist/blake3/validate.d.ts +29 -0
- package/dist/blake3/validate.js +80 -0
- package/dist/blake3.wasm +0 -0
- package/dist/chacha20/cipher-suite.d.ts +10 -0
- package/dist/chacha20/cipher-suite.js +98 -13
- package/dist/chacha20/generator.d.ts +12 -0
- package/dist/chacha20/generator.js +91 -0
- package/dist/chacha20/index.d.ts +100 -3
- package/dist/chacha20/index.js +169 -35
- package/dist/chacha20/ops.d.ts +57 -6
- package/dist/chacha20/ops.js +107 -27
- package/dist/chacha20/pool-worker.js +14 -0
- package/dist/chacha20/types.d.ts +1 -32
- package/dist/cte-wasm.d.ts +1 -0
- package/dist/cte-wasm.js +3 -0
- package/dist/cte.wasm +0 -0
- package/dist/curve25519.wasm +0 -0
- package/dist/ecdsa/der.d.ts +23 -0
- package/dist/ecdsa/der.js +192 -0
- package/dist/ecdsa/ecprivatekey-der.d.ts +32 -0
- package/dist/ecdsa/ecprivatekey-der.js +230 -0
- package/dist/ecdsa/embedded.d.ts +1 -0
- package/dist/ecdsa/embedded.js +25 -0
- package/dist/ecdsa/index.d.ts +124 -0
- package/dist/ecdsa/index.js +366 -0
- package/dist/ecdsa/types.d.ts +31 -0
- package/dist/ecdsa/types.js +28 -0
- package/dist/ecdsa/validate.d.ts +18 -0
- package/dist/ecdsa/validate.js +92 -0
- package/dist/ed25519/embedded.d.ts +1 -0
- package/dist/ed25519/embedded.js +31 -0
- package/dist/ed25519/index.d.ts +70 -0
- package/dist/ed25519/index.js +308 -0
- package/dist/ed25519/types.d.ts +27 -0
- package/dist/ed25519/types.js +27 -0
- package/dist/ed25519/validate.d.ts +7 -0
- package/dist/ed25519/validate.js +77 -0
- package/dist/embedded/aes-pool-worker.d.ts +1 -0
- package/dist/embedded/aes-pool-worker.js +5 -0
- package/dist/embedded/aes.d.ts +1 -0
- package/dist/embedded/aes.js +3 -0
- package/dist/embedded/blake3.d.ts +1 -0
- package/dist/embedded/blake3.js +3 -0
- package/dist/embedded/chacha20-pool-worker.d.ts +1 -0
- package/dist/embedded/chacha20-pool-worker.js +5 -0
- package/dist/embedded/chacha20.d.ts +1 -1
- package/dist/embedded/chacha20.js +2 -2
- package/dist/embedded/curve25519.d.ts +1 -0
- package/dist/embedded/curve25519.js +3 -0
- package/dist/embedded/mldsa.d.ts +1 -0
- package/dist/embedded/mldsa.js +3 -0
- package/dist/embedded/mlkem.d.ts +1 -0
- package/dist/embedded/mlkem.js +3 -0
- package/dist/embedded/p256.d.ts +1 -0
- package/dist/embedded/p256.js +3 -0
- package/dist/embedded/serpent-pool-worker.d.ts +1 -0
- package/dist/embedded/serpent-pool-worker.js +5 -0
- package/dist/embedded/serpent.d.ts +1 -1
- package/dist/embedded/serpent.js +2 -2
- package/dist/embedded/sha2.d.ts +1 -1
- package/dist/embedded/sha2.js +2 -2
- package/dist/embedded/sha3.d.ts +1 -1
- package/dist/embedded/sha3.js +2 -2
- package/dist/embedded/slhdsa.d.ts +1 -0
- package/dist/embedded/slhdsa.js +3 -0
- package/dist/errors.d.ts +92 -1
- package/dist/errors.js +111 -1
- package/dist/fortuna.d.ts +18 -12
- package/dist/fortuna.js +166 -99
- package/dist/index.d.ts +42 -11
- package/dist/index.js +65 -20
- package/dist/init.d.ts +1 -3
- package/dist/init.js +73 -7
- package/dist/keccak/embedded.js +1 -1
- package/dist/keccak/index.d.ts +2 -0
- package/dist/keccak/index.js +4 -2
- package/dist/loader.d.ts +1 -19
- package/dist/loader.js +26 -32
- package/dist/merkle/blake3-tree.d.ts +35 -0
- package/dist/merkle/blake3-tree.js +187 -0
- package/dist/merkle/checkpoint.d.ts +58 -0
- package/dist/merkle/checkpoint.js +217 -0
- package/dist/merkle/index.d.ts +19 -0
- package/dist/merkle/index.js +37 -0
- package/dist/merkle/merkle-log.d.ts +130 -0
- package/dist/merkle/merkle-log.js +207 -0
- package/dist/merkle/merkle-verifier.d.ts +126 -0
- package/dist/merkle/merkle-verifier.js +296 -0
- package/dist/merkle/proof.d.ts +70 -0
- package/dist/merkle/proof.js +300 -0
- package/dist/merkle/sha256-tree.d.ts +33 -0
- package/dist/merkle/sha256-tree.js +145 -0
- package/dist/merkle/signed-log.d.ts +156 -0
- package/dist/merkle/signed-log.js +356 -0
- package/dist/merkle/signed-note.d.ts +309 -0
- package/dist/merkle/signed-note.js +648 -0
- package/dist/merkle/sth.d.ts +31 -0
- package/dist/merkle/sth.js +31 -0
- package/dist/merkle/storage.d.ts +40 -0
- package/dist/merkle/storage.js +71 -0
- package/dist/merkle/tree.d.ts +68 -0
- package/dist/merkle/tree.js +94 -0
- package/dist/mldsa/embedded.d.ts +1 -0
- package/dist/{kyber → mldsa}/embedded.js +5 -5
- package/dist/mldsa/expand.d.ts +53 -0
- package/dist/mldsa/expand.js +188 -0
- package/dist/mldsa/format.d.ts +16 -0
- package/dist/mldsa/format.js +68 -0
- package/dist/mldsa/hashvariant.d.ts +32 -0
- package/dist/mldsa/hashvariant.js +248 -0
- package/dist/mldsa/index.d.ts +142 -0
- package/dist/mldsa/index.js +463 -0
- package/dist/mldsa/keygen.d.ts +16 -0
- package/dist/mldsa/keygen.js +232 -0
- package/dist/mldsa/params.d.ts +21 -0
- package/dist/mldsa/params.js +55 -0
- package/dist/mldsa/sha3-helpers.d.ts +30 -0
- package/dist/mldsa/sha3-helpers.js +124 -0
- package/dist/mldsa/sign.d.ts +36 -0
- package/dist/mldsa/sign.js +380 -0
- package/dist/mldsa/types.d.ts +91 -0
- package/dist/mldsa/types.js +25 -0
- package/dist/mldsa/validate.d.ts +55 -0
- package/dist/mldsa/validate.js +125 -0
- package/dist/mldsa/verify.d.ts +29 -0
- package/dist/mldsa/verify.js +269 -0
- package/dist/mldsa.wasm +0 -0
- package/dist/mlkem/embedded.d.ts +1 -0
- package/dist/mlkem/embedded.js +27 -0
- package/dist/mlkem/indcpa.d.ts +49 -0
- package/dist/{kyber → mlkem}/indcpa.js +48 -48
- package/dist/mlkem/index.d.ts +37 -0
- package/dist/{kyber → mlkem}/index.js +41 -31
- package/dist/mlkem/kem.d.ts +21 -0
- package/dist/{kyber → mlkem}/kem.js +48 -13
- package/dist/{kyber → mlkem}/params.d.ts +4 -4
- package/dist/{kyber → mlkem}/params.js +2 -2
- package/dist/mlkem/suite.d.ts +12 -0
- package/dist/{kyber → mlkem}/suite.js +17 -12
- package/dist/{kyber → mlkem}/types.d.ts +4 -3
- package/dist/{kyber → mlkem}/types.js +1 -1
- package/dist/mlkem/validate.d.ts +23 -0
- package/dist/{kyber → mlkem}/validate.js +24 -20
- package/dist/{kyber.wasm → mlkem.wasm} +0 -0
- package/dist/p256.wasm +0 -0
- package/dist/ratchet/index.d.ts +8 -0
- package/dist/ratchet/index.js +38 -0
- package/dist/ratchet/kdf-chain.d.ts +13 -0
- package/dist/ratchet/kdf-chain.js +85 -0
- package/dist/ratchet/ratchet-keypair.d.ts +9 -0
- package/dist/ratchet/ratchet-keypair.js +61 -0
- package/dist/ratchet/root-kdf.d.ts +4 -0
- package/dist/ratchet/root-kdf.js +124 -0
- package/dist/ratchet/skipped-key-store.d.ts +14 -0
- package/dist/ratchet/skipped-key-store.js +154 -0
- package/dist/ratchet/types.d.ts +36 -0
- package/dist/ratchet/types.js +26 -0
- package/dist/serpent/cipher-suite.d.ts +10 -0
- package/dist/serpent/cipher-suite.js +144 -56
- package/dist/serpent/generator.d.ts +12 -0
- package/dist/serpent/generator.js +97 -0
- package/dist/serpent/index.d.ts +62 -1
- package/dist/serpent/index.js +97 -21
- package/dist/serpent/pool-worker.js +28 -102
- package/dist/serpent/serpent-cbc.d.ts +16 -6
- package/dist/serpent/serpent-cbc.js +58 -37
- package/dist/serpent/shared-ops.d.ts +63 -0
- package/dist/serpent/shared-ops.js +178 -0
- package/dist/serpent/types.d.ts +1 -5
- package/dist/serpent.wasm +0 -0
- package/dist/sha2/hash.d.ts +2 -0
- package/dist/sha2/hash.js +53 -0
- package/dist/sha2/hkdf.js +5 -5
- package/dist/sha2/index.d.ts +22 -1
- package/dist/sha2/index.js +80 -11
- package/dist/sha2/types.d.ts +41 -2
- package/dist/sha2.wasm +0 -0
- package/dist/sha3/hash.d.ts +2 -0
- package/dist/sha3/hash.js +53 -0
- package/dist/sha3/index.d.ts +87 -3
- package/dist/sha3/index.js +317 -19
- package/dist/sha3/kmac.d.ts +121 -0
- package/dist/sha3/kmac.js +800 -0
- package/dist/sha3.wasm +0 -0
- package/dist/shared/pkcs7.d.ts +22 -0
- package/dist/shared/pkcs7.js +84 -0
- package/dist/sign/ctx.d.ts +41 -0
- package/dist/sign/ctx.js +102 -0
- package/dist/sign/envelope.d.ts +45 -0
- package/dist/sign/envelope.js +152 -0
- package/dist/sign/hasher.d.ts +9 -0
- package/dist/sign/hasher.js +132 -0
- package/dist/sign/index.d.ts +11 -0
- package/dist/sign/index.js +34 -0
- package/dist/sign/sign-stream.d.ts +25 -0
- package/dist/sign/sign-stream.js +112 -0
- package/dist/sign/suites/ecdsa-p256.d.ts +2 -0
- package/dist/sign/suites/ecdsa-p256.js +120 -0
- package/dist/sign/suites/ed25519.d.ts +3 -0
- package/dist/sign/suites/ed25519.js +165 -0
- package/dist/sign/suites/hybrid-classical.d.ts +23 -0
- package/dist/sign/suites/hybrid-classical.js +526 -0
- package/dist/sign/suites/hybrid-pq.d.ts +4 -0
- package/dist/sign/suites/hybrid-pq.js +234 -0
- package/dist/sign/suites/mldsa.d.ts +7 -0
- package/dist/sign/suites/mldsa.js +161 -0
- package/dist/sign/suites/slhdsa.d.ts +7 -0
- package/dist/sign/suites/slhdsa.js +176 -0
- package/dist/sign/types.d.ts +106 -0
- package/dist/sign/types.js +28 -0
- package/dist/sign/verify-stream.d.ts +30 -0
- package/dist/sign/verify-stream.js +227 -0
- package/dist/slhdsa/embedded.d.ts +1 -0
- package/dist/slhdsa/embedded.js +26 -0
- package/dist/slhdsa/index.d.ts +149 -0
- package/dist/slhdsa/index.js +493 -0
- package/dist/slhdsa/params.d.ts +26 -0
- package/dist/slhdsa/params.js +70 -0
- package/dist/slhdsa/prehash.d.ts +68 -0
- package/dist/slhdsa/prehash.js +307 -0
- package/dist/slhdsa/sign.d.ts +39 -0
- package/dist/slhdsa/sign.js +116 -0
- package/dist/slhdsa/types.d.ts +129 -0
- package/dist/slhdsa/types.js +27 -0
- package/dist/slhdsa/validate.d.ts +60 -0
- package/dist/slhdsa/validate.js +127 -0
- package/dist/slhdsa/verify.d.ts +32 -0
- package/dist/slhdsa/verify.js +107 -0
- package/dist/slhdsa.wasm +0 -0
- package/dist/stream/header.js +8 -8
- package/dist/stream/index.d.ts +1 -0
- package/dist/stream/index.js +1 -0
- package/dist/stream/open-stream.js +65 -22
- package/dist/stream/seal-stream-pool.d.ts +2 -0
- package/dist/stream/seal-stream-pool.js +100 -33
- package/dist/stream/seal-stream.d.ts +1 -1
- package/dist/stream/seal-stream.js +48 -19
- package/dist/stream/seal.js +6 -6
- package/dist/stream/types.d.ts +3 -1
- package/dist/stream/types.js +1 -1
- package/dist/types.d.ts +22 -1
- package/dist/types.js +1 -1
- package/dist/utils.d.ts +9 -10
- package/dist/utils.js +84 -59
- package/dist/wasm-source.d.ts +9 -8
- package/dist/wasm-source.js +1 -1
- package/dist/x25519/embedded.d.ts +1 -0
- package/dist/x25519/embedded.js +31 -0
- package/dist/x25519/index.d.ts +43 -0
- package/dist/x25519/index.js +159 -0
- package/dist/x25519/types.d.ts +25 -0
- package/dist/x25519/types.js +27 -0
- package/dist/x25519/validate.d.ts +2 -0
- package/dist/x25519/validate.js +39 -0
- package/package.json +123 -64
- package/SECURITY.md +0 -276
- package/dist/ct-wasm.d.ts +0 -1
- package/dist/ct-wasm.js +0 -3
- package/dist/ct.wasm +0 -0
- package/dist/docs/aead.md +0 -323
- package/dist/docs/architecture.md +0 -932
- package/dist/docs/argon2id.md +0 -302
- package/dist/docs/chacha20.md +0 -674
- package/dist/docs/exports.md +0 -241
- package/dist/docs/fortuna.md +0 -313
- package/dist/docs/init.md +0 -302
- package/dist/docs/loader.md +0 -161
- package/dist/docs/serpent.md +0 -519
- package/dist/docs/sha2.md +0 -613
- package/dist/docs/sha3.md +0 -546
- package/dist/docs/types.md +0 -276
- package/dist/docs/utils.md +0 -367
- package/dist/embedded/kyber.d.ts +0 -1
- package/dist/embedded/kyber.js +0 -3
- package/dist/kyber/embedded.d.ts +0 -1
- package/dist/kyber/indcpa.d.ts +0 -49
- package/dist/kyber/index.d.ts +0 -38
- package/dist/kyber/kem.d.ts +0 -21
- package/dist/kyber/suite.d.ts +0 -13
- package/dist/kyber/validate.d.ts +0 -19
|
@@ -0,0 +1,463 @@
|
|
|
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/mldsa/index.ts
|
|
23
|
+
//
|
|
24
|
+
// ML-DSA public API, MlDsa44, MlDsa65, MlDsa87 classes.
|
|
25
|
+
// FIPS 204, Module-Lattice-Based Digital Signature Standard.
|
|
26
|
+
//
|
|
27
|
+
// Public surface: keygen / keygenDerand, sign / verify (pure ML-DSA),
|
|
28
|
+
// and signHash / verifyHash (HashML-DSA). Use init({ mldsa, sha3 })
|
|
29
|
+
// before constructing any class, both modules are required.
|
|
30
|
+
import { getInstance, initModule, isInitialized, _assertNotOwned } from '../init.js';
|
|
31
|
+
import { randomBytes, wipe } from '../utils.js';
|
|
32
|
+
import { MLDSA44, MLDSA65, MLDSA87 } from './params.js';
|
|
33
|
+
import { mldsaKeygenInternal } from './keygen.js';
|
|
34
|
+
import { mldsaSignInternal, signWithPrehash } from './sign.js';
|
|
35
|
+
import { mldsaVerifyInternal, verifyWithPrehash } from './verify.js';
|
|
36
|
+
import { constructMPrime } from './format.js';
|
|
37
|
+
import { validateContext, validateSigningKey, validateRnd, validateMessage, validateDigest, } from './validate.js';
|
|
38
|
+
import { algoNeedsSha2, digestSize, preHashMessage, } from './hashvariant.js';
|
|
39
|
+
export async function mldsaInit(source) {
|
|
40
|
+
return initModule('mldsa', source);
|
|
41
|
+
}
|
|
42
|
+
export { MLDSA44, MLDSA65, MLDSA87 };
|
|
43
|
+
export { isInitialized };
|
|
44
|
+
// ── Layout assertion ────────────────────────────────────────────────────────
|
|
45
|
+
function assertLayout(mx, p) {
|
|
46
|
+
const matrix = mx.getMatrixSlot();
|
|
47
|
+
const matrixEnd = matrix + mx.getMatrixSlotSize();
|
|
48
|
+
const pvBase = mx.getPolyvecSlotBase();
|
|
49
|
+
const pkOff = mx.getPkOffset();
|
|
50
|
+
const skOff = mx.getSkOffset();
|
|
51
|
+
const sigOff = mx.getSigOffset();
|
|
52
|
+
const xofOff = mx.getXofPrfOffset();
|
|
53
|
+
if (matrixEnd > pvBase)
|
|
54
|
+
throw new Error('leviathan-crypto: mldsa MATRIX_SLOT overflows POLYVEC region');
|
|
55
|
+
const polyBytes = 1024;
|
|
56
|
+
if (p.k * p.l * polyBytes > mx.getMatrixSlotSize())
|
|
57
|
+
throw new Error(`leviathan-crypto: mldsa MATRIX_SLOT too small for ${p.paramSet} `
|
|
58
|
+
+ `(needs ${p.k * p.l * polyBytes}, have ${mx.getMatrixSlotSize()})`);
|
|
59
|
+
if (pkOff + p.pkBytes > skOff)
|
|
60
|
+
throw new Error('leviathan-crypto: mldsa pk buffer overflows into sk region');
|
|
61
|
+
if (skOff + p.skBytes > sigOff)
|
|
62
|
+
throw new Error('leviathan-crypto: mldsa sk buffer overflows into sig region');
|
|
63
|
+
if (sigOff + p.sigBytes > xofOff)
|
|
64
|
+
throw new Error('leviathan-crypto: mldsa sig buffer overflows into XOF region');
|
|
65
|
+
}
|
|
66
|
+
// ── Base class ──────────────────────────────────────────────────────────────
|
|
67
|
+
export class MlDsaBase {
|
|
68
|
+
params;
|
|
69
|
+
constructor(params) {
|
|
70
|
+
if (!isInitialized('mldsa'))
|
|
71
|
+
throw new Error('leviathan-crypto: call init({ mldsa: ... }) before using MlDsa classes');
|
|
72
|
+
if (!isInitialized('sha3'))
|
|
73
|
+
throw new Error('leviathan-crypto: call init({ sha3: ... }) before using MlDsa classes');
|
|
74
|
+
this.params = params;
|
|
75
|
+
assertLayout(this.mx, params);
|
|
76
|
+
}
|
|
77
|
+
get mx() {
|
|
78
|
+
return getInstance('mldsa').exports;
|
|
79
|
+
}
|
|
80
|
+
get sx() {
|
|
81
|
+
return getInstance('sha3').exports;
|
|
82
|
+
}
|
|
83
|
+
get sha2x() {
|
|
84
|
+
return getInstance('sha2').exports;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Deterministic key generation, FIPS 204 §6.1 Algorithm 6.
|
|
88
|
+
* @param xi 32-byte seed. The sole input; ml-dsa keygen has no
|
|
89
|
+
* additional rejection-tied randomness.
|
|
90
|
+
*/
|
|
91
|
+
keygenDerand(xi) {
|
|
92
|
+
_assertNotOwned('sha3');
|
|
93
|
+
_assertNotOwned('mldsa');
|
|
94
|
+
if (xi.length !== 32)
|
|
95
|
+
throw new RangeError(`xi seed must be 32 bytes (got ${xi.length})`);
|
|
96
|
+
return mldsaKeygenInternal(this.mx, this.sx, this.params, xi);
|
|
97
|
+
}
|
|
98
|
+
/** Random key generation, wraps `keygenDerand` with `randomBytes(32)`. */
|
|
99
|
+
keygen() {
|
|
100
|
+
const xi = randomBytes(32);
|
|
101
|
+
try {
|
|
102
|
+
return this.keygenDerand(xi);
|
|
103
|
+
}
|
|
104
|
+
finally {
|
|
105
|
+
wipe(xi);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Hedged signing, FIPS 204 §3.4 (recommended default).
|
|
110
|
+
* Generates a fresh 32-byte rnd via `randomBytes()` per signature; the
|
|
111
|
+
* rnd is mixed into ρ'' so two signatures over the same (sk, M) produce
|
|
112
|
+
* different bytes. Hedged signatures are recommended over deterministic
|
|
113
|
+
* because they remain unforgeable under fault attacks that bias the
|
|
114
|
+
* rejection-sampling stream (FIPS 204 §3.4 / §3.6.1).
|
|
115
|
+
*/
|
|
116
|
+
sign(sk, M, ctx = new Uint8Array(0)) {
|
|
117
|
+
_assertNotOwned('sha3');
|
|
118
|
+
_assertNotOwned('mldsa');
|
|
119
|
+
validateSigningKey(sk, this.params);
|
|
120
|
+
validateMessage(M);
|
|
121
|
+
validateContext(ctx);
|
|
122
|
+
// FIPS 204 §5.2 Algorithm 2 line 10, M' = 0x00 ‖ |ctx| ‖ ctx ‖ M.
|
|
123
|
+
const MPrime = constructMPrime(0x00, ctx, M);
|
|
124
|
+
const rnd = randomBytes(32);
|
|
125
|
+
try {
|
|
126
|
+
return mldsaSignInternal(this.mx, this.sx, this.params, sk, MPrime, rnd);
|
|
127
|
+
}
|
|
128
|
+
finally {
|
|
129
|
+
wipe(rnd);
|
|
130
|
+
wipe(MPrime);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Deterministic signing, FIPS 204 §3.4. Sets rnd ← 0³² so two
|
|
135
|
+
* signatures over the same (sk, M) produce identical bytes. Caller
|
|
136
|
+
* accepts the §3.4 caveat: deterministic signatures are vulnerable to
|
|
137
|
+
* fault attacks that bias the SampleInBall stream, use only when no
|
|
138
|
+
* entropy is available or determinism is a hard protocol requirement.
|
|
139
|
+
*/
|
|
140
|
+
signDeterministic(sk, M, ctx = new Uint8Array(0)) {
|
|
141
|
+
_assertNotOwned('sha3');
|
|
142
|
+
_assertNotOwned('mldsa');
|
|
143
|
+
validateSigningKey(sk, this.params);
|
|
144
|
+
validateMessage(M);
|
|
145
|
+
validateContext(ctx);
|
|
146
|
+
const MPrime = constructMPrime(0x00, ctx, M);
|
|
147
|
+
const rnd = new Uint8Array(32); // already zeros
|
|
148
|
+
try {
|
|
149
|
+
return mldsaSignInternal(this.mx, this.sx, this.params, sk, MPrime, rnd);
|
|
150
|
+
}
|
|
151
|
+
finally {
|
|
152
|
+
wipe(MPrime);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Externally-randomised signing, testing / CAVP API. Caller supplies
|
|
157
|
+
* the 32-byte rnd; library does not mix in additional entropy. Hard
|
|
158
|
+
* contract on the caller: rnd MUST come from an approved RBG and MUST
|
|
159
|
+
* NOT be reused across signatures. ACVP `sigGen` test vectors (with a
|
|
160
|
+
* supplied rnd) drive this path.
|
|
161
|
+
*/
|
|
162
|
+
signDerand(sk, M, ctx, rnd) {
|
|
163
|
+
_assertNotOwned('sha3');
|
|
164
|
+
_assertNotOwned('mldsa');
|
|
165
|
+
validateSigningKey(sk, this.params);
|
|
166
|
+
validateMessage(M);
|
|
167
|
+
validateContext(ctx);
|
|
168
|
+
validateRnd(rnd);
|
|
169
|
+
const MPrime = constructMPrime(0x00, ctx, M);
|
|
170
|
+
try {
|
|
171
|
+
return mldsaSignInternal(this.mx, this.sx, this.params, sk, MPrime, rnd);
|
|
172
|
+
}
|
|
173
|
+
finally {
|
|
174
|
+
wipe(MPrime);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Pure ML-DSA verify, FIPS 204 §5.3 Algorithm 3 / §6.3 Algorithm 8.
|
|
179
|
+
*
|
|
180
|
+
* Returns boolean, `true` only if (a) the FIPS 204 norm bound on z
|
|
181
|
+
* holds and (b) the constant-time comparison of c̃ to the recomputed
|
|
182
|
+
* c̃' succeeds. Throws RangeError only on caller-side contract
|
|
183
|
+
* violations (`ctx.length > 255`). Wrong-length pk/sig and malformed
|
|
184
|
+
* hint encodings are NOT contract violations: they cause `verify` to
|
|
185
|
+
* return false (FIPS 204 §3.6.2 / §D.3).
|
|
186
|
+
*/
|
|
187
|
+
verify(vk, M, sig, ctx = new Uint8Array(0)) {
|
|
188
|
+
_assertNotOwned('sha3');
|
|
189
|
+
_assertNotOwned('mldsa');
|
|
190
|
+
validateMessage(M);
|
|
191
|
+
// FIPS 204 §3.6.2, wrong-length pk or σ is not a caller bug; it
|
|
192
|
+
// is a structural mismatch that cannot verify. Return false rather
|
|
193
|
+
// than throw, matching how Algorithm 3 returns ⊥ on length mismatch.
|
|
194
|
+
if (!(vk instanceof Uint8Array) || vk.length !== this.params.pkBytes)
|
|
195
|
+
return false;
|
|
196
|
+
if (!(sig instanceof Uint8Array) || sig.length !== this.params.sigBytes)
|
|
197
|
+
return false;
|
|
198
|
+
// ctx oversize is a caller-side contract violation per Alg 3 line 1.
|
|
199
|
+
validateContext(ctx);
|
|
200
|
+
const MPrime = constructMPrime(0x00, ctx, M);
|
|
201
|
+
try {
|
|
202
|
+
return mldsaVerifyInternal(this.mx, this.sx, this.params, vk, MPrime, sig);
|
|
203
|
+
}
|
|
204
|
+
finally {
|
|
205
|
+
wipe(MPrime);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
// ── HashML-DSA, FIPS 204 §5.4 (pre-hash variant) ──────────────────────
|
|
209
|
+
//
|
|
210
|
+
// HashML-DSA wraps the same Sign_internal / Verify_internal primitives
|
|
211
|
+
// pure ML-DSA uses, but pre-hashes M and builds M' with domain-sep byte
|
|
212
|
+
// 0x01 plus the hash function's OID DER bytes, so signatures produced
|
|
213
|
+
// by sign / signHash on the same key are NOT interchangeable. See
|
|
214
|
+
// FIPS 204 §3.6.4 for the cross-protocol attack rationale.
|
|
215
|
+
//
|
|
216
|
+
// `ph` is the LAST positional parameter on every HashML-DSA method.
|
|
217
|
+
// There is no sensible default, the spec lists 12 approved choices and
|
|
218
|
+
// none has cryptographic priority. Callers must select one explicitly.
|
|
219
|
+
//
|
|
220
|
+
// `init({ sha2: ... })` is required only when `ph` is a SHA-2 family
|
|
221
|
+
// algorithm. Using SHA3-* / SHAKE pre-hash needs no additional modules
|
|
222
|
+
// beyond the `mldsa` + `sha3` pair pure ML-DSA already requires.
|
|
223
|
+
_assertHashPrereqs(ph) {
|
|
224
|
+
// Validate ph before any other dispatch so widened-type callers
|
|
225
|
+
// (e.g. parsing a vector file via `as PreHashAlgorithm`) hit the
|
|
226
|
+
// canonical "unsupported HashML-DSA pre-hash" RangeError rather
|
|
227
|
+
// than a downstream sha2-not-initialized error or a fallthrough.
|
|
228
|
+
digestSize(ph);
|
|
229
|
+
if (algoNeedsSha2(ph)) {
|
|
230
|
+
if (!isInitialized('sha2'))
|
|
231
|
+
throw new Error('leviathan-crypto: call init({ sha2: ... }) before HashML-DSA with SHA-2 pre-hash');
|
|
232
|
+
_assertNotOwned('sha2');
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Hedged HashML-DSA sign, FIPS 204 §5.4 Algorithm 4.
|
|
237
|
+
*
|
|
238
|
+
* Pre-hashes `M` with the chosen approved function `ph`, builds
|
|
239
|
+
* M' = 0x01 ‖ |ctx| ‖ ctx ‖ OID(ph) ‖ PH_M, then drives
|
|
240
|
+
* ML-DSA.Sign_internal with a fresh 32-byte rnd (FIPS 204 §3.4
|
|
241
|
+
* recommended default; see {@link sign} for the rationale).
|
|
242
|
+
*/
|
|
243
|
+
signHash(sk, M, ph, ctx = new Uint8Array(0)) {
|
|
244
|
+
_assertNotOwned('sha3');
|
|
245
|
+
_assertNotOwned('mldsa');
|
|
246
|
+
this._assertHashPrereqs(ph);
|
|
247
|
+
validateSigningKey(sk, this.params);
|
|
248
|
+
validateMessage(M);
|
|
249
|
+
validateContext(ctx);
|
|
250
|
+
const sha2x = algoNeedsSha2(ph) ? this.sha2x : undefined;
|
|
251
|
+
const PH_M = preHashMessage(this.sx, sha2x, ph, M);
|
|
252
|
+
const rnd = randomBytes(32);
|
|
253
|
+
try {
|
|
254
|
+
return signWithPrehash(this.mx, this.sx, this.params, sk, PH_M, ph, ctx, rnd);
|
|
255
|
+
}
|
|
256
|
+
finally {
|
|
257
|
+
wipe(rnd);
|
|
258
|
+
// PH_M is M-derived (M is public input) so leakage is benign,
|
|
259
|
+
// but discipline matters, wipe it on every path.
|
|
260
|
+
wipe(PH_M);
|
|
261
|
+
// SHA-2 module's INPUT/OUT/H regions held the last block of M
|
|
262
|
+
// and the digest. Wipe them so secret material from any prior
|
|
263
|
+
// sha2 op (e.g. an HMAC) plus this PH_M digest don't linger.
|
|
264
|
+
if (sha2x)
|
|
265
|
+
sha2x.wipeBuffers();
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Deterministic HashML-DSA sign, FIPS 204 §5.4 Algorithm 4 with
|
|
270
|
+
* rnd ← 0³². Same fault-attack caveat as {@link signDeterministic}.
|
|
271
|
+
*/
|
|
272
|
+
signHashDeterministic(sk, M, ph, ctx = new Uint8Array(0)) {
|
|
273
|
+
_assertNotOwned('sha3');
|
|
274
|
+
_assertNotOwned('mldsa');
|
|
275
|
+
this._assertHashPrereqs(ph);
|
|
276
|
+
validateSigningKey(sk, this.params);
|
|
277
|
+
validateMessage(M);
|
|
278
|
+
validateContext(ctx);
|
|
279
|
+
const sha2x = algoNeedsSha2(ph) ? this.sha2x : undefined;
|
|
280
|
+
const PH_M = preHashMessage(this.sx, sha2x, ph, M);
|
|
281
|
+
const rnd = new Uint8Array(32); // already zeros
|
|
282
|
+
try {
|
|
283
|
+
return signWithPrehash(this.mx, this.sx, this.params, sk, PH_M, ph, ctx, rnd);
|
|
284
|
+
}
|
|
285
|
+
finally {
|
|
286
|
+
wipe(PH_M);
|
|
287
|
+
if (sha2x)
|
|
288
|
+
sha2x.wipeBuffers();
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Externally-randomised HashML-DSA sign, testing / CAVP API. Caller
|
|
293
|
+
* supplies the 32-byte rnd (same contract as {@link signDerand}). Used
|
|
294
|
+
* to oracle ACVP HashML-DSA sigGen vectors with byte-identical output.
|
|
295
|
+
*/
|
|
296
|
+
signHashDerand(sk, M, ph, ctx, rnd) {
|
|
297
|
+
_assertNotOwned('sha3');
|
|
298
|
+
_assertNotOwned('mldsa');
|
|
299
|
+
this._assertHashPrereqs(ph);
|
|
300
|
+
validateSigningKey(sk, this.params);
|
|
301
|
+
validateMessage(M);
|
|
302
|
+
validateContext(ctx);
|
|
303
|
+
validateRnd(rnd);
|
|
304
|
+
const sha2x = algoNeedsSha2(ph) ? this.sha2x : undefined;
|
|
305
|
+
const PH_M = preHashMessage(this.sx, sha2x, ph, M);
|
|
306
|
+
try {
|
|
307
|
+
return signWithPrehash(this.mx, this.sx, this.params, sk, PH_M, ph, ctx, rnd);
|
|
308
|
+
}
|
|
309
|
+
finally {
|
|
310
|
+
wipe(PH_M);
|
|
311
|
+
if (sha2x)
|
|
312
|
+
sha2x.wipeBuffers();
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* HashML-DSA verify, FIPS 204 §5.4 Algorithm 5.
|
|
317
|
+
*
|
|
318
|
+
* Same return / throw posture as {@link verify}: returns boolean for
|
|
319
|
+
* every signature outcome (including malformed-σ → false), throws
|
|
320
|
+
* RangeError only on caller-side contract violations such as
|
|
321
|
+
* `ctx.length > 255` or unsupported `ph`.
|
|
322
|
+
*/
|
|
323
|
+
verifyHash(vk, M, sig, ph, ctx = new Uint8Array(0)) {
|
|
324
|
+
_assertNotOwned('sha3');
|
|
325
|
+
_assertNotOwned('mldsa');
|
|
326
|
+
this._assertHashPrereqs(ph);
|
|
327
|
+
validateMessage(M);
|
|
328
|
+
// FIPS 204 §3.6.2, wrong-length pk or σ is not a caller bug; it
|
|
329
|
+
// is a structural mismatch that cannot verify. Return false rather
|
|
330
|
+
// than throw, matching how Algorithm 5 returns false on length
|
|
331
|
+
// mismatch via Verify_internal's structural checks.
|
|
332
|
+
if (!(vk instanceof Uint8Array) || vk.length !== this.params.pkBytes)
|
|
333
|
+
return false;
|
|
334
|
+
if (!(sig instanceof Uint8Array) || sig.length !== this.params.sigBytes)
|
|
335
|
+
return false;
|
|
336
|
+
validateContext(ctx);
|
|
337
|
+
const sha2x = algoNeedsSha2(ph) ? this.sha2x : undefined;
|
|
338
|
+
const PH_M = preHashMessage(this.sx, sha2x, ph, M);
|
|
339
|
+
try {
|
|
340
|
+
return verifyWithPrehash(this.mx, this.sx, this.params, vk, PH_M, sig, ph, ctx);
|
|
341
|
+
}
|
|
342
|
+
finally {
|
|
343
|
+
wipe(PH_M);
|
|
344
|
+
if (sha2x)
|
|
345
|
+
sha2x.wipeBuffers();
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
// ── HashML-DSA prehashed variants, FIPS 204 §5.4 ──────────────────────
|
|
349
|
+
/**
|
|
350
|
+
* Hedged HashML-DSA sign with a caller-supplied prehash, FIPS 204
|
|
351
|
+
* §5.4 Algorithm 4 lines 22-24 (the post-PH path).
|
|
352
|
+
*
|
|
353
|
+
* `digest` must be exactly `digestSize(ph)` bytes (FIPS 204 §5.4.1);
|
|
354
|
+
* a mismatch throws `SigningError('sig-malformed-input')`. The caller
|
|
355
|
+
* owns `digest` and is responsible for wiping it; this method never
|
|
356
|
+
* mutates the buffer.
|
|
357
|
+
*
|
|
358
|
+
* Hedged variant generates a fresh 32-byte rnd internally per
|
|
359
|
+
* signature, see {@link sign} for the §3.4 rationale.
|
|
360
|
+
*/
|
|
361
|
+
signHashPrehashed(sk, digest, ph, ctx = new Uint8Array(0)) {
|
|
362
|
+
_assertNotOwned('sha3');
|
|
363
|
+
_assertNotOwned('mldsa');
|
|
364
|
+
this._assertHashPrereqs(ph);
|
|
365
|
+
validateSigningKey(sk, this.params);
|
|
366
|
+
validateContext(ctx);
|
|
367
|
+
validateDigest(digest, ph);
|
|
368
|
+
const rnd = randomBytes(32);
|
|
369
|
+
try {
|
|
370
|
+
return signWithPrehash(this.mx, this.sx, this.params, sk, digest, ph, ctx, rnd);
|
|
371
|
+
}
|
|
372
|
+
finally {
|
|
373
|
+
wipe(rnd);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Deterministic HashML-DSA sign with a caller-supplied prehash, rnd
|
|
378
|
+
* ← 0³² per FIPS 204 §3.4. Same fault-attack caveat as
|
|
379
|
+
* {@link signDeterministic}.
|
|
380
|
+
*/
|
|
381
|
+
signHashPrehashedDeterministic(sk, digest, ph, ctx = new Uint8Array(0)) {
|
|
382
|
+
_assertNotOwned('sha3');
|
|
383
|
+
_assertNotOwned('mldsa');
|
|
384
|
+
this._assertHashPrereqs(ph);
|
|
385
|
+
validateSigningKey(sk, this.params);
|
|
386
|
+
validateContext(ctx);
|
|
387
|
+
validateDigest(digest, ph);
|
|
388
|
+
const rnd = new Uint8Array(32); // already zeros
|
|
389
|
+
return signWithPrehash(this.mx, this.sx, this.params, sk, digest, ph, ctx, rnd);
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Externally-randomised HashML-DSA sign with a caller-supplied
|
|
393
|
+
* prehash, testing / CAVP API. Caller supplies the 32-byte rnd (same
|
|
394
|
+
* contract as {@link signDerand}): rnd MUST come from an approved RBG
|
|
395
|
+
* and MUST NOT be reused across signatures.
|
|
396
|
+
*/
|
|
397
|
+
signHashPrehashedDerand(sk, digest, ph, rnd, ctx = new Uint8Array(0)) {
|
|
398
|
+
_assertNotOwned('sha3');
|
|
399
|
+
_assertNotOwned('mldsa');
|
|
400
|
+
this._assertHashPrereqs(ph);
|
|
401
|
+
validateSigningKey(sk, this.params);
|
|
402
|
+
validateContext(ctx);
|
|
403
|
+
validateRnd(rnd);
|
|
404
|
+
validateDigest(digest, ph);
|
|
405
|
+
return signWithPrehash(this.mx, this.sx, this.params, sk, digest, ph, ctx, rnd);
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* HashML-DSA verify with a caller-supplied prehash, FIPS 204 §5.4
|
|
409
|
+
* Algorithm 5 lines 17-19 (the post-PH path).
|
|
410
|
+
*
|
|
411
|
+
* Returns boolean for every signature outcome. Wrong-length pk / σ
|
|
412
|
+
* and wrong-size `digest` all return `false` (FIPS 204 §3.6.2
|
|
413
|
+
* structural mismatch). Throws `RangeError` only on caller-side
|
|
414
|
+
* contract violations (`ctx.length > 255`, unsupported `ph`).
|
|
415
|
+
*/
|
|
416
|
+
verifyHashPrehashed(vk, digest, sig, ph, ctx = new Uint8Array(0)) {
|
|
417
|
+
_assertNotOwned('sha3');
|
|
418
|
+
_assertNotOwned('mldsa');
|
|
419
|
+
this._assertHashPrereqs(ph);
|
|
420
|
+
// FIPS 204 §3.6.2, wrong-length pk / σ are not contract violations;
|
|
421
|
+
// they are structural mismatches that cannot verify. Wrong-size
|
|
422
|
+
// digest follows the same posture (the digest is an input to M',
|
|
423
|
+
// a wrong length means M' would have a different shape than the
|
|
424
|
+
// signer used). Return false rather than throw.
|
|
425
|
+
if (!(vk instanceof Uint8Array) || vk.length !== this.params.pkBytes)
|
|
426
|
+
return false;
|
|
427
|
+
if (!(sig instanceof Uint8Array) || sig.length !== this.params.sigBytes)
|
|
428
|
+
return false;
|
|
429
|
+
if (!(digest instanceof Uint8Array) || digest.length !== digestSize(ph))
|
|
430
|
+
return false;
|
|
431
|
+
validateContext(ctx);
|
|
432
|
+
return verifyWithPrehash(this.mx, this.sx, this.params, vk, digest, sig, ph, ctx);
|
|
433
|
+
}
|
|
434
|
+
dispose() {
|
|
435
|
+
this.mx.wipeBuffers();
|
|
436
|
+
// MlDsaBase does not own the sha3 module, wiping sha3 here would
|
|
437
|
+
// clobber any SHAKE128/SHAKE256 instance live at the time of
|
|
438
|
+
// dispose(). The wipe is not needed: every public mldsa op
|
|
439
|
+
// (keygen, sign, verify and their Hash variants) calls
|
|
440
|
+
// sx.wipeBuffers() before returning, under the
|
|
441
|
+
// _assertNotOwned('sha3') guard it holds. sha3 scratch carries no
|
|
442
|
+
// residue across an mldsa op boundary.
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
// ── Public classes ──────────────────────────────────────────────────────────
|
|
446
|
+
/** ML-DSA-44, FIPS 204 §4 Table 1 (NIST security category 2). */
|
|
447
|
+
export class MlDsa44 extends MlDsaBase {
|
|
448
|
+
constructor() {
|
|
449
|
+
super(MLDSA44);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
/** ML-DSA-65, FIPS 204 §4 Table 1 (NIST security category 3). */
|
|
453
|
+
export class MlDsa65 extends MlDsaBase {
|
|
454
|
+
constructor() {
|
|
455
|
+
super(MLDSA65);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
/** ML-DSA-87, FIPS 204 §4 Table 1 (NIST security category 5). */
|
|
459
|
+
export class MlDsa87 extends MlDsaBase {
|
|
460
|
+
constructor() {
|
|
461
|
+
super(MLDSA87);
|
|
462
|
+
}
|
|
463
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { MlDsaExports, Sha3Exports, MlDsaKeyPair } from './types.js';
|
|
2
|
+
import type { MlDsaParams } from './params.js';
|
|
3
|
+
/**
|
|
4
|
+
* ML-DSA.KeyGen_internal, FIPS 204 Algorithm 6.
|
|
5
|
+
*
|
|
6
|
+
* Input ξ (32 bytes): the keygen seed. Produced internally by `keygen()`
|
|
7
|
+
* via `randomBytes(32)`, or supplied by `keygenDerand`.
|
|
8
|
+
* Output (pk, sk) byte-encoded per Alg 22 (pkEncode) and Alg 24 (skEncode).
|
|
9
|
+
*
|
|
10
|
+
* Wipe contract on return: every WASM region that held a secret or
|
|
11
|
+
* secret-derived intermediate is zeroed. Public regions (matrix Â, t₁,
|
|
12
|
+
* pk, ρ) are deliberately not wiped, they can be re-derived from the
|
|
13
|
+
* returned pk/sk anyway. The caller is expected to wipe the local ξ
|
|
14
|
+
* buffer it allocated; this function does not own that buffer.
|
|
15
|
+
*/
|
|
16
|
+
export declare function mldsaKeygenInternal(mx: MlDsaExports, sx: Sha3Exports, params: MlDsaParams, xi: Uint8Array): MlDsaKeyPair;
|