@monolythium/core-sdk 0.4.0 → 0.4.2
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/dist/crypto/index.cjs +138 -77
- package/dist/crypto/index.cjs.map +1 -1
- package/dist/crypto/index.d.cts +3 -252
- package/dist/crypto/index.d.ts +3 -252
- package/dist/crypto/index.js +138 -77
- package/dist/crypto/index.js.map +1 -1
- package/dist/index.cjs +1273 -92
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +113 -6
- package/dist/index.d.ts +113 -6
- package/dist/index.js +1243 -94
- package/dist/index.js.map +1 -1
- package/dist/{submission-CKXlYstD.d.cts → submission-Cc9r1eqX.d.cts} +395 -63
- package/dist/{submission-CKXlYstD.d.ts → submission-Cc9r1eqX.d.ts} +395 -63
- package/package.json +1 -1
package/dist/crypto/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { I as MlDsa65Backend
|
|
2
|
-
export {
|
|
1
|
+
import { I as MlDsa65Backend } from '../submission-Cc9r1eqX.cjs';
|
|
2
|
+
export { j0 as ADDRESS_DERIVATION_DOMAIN, j1 as CLUSTER_MLKEM_SHAMIR, j2 as CLUSTER_MLKEM_SHAMIR_ALGO, j3 as ClusterSealKeyEntryInput, j4 as ClusterSealKeys, j5 as ClusterSealKeysSource, j6 as DKG_AEAD_TAG_LEN, j7 as DKG_NONCE_LEN, j8 as DecryptHint, j9 as ENCRYPTED_SUBMISSION_UNAVAILABLE_MESSAGE, ja as ENUM_VARIANT_INDEX_ML_DSA_65, jb as EncryptedEnvelope, jc as EncryptedSubmission, E as EncryptionKey, jd as JsonRpcCallClient, je as LythiumSealEnvelope, jf as ML_DSA_65_PUBLIC_KEY_LEN, jg as ML_DSA_65_SEED_LEN, jh as ML_DSA_65_SIGNATURE_LEN, ji as ML_DSA_65_SIGNING_KEY_LEN, jj as ML_KEM_768_CIPHERTEXT_LEN, jk as ML_KEM_768_ENCAPSULATION_KEY_LEN, jl as ML_KEM_768_SHARED_SECRET_LEN, F as MempoolClass, D as NativeEvmTxFields, jm as NativeTxExtension, jn as NativeTxExtensionDescriptor, jo as NativeTxExtensionLike, jp as NonceAad, jq as PlaintextSubmission, jr as SEAL_COMMIT_LEN, js as SEAL_DK_LEN, jt as SEAL_EK_LEN, ju as SEAL_KEM_CT_LEN, jv as SEAL_KEM_SEED_LEN, jw as SEAL_KEY_LEN, jx as SEAL_NONCE_LEN, jy as SEAL_SHARE_LEN, jz as SEAL_TAG_LEN, jA as STANDARD_ALGO_NUMBER_ML_DSA_65, jB as SealRandomSource, jC as SealRecipient, jD as SealedSubmission, jE as bincodeDecryptHint, jF as bincodeEncryptedEnvelope, jG as bincodeNonceAad, jH as bincodeSignedTransaction, jI as buildEncryptedEnvelope, jJ as buildEncryptedSubmission, jK as buildPlaintextSubmission, jL as cryptoRandomSource, jM as encodeMlDsa65Opaque, jN as encodeSealEnvelope, jO as encodeTransactionForHash, jP as encryptInnerTx, jQ as fetchEncryptionKey, jR as getClusterSealKeys, jS as mlDsa65AddressBytes, jT as mlDsa65AddressFromPublicKey, jU as outerSigDigest, jV as parseClusterSealKeys, jW as sealRosterHash, jX as sealToCluster, jY as sealTransaction, jZ as submitEncryptedEnvelope, j_ as submitPlaintextTransaction, j$ as submitSealedTransaction, k0 as submitTransactionWithPrivacy } from '../submission-Cc9r1eqX.cjs';
|
|
3
3
|
|
|
4
4
|
declare class BincodeWriter {
|
|
5
5
|
#private;
|
|
@@ -51,253 +51,4 @@ declare function pqm1MnemonicToMlDsa65Backend(mnemonic: string): MlDsa65Backend;
|
|
|
51
51
|
declare function pqm1MnemonicToAddress(mnemonic: string): string;
|
|
52
52
|
declare function generatePqm1Mnemonic(rng?: Pqm1Rng): string;
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
* LythiumSeal scheme-3 client-side seal primitive.
|
|
56
|
-
*
|
|
57
|
-
* Post-quantum cluster-threshold encrypted-mempool sealing:
|
|
58
|
-
* cluster-ML-KEM-768 (FIPS-203) + information-theoretic GF(256) Shamir
|
|
59
|
-
* `t`-of-`n` + committing ChaCha20-Poly1305 (with an explicit SHAKE256
|
|
60
|
-
* key-commitment). A signed transaction body is sealed to a committee of
|
|
61
|
-
* `n` operators such that any `t` of them, each holding only its own
|
|
62
|
-
* ML-KEM decapsulation key, must cooperate to recover the plaintext. No
|
|
63
|
-
* single operator (and no minority of `< t`) can read the body.
|
|
64
|
-
*
|
|
65
|
-
* This is a byte-exact port of the standalone `lythiumseal` Rust crate
|
|
66
|
-
* (github.com/monolythium/lythiumseal) plus the chain-side
|
|
67
|
-
* `LythiumSealEnvelope` wire shape from `mono-core`'s mempool
|
|
68
|
-
* (`seal_to_cluster`). Byte-compatibility is proven by a cross-language
|
|
69
|
-
* KAT (`tests/lythiumseal-kat.test.ts`) against vectors generated from the
|
|
70
|
-
* Rust reference: the same fixed roster + deterministic draw order
|
|
71
|
-
* reproduces the exact envelope bincode bytes the chain accepts, and a
|
|
72
|
-
* Rust-sealed envelope round-trips through the TS decoder.
|
|
73
|
-
*
|
|
74
|
-
* The cryptography is standardized: ML-KEM-768 from `@noble/post-quantum`,
|
|
75
|
-
* ChaCha20-Poly1305 from `@noble/ciphers`, and SHAKE256 from
|
|
76
|
-
* `@noble/hashes`. The GF(256) Shamir layer is the AES field (reduction
|
|
77
|
-
* polynomial 0x11b) implemented in-module to match the crate exactly.
|
|
78
|
-
*/
|
|
79
|
-
/** ML-KEM-768 encapsulation-key byte length. */
|
|
80
|
-
declare const SEAL_EK_LEN = 1184;
|
|
81
|
-
/** ML-KEM-768 decapsulation-key byte length. */
|
|
82
|
-
declare const SEAL_DK_LEN = 2400;
|
|
83
|
-
/** ML-KEM-768 ciphertext byte length. */
|
|
84
|
-
declare const SEAL_KEM_CT_LEN = 1088;
|
|
85
|
-
/** ML-KEM-768 keygen seed length (`d || z`, FIPS-203). */
|
|
86
|
-
declare const SEAL_KEM_SEED_LEN = 64;
|
|
87
|
-
/** AEAD key length (ChaCha20-Poly1305 / body key). */
|
|
88
|
-
declare const SEAL_KEY_LEN = 32;
|
|
89
|
-
/** AEAD nonce length (96-bit). */
|
|
90
|
-
declare const SEAL_NONCE_LEN = 12;
|
|
91
|
-
/** Poly1305 tag length. */
|
|
92
|
-
declare const SEAL_TAG_LEN = 16;
|
|
93
|
-
/** Explicit SHAKE256 key-commitment length. */
|
|
94
|
-
declare const SEAL_COMMIT_LEN = 32;
|
|
95
|
-
/** Shamir share wire length (`index || value`). */
|
|
96
|
-
declare const SEAL_SHARE_LEN: number;
|
|
97
|
-
/** Scheme selector for the cluster-ML-KEM + Shamir threshold body. */
|
|
98
|
-
declare const CLUSTER_MLKEM_SHAMIR = 3;
|
|
99
|
-
/**
|
|
100
|
-
* Random source for a seal: fills `dest` with random bytes. Production
|
|
101
|
-
* callers pass a CSPRNG-backed source ({@link cryptoRandomSource}); the
|
|
102
|
-
* KAT passes a deterministic source so the seal bytes are reproducible.
|
|
103
|
-
*
|
|
104
|
-
* Each call must consume the source the same way the Rust reference does:
|
|
105
|
-
* the deterministic source models `rand_core`'s `fill_bytes`, which fills
|
|
106
|
-
* in 8-byte chunks (one `u64` per chunk) and discards the unused tail of
|
|
107
|
-
* the final chunk of each call.
|
|
108
|
-
*/
|
|
109
|
-
interface SealRandomSource {
|
|
110
|
-
fillBytes(dest: Uint8Array): void;
|
|
111
|
-
}
|
|
112
|
-
/** CSPRNG-backed source (WebCrypto). The default for production seals. */
|
|
113
|
-
declare function cryptoRandomSource(): SealRandomSource;
|
|
114
|
-
interface CommittingBody {
|
|
115
|
-
nonce: Uint8Array;
|
|
116
|
-
ct: Uint8Array;
|
|
117
|
-
commitment: Uint8Array;
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* `keccak256(domain || cluster_id_le || t || n || concat(idx || ek)...)`.
|
|
121
|
-
* Commits to the exact recipient ek set + order. Operators and wallets
|
|
122
|
-
* MUST compute it identically; this is the single canonical site.
|
|
123
|
-
*
|
|
124
|
-
* keccak256 is taken from the ml-dsa module's hash import to avoid a second
|
|
125
|
-
* keccak dependency; passed in by the caller to keep this module
|
|
126
|
-
* cipher-only.
|
|
127
|
-
*/
|
|
128
|
-
declare function sealRosterHash(keccak256: (input: Uint8Array) => Uint8Array, clusterId: number, t: number, n: number, roster: ReadonlyArray<{
|
|
129
|
-
operatorIndex: number;
|
|
130
|
-
ek: Uint8Array;
|
|
131
|
-
}>): Uint8Array;
|
|
132
|
-
/** One recipient slot in the scheme-3 envelope. */
|
|
133
|
-
interface SealRecipient {
|
|
134
|
-
operatorIndex: number;
|
|
135
|
-
kemCt: Uint8Array;
|
|
136
|
-
wrapped: CommittingBody;
|
|
137
|
-
}
|
|
138
|
-
/**
|
|
139
|
-
* Scheme-3 LythiumSeal envelope - the encrypted-tx body for the
|
|
140
|
-
* cluster-ML-KEM + Shamir threshold path. Bincode-encodes into the bytes
|
|
141
|
-
* that ride inside `EncryptedEnvelope.ciphertext`.
|
|
142
|
-
*/
|
|
143
|
-
interface LythiumSealEnvelope {
|
|
144
|
-
clusterId: number;
|
|
145
|
-
epoch: bigint;
|
|
146
|
-
rosterHash: Uint8Array;
|
|
147
|
-
t: number;
|
|
148
|
-
n: number;
|
|
149
|
-
aeadBody: CommittingBody;
|
|
150
|
-
recipients: SealRecipient[];
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* Bincode-encode (bincode 1.3 defaults: LE fixint, `u64` length prefixes,
|
|
154
|
-
* raw fixed-size arrays) the envelope into the `EncryptedEnvelope.ciphertext`
|
|
155
|
-
* body bytes. Byte-identical to `LythiumSealEnvelope::encode` in mono-core.
|
|
156
|
-
*/
|
|
157
|
-
declare function encodeSealEnvelope(env: LythiumSealEnvelope): Uint8Array;
|
|
158
|
-
/**
|
|
159
|
-
* Seal `plaintext` to the cluster's ordered `recipientEks` (`n` operators)
|
|
160
|
-
* at reconstruction threshold `t`, bound to `(clusterId, epoch,
|
|
161
|
-
* rosterHash)`. Draws a fresh body key for every call (nonce safety rests
|
|
162
|
-
* on body-key freshness, not nonce uniqueness - see the crate invariants),
|
|
163
|
-
* GF(256) Shamir `t`-of-`n` splits it, and ML-KEM-encapsulates one share
|
|
164
|
-
* to each operator's encapsulation key under a KDF-bound member KEK.
|
|
165
|
-
*
|
|
166
|
-
* The result is the `LythiumSealEnvelope` (scheme 3) that nests inside the
|
|
167
|
-
* outer `EncryptedEnvelope.ciphertext`. Recovering the plaintext requires
|
|
168
|
-
* `t` operators to each decapsulate their own slot; no single operator can.
|
|
169
|
-
*
|
|
170
|
-
* @param rng deterministic source for the KAT; defaults to a CSPRNG.
|
|
171
|
-
*/
|
|
172
|
-
declare function sealToCluster(args: {
|
|
173
|
-
plaintext: Uint8Array;
|
|
174
|
-
recipientEks: ReadonlyArray<Uint8Array>;
|
|
175
|
-
t: number;
|
|
176
|
-
clusterId: number;
|
|
177
|
-
epoch: bigint;
|
|
178
|
-
rosterHash: Uint8Array;
|
|
179
|
-
rng?: SealRandomSource;
|
|
180
|
-
}): LythiumSealEnvelope;
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* Client-side scheme-3 LythiumSeal seal path for the wallet/SDK.
|
|
184
|
-
*
|
|
185
|
-
* `getClusterSealKeys` reads the cluster seal roster (per-operator ML-KEM-768
|
|
186
|
-
* encapsulation keys + `(t, n)` + roster hash + epoch). `sealTransaction`
|
|
187
|
-
* turns a signed inner transaction into the scheme-3 `LythiumSealEnvelope`,
|
|
188
|
-
* wraps it in an `EncryptedEnvelope` with the outer ML-DSA-65 signature, and
|
|
189
|
-
* yields the wire bytes mono-core's `lyth_submitEncrypted` accepts.
|
|
190
|
-
*
|
|
191
|
-
* Byte-compatibility with the chain is proven by the cross-language KAT in
|
|
192
|
-
* `tests/lythiumseal-kat.test.ts`.
|
|
193
|
-
*/
|
|
194
|
-
|
|
195
|
-
/** Algorithm tag the node serves for the scheme-3 seal path. */
|
|
196
|
-
declare const CLUSTER_MLKEM_SHAMIR_ALGO = "cluster-mlkem768-shamir";
|
|
197
|
-
/**
|
|
198
|
-
* The cluster seal roster the SDK seals a transaction body to.
|
|
199
|
-
*
|
|
200
|
-
* Built from the `lyth_getClusterSealKeys(clusterId)` RPC response (or read
|
|
201
|
-
* from genesis when that RPC is disabled on the public profile): the ordered
|
|
202
|
-
* per-operator ML-KEM-768 encapsulation keys + the `(t, n)` threshold + the
|
|
203
|
-
* roster hash + the epoch.
|
|
204
|
-
*/
|
|
205
|
-
interface ClusterSealKeys {
|
|
206
|
-
algo: string;
|
|
207
|
-
clusterId: number;
|
|
208
|
-
epoch: bigint;
|
|
209
|
-
/** 32-byte roster hash the seal context binds. */
|
|
210
|
-
rosterHash: Uint8Array;
|
|
211
|
-
/** Reconstruction threshold `t`. */
|
|
212
|
-
t: number;
|
|
213
|
-
/** Total operators `n`. */
|
|
214
|
-
n: number;
|
|
215
|
-
/** Per-operator 1184-byte ML-KEM-768 encapsulation keys, ordered `1..=n`. */
|
|
216
|
-
recipientEks: Uint8Array[];
|
|
217
|
-
}
|
|
218
|
-
/** One operator's entry in a roster source (RPC JSON or genesis). */
|
|
219
|
-
interface ClusterSealKeyEntryInput {
|
|
220
|
-
operatorIndex: number;
|
|
221
|
-
/** `0x`-hex of the operator's 1184-byte ML-KEM-768 encapsulation key. */
|
|
222
|
-
mlKemEk: string;
|
|
223
|
-
}
|
|
224
|
-
/** A cluster seal roster as served by the RPC or read from genesis. */
|
|
225
|
-
interface ClusterSealKeysSource {
|
|
226
|
-
algo?: string;
|
|
227
|
-
clusterId: number;
|
|
228
|
-
epoch: number | string | bigint;
|
|
229
|
-
/** `0x`-hex of the 32-byte roster hash (optional; recomputed + verified). */
|
|
230
|
-
rosterHash?: string;
|
|
231
|
-
t: number;
|
|
232
|
-
n: number;
|
|
233
|
-
roster: ClusterSealKeyEntryInput[];
|
|
234
|
-
}
|
|
235
|
-
/**
|
|
236
|
-
* Normalize a roster source into the typed {@link ClusterSealKeys} the SDK
|
|
237
|
-
* seals against. The roster hash is RECOMPUTED from the ordered ek set via
|
|
238
|
-
* the canonical `seal_roster_hash` and, when the source carries one, the
|
|
239
|
-
* recomputed value must match - so a wallet can never seal under a roster
|
|
240
|
-
* hash that does not commit to the exact recipient set it is sealing to.
|
|
241
|
-
*
|
|
242
|
-
* @throws if the roster is empty, an ek has the wrong length, the operator
|
|
243
|
-
* indices are not the contiguous `1..=n` order, the threshold is out of
|
|
244
|
-
* `2 <= t <= n`, or a supplied roster hash does not match the recomputed one.
|
|
245
|
-
*/
|
|
246
|
-
declare function parseClusterSealKeys(source: ClusterSealKeysSource): ClusterSealKeys;
|
|
247
|
-
/**
|
|
248
|
-
* Fetch the cluster seal roster from a running node via
|
|
249
|
-
* `lyth_getClusterSealKeys(clusterId)`.
|
|
250
|
-
*
|
|
251
|
-
* NOTE: this RPC is DISABLED on the public node profile. When it returns
|
|
252
|
-
* "method not found" / "unavailable", read the roster from genesis instead
|
|
253
|
-
* and pass it through {@link parseClusterSealKeys} - the roster lives in the
|
|
254
|
-
* genesis `[[clusters.members]]` `seal_ek` fields, which is exactly what the
|
|
255
|
-
* RPC would otherwise serve.
|
|
256
|
-
*
|
|
257
|
-
* @throws if the RPC is unavailable (carry the roster as input instead) or
|
|
258
|
-
* the served roster does not validate.
|
|
259
|
-
*/
|
|
260
|
-
declare function getClusterSealKeys(client: RpcClient, clusterId?: number): Promise<ClusterSealKeys>;
|
|
261
|
-
/** A built scheme-3 encrypted submission, ready for `lyth_submitEncrypted`. */
|
|
262
|
-
interface SealedSubmission {
|
|
263
|
-
/** Bincode `EncryptedEnvelope` wire bytes, `0x`-prefixed hex. */
|
|
264
|
-
envelopeWireHex: string;
|
|
265
|
-
/** Bincode `EncryptedEnvelope` wire bytes. */
|
|
266
|
-
envelopeWireBytes: Uint8Array;
|
|
267
|
-
/** Length of the inner scheme-3 ciphertext body in bytes. */
|
|
268
|
-
ciphertextBytes: number;
|
|
269
|
-
}
|
|
270
|
-
/**
|
|
271
|
-
* Seal a signed inner transaction to the cluster and wrap it in an
|
|
272
|
-
* `EncryptedEnvelope` with the outer ML-DSA-65 signature.
|
|
273
|
-
*
|
|
274
|
-
* `signedTxBincode` is the bincode `SignedTransaction` wire bytes (the body
|
|
275
|
-
* `mesh_submitTx` would otherwise carry in the clear). `aad` is the
|
|
276
|
-
* authenticated envelope header; per Law §3.6 / R3-H08 its fee fields MUST
|
|
277
|
-
* mirror the inner tx's fee fields exactly, so the chain's `verify_inner_match`
|
|
278
|
-
* passes on reveal - the caller is responsible for building it from the same
|
|
279
|
-
* fields it signed.
|
|
280
|
-
*
|
|
281
|
-
* The outer signature is taken over the canonical preimage
|
|
282
|
-
* `keccak256(bincode(aad) || ciphertext || bincode(hint) || sender_pubkey)`,
|
|
283
|
-
* identical to mono-core's `EncryptedEnvelope::signed_digest`.
|
|
284
|
-
*
|
|
285
|
-
* @param rng deterministic source for the KAT; defaults to a CSPRNG.
|
|
286
|
-
*/
|
|
287
|
-
declare function sealTransaction(args: {
|
|
288
|
-
signedTxBincode: Uint8Array;
|
|
289
|
-
clusterSealKeys: ClusterSealKeys;
|
|
290
|
-
aad: NonceAad;
|
|
291
|
-
senderAddress: Uint8Array;
|
|
292
|
-
senderPubkey: Uint8Array;
|
|
293
|
-
signOuterDigest: (digest: Uint8Array) => Promise<Uint8Array> | Uint8Array;
|
|
294
|
-
rng?: SealRandomSource;
|
|
295
|
-
}): Promise<SealedSubmission>;
|
|
296
|
-
/**
|
|
297
|
-
* Submit a built scheme-3 encrypted envelope through `lyth_submitEncrypted`.
|
|
298
|
-
*
|
|
299
|
-
* @returns the mempool tx hash the node assigns on admission.
|
|
300
|
-
*/
|
|
301
|
-
declare function submitSealedTransaction(client: RpcClient, submission: SealedSubmission): Promise<string>;
|
|
302
|
-
|
|
303
|
-
export { BincodeWriter, CLUSTER_MLKEM_SHAMIR, CLUSTER_MLKEM_SHAMIR_ALGO, type ClusterSealKeyEntryInput, type ClusterSealKeys, type ClusterSealKeysSource, type LythiumSealEnvelope, MlDsa65Backend, NonceAad, PQM1_ALGO_TAG_FALCON512_RESERVED, PQM1_ALGO_TAG_MLDSA65, PQM1_ALGO_TAG_MLDSA87_RESERVED, PQM1_ALGO_TAG_SLHDSA128S_RESERVED, PQM1_ENTROPY_LEN, PQM1_PAYLOAD_LEN, PQM1_V1_MLDSA65_DOMAIN_TAG, PQM1_V1_MNEMONIC_WORDS, PQM1_VERSION_V1, Pqm1Error, type Pqm1ErrorKind, type Pqm1Payload, type Pqm1Rng, SEAL_COMMIT_LEN, SEAL_DK_LEN, SEAL_EK_LEN, SEAL_KEM_CT_LEN, SEAL_KEM_SEED_LEN, SEAL_KEY_LEN, SEAL_NONCE_LEN, SEAL_SHARE_LEN, SEAL_TAG_LEN, type SealRandomSource, type SealRecipient, type SealedSubmission, assemblePqm1Payload, bytesToHex, concatBytes, cryptoRandomSource, derivePqm1MlDsa65SeedFromPayload, encodeSealEnvelope, expectBytes, generatePqm1Mnemonic, getClusterSealKeys, hexToBytes, parseClusterSealKeys, parsePqm1Payload, pqm1MnemonicToAddress, pqm1MnemonicToMlDsa65Backend, pqm1MnemonicToMlDsa65Seed, pqm1MnemonicToPayload, pqm1PayloadToMnemonic, sealRosterHash, sealToCluster, sealTransaction, submitSealedTransaction };
|
|
54
|
+
export { BincodeWriter, MlDsa65Backend, PQM1_ALGO_TAG_FALCON512_RESERVED, PQM1_ALGO_TAG_MLDSA65, PQM1_ALGO_TAG_MLDSA87_RESERVED, PQM1_ALGO_TAG_SLHDSA128S_RESERVED, PQM1_ENTROPY_LEN, PQM1_PAYLOAD_LEN, PQM1_V1_MLDSA65_DOMAIN_TAG, PQM1_V1_MNEMONIC_WORDS, PQM1_VERSION_V1, Pqm1Error, type Pqm1ErrorKind, type Pqm1Payload, type Pqm1Rng, assemblePqm1Payload, bytesToHex, concatBytes, derivePqm1MlDsa65SeedFromPayload, expectBytes, generatePqm1Mnemonic, hexToBytes, parsePqm1Payload, pqm1MnemonicToAddress, pqm1MnemonicToMlDsa65Backend, pqm1MnemonicToMlDsa65Seed, pqm1MnemonicToPayload, pqm1PayloadToMnemonic };
|
package/dist/crypto/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { I as MlDsa65Backend
|
|
2
|
-
export {
|
|
1
|
+
import { I as MlDsa65Backend } from '../submission-Cc9r1eqX.js';
|
|
2
|
+
export { j0 as ADDRESS_DERIVATION_DOMAIN, j1 as CLUSTER_MLKEM_SHAMIR, j2 as CLUSTER_MLKEM_SHAMIR_ALGO, j3 as ClusterSealKeyEntryInput, j4 as ClusterSealKeys, j5 as ClusterSealKeysSource, j6 as DKG_AEAD_TAG_LEN, j7 as DKG_NONCE_LEN, j8 as DecryptHint, j9 as ENCRYPTED_SUBMISSION_UNAVAILABLE_MESSAGE, ja as ENUM_VARIANT_INDEX_ML_DSA_65, jb as EncryptedEnvelope, jc as EncryptedSubmission, E as EncryptionKey, jd as JsonRpcCallClient, je as LythiumSealEnvelope, jf as ML_DSA_65_PUBLIC_KEY_LEN, jg as ML_DSA_65_SEED_LEN, jh as ML_DSA_65_SIGNATURE_LEN, ji as ML_DSA_65_SIGNING_KEY_LEN, jj as ML_KEM_768_CIPHERTEXT_LEN, jk as ML_KEM_768_ENCAPSULATION_KEY_LEN, jl as ML_KEM_768_SHARED_SECRET_LEN, F as MempoolClass, D as NativeEvmTxFields, jm as NativeTxExtension, jn as NativeTxExtensionDescriptor, jo as NativeTxExtensionLike, jp as NonceAad, jq as PlaintextSubmission, jr as SEAL_COMMIT_LEN, js as SEAL_DK_LEN, jt as SEAL_EK_LEN, ju as SEAL_KEM_CT_LEN, jv as SEAL_KEM_SEED_LEN, jw as SEAL_KEY_LEN, jx as SEAL_NONCE_LEN, jy as SEAL_SHARE_LEN, jz as SEAL_TAG_LEN, jA as STANDARD_ALGO_NUMBER_ML_DSA_65, jB as SealRandomSource, jC as SealRecipient, jD as SealedSubmission, jE as bincodeDecryptHint, jF as bincodeEncryptedEnvelope, jG as bincodeNonceAad, jH as bincodeSignedTransaction, jI as buildEncryptedEnvelope, jJ as buildEncryptedSubmission, jK as buildPlaintextSubmission, jL as cryptoRandomSource, jM as encodeMlDsa65Opaque, jN as encodeSealEnvelope, jO as encodeTransactionForHash, jP as encryptInnerTx, jQ as fetchEncryptionKey, jR as getClusterSealKeys, jS as mlDsa65AddressBytes, jT as mlDsa65AddressFromPublicKey, jU as outerSigDigest, jV as parseClusterSealKeys, jW as sealRosterHash, jX as sealToCluster, jY as sealTransaction, jZ as submitEncryptedEnvelope, j_ as submitPlaintextTransaction, j$ as submitSealedTransaction, k0 as submitTransactionWithPrivacy } from '../submission-Cc9r1eqX.js';
|
|
3
3
|
|
|
4
4
|
declare class BincodeWriter {
|
|
5
5
|
#private;
|
|
@@ -51,253 +51,4 @@ declare function pqm1MnemonicToMlDsa65Backend(mnemonic: string): MlDsa65Backend;
|
|
|
51
51
|
declare function pqm1MnemonicToAddress(mnemonic: string): string;
|
|
52
52
|
declare function generatePqm1Mnemonic(rng?: Pqm1Rng): string;
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
* LythiumSeal scheme-3 client-side seal primitive.
|
|
56
|
-
*
|
|
57
|
-
* Post-quantum cluster-threshold encrypted-mempool sealing:
|
|
58
|
-
* cluster-ML-KEM-768 (FIPS-203) + information-theoretic GF(256) Shamir
|
|
59
|
-
* `t`-of-`n` + committing ChaCha20-Poly1305 (with an explicit SHAKE256
|
|
60
|
-
* key-commitment). A signed transaction body is sealed to a committee of
|
|
61
|
-
* `n` operators such that any `t` of them, each holding only its own
|
|
62
|
-
* ML-KEM decapsulation key, must cooperate to recover the plaintext. No
|
|
63
|
-
* single operator (and no minority of `< t`) can read the body.
|
|
64
|
-
*
|
|
65
|
-
* This is a byte-exact port of the standalone `lythiumseal` Rust crate
|
|
66
|
-
* (github.com/monolythium/lythiumseal) plus the chain-side
|
|
67
|
-
* `LythiumSealEnvelope` wire shape from `mono-core`'s mempool
|
|
68
|
-
* (`seal_to_cluster`). Byte-compatibility is proven by a cross-language
|
|
69
|
-
* KAT (`tests/lythiumseal-kat.test.ts`) against vectors generated from the
|
|
70
|
-
* Rust reference: the same fixed roster + deterministic draw order
|
|
71
|
-
* reproduces the exact envelope bincode bytes the chain accepts, and a
|
|
72
|
-
* Rust-sealed envelope round-trips through the TS decoder.
|
|
73
|
-
*
|
|
74
|
-
* The cryptography is standardized: ML-KEM-768 from `@noble/post-quantum`,
|
|
75
|
-
* ChaCha20-Poly1305 from `@noble/ciphers`, and SHAKE256 from
|
|
76
|
-
* `@noble/hashes`. The GF(256) Shamir layer is the AES field (reduction
|
|
77
|
-
* polynomial 0x11b) implemented in-module to match the crate exactly.
|
|
78
|
-
*/
|
|
79
|
-
/** ML-KEM-768 encapsulation-key byte length. */
|
|
80
|
-
declare const SEAL_EK_LEN = 1184;
|
|
81
|
-
/** ML-KEM-768 decapsulation-key byte length. */
|
|
82
|
-
declare const SEAL_DK_LEN = 2400;
|
|
83
|
-
/** ML-KEM-768 ciphertext byte length. */
|
|
84
|
-
declare const SEAL_KEM_CT_LEN = 1088;
|
|
85
|
-
/** ML-KEM-768 keygen seed length (`d || z`, FIPS-203). */
|
|
86
|
-
declare const SEAL_KEM_SEED_LEN = 64;
|
|
87
|
-
/** AEAD key length (ChaCha20-Poly1305 / body key). */
|
|
88
|
-
declare const SEAL_KEY_LEN = 32;
|
|
89
|
-
/** AEAD nonce length (96-bit). */
|
|
90
|
-
declare const SEAL_NONCE_LEN = 12;
|
|
91
|
-
/** Poly1305 tag length. */
|
|
92
|
-
declare const SEAL_TAG_LEN = 16;
|
|
93
|
-
/** Explicit SHAKE256 key-commitment length. */
|
|
94
|
-
declare const SEAL_COMMIT_LEN = 32;
|
|
95
|
-
/** Shamir share wire length (`index || value`). */
|
|
96
|
-
declare const SEAL_SHARE_LEN: number;
|
|
97
|
-
/** Scheme selector for the cluster-ML-KEM + Shamir threshold body. */
|
|
98
|
-
declare const CLUSTER_MLKEM_SHAMIR = 3;
|
|
99
|
-
/**
|
|
100
|
-
* Random source for a seal: fills `dest` with random bytes. Production
|
|
101
|
-
* callers pass a CSPRNG-backed source ({@link cryptoRandomSource}); the
|
|
102
|
-
* KAT passes a deterministic source so the seal bytes are reproducible.
|
|
103
|
-
*
|
|
104
|
-
* Each call must consume the source the same way the Rust reference does:
|
|
105
|
-
* the deterministic source models `rand_core`'s `fill_bytes`, which fills
|
|
106
|
-
* in 8-byte chunks (one `u64` per chunk) and discards the unused tail of
|
|
107
|
-
* the final chunk of each call.
|
|
108
|
-
*/
|
|
109
|
-
interface SealRandomSource {
|
|
110
|
-
fillBytes(dest: Uint8Array): void;
|
|
111
|
-
}
|
|
112
|
-
/** CSPRNG-backed source (WebCrypto). The default for production seals. */
|
|
113
|
-
declare function cryptoRandomSource(): SealRandomSource;
|
|
114
|
-
interface CommittingBody {
|
|
115
|
-
nonce: Uint8Array;
|
|
116
|
-
ct: Uint8Array;
|
|
117
|
-
commitment: Uint8Array;
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* `keccak256(domain || cluster_id_le || t || n || concat(idx || ek)...)`.
|
|
121
|
-
* Commits to the exact recipient ek set + order. Operators and wallets
|
|
122
|
-
* MUST compute it identically; this is the single canonical site.
|
|
123
|
-
*
|
|
124
|
-
* keccak256 is taken from the ml-dsa module's hash import to avoid a second
|
|
125
|
-
* keccak dependency; passed in by the caller to keep this module
|
|
126
|
-
* cipher-only.
|
|
127
|
-
*/
|
|
128
|
-
declare function sealRosterHash(keccak256: (input: Uint8Array) => Uint8Array, clusterId: number, t: number, n: number, roster: ReadonlyArray<{
|
|
129
|
-
operatorIndex: number;
|
|
130
|
-
ek: Uint8Array;
|
|
131
|
-
}>): Uint8Array;
|
|
132
|
-
/** One recipient slot in the scheme-3 envelope. */
|
|
133
|
-
interface SealRecipient {
|
|
134
|
-
operatorIndex: number;
|
|
135
|
-
kemCt: Uint8Array;
|
|
136
|
-
wrapped: CommittingBody;
|
|
137
|
-
}
|
|
138
|
-
/**
|
|
139
|
-
* Scheme-3 LythiumSeal envelope - the encrypted-tx body for the
|
|
140
|
-
* cluster-ML-KEM + Shamir threshold path. Bincode-encodes into the bytes
|
|
141
|
-
* that ride inside `EncryptedEnvelope.ciphertext`.
|
|
142
|
-
*/
|
|
143
|
-
interface LythiumSealEnvelope {
|
|
144
|
-
clusterId: number;
|
|
145
|
-
epoch: bigint;
|
|
146
|
-
rosterHash: Uint8Array;
|
|
147
|
-
t: number;
|
|
148
|
-
n: number;
|
|
149
|
-
aeadBody: CommittingBody;
|
|
150
|
-
recipients: SealRecipient[];
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* Bincode-encode (bincode 1.3 defaults: LE fixint, `u64` length prefixes,
|
|
154
|
-
* raw fixed-size arrays) the envelope into the `EncryptedEnvelope.ciphertext`
|
|
155
|
-
* body bytes. Byte-identical to `LythiumSealEnvelope::encode` in mono-core.
|
|
156
|
-
*/
|
|
157
|
-
declare function encodeSealEnvelope(env: LythiumSealEnvelope): Uint8Array;
|
|
158
|
-
/**
|
|
159
|
-
* Seal `plaintext` to the cluster's ordered `recipientEks` (`n` operators)
|
|
160
|
-
* at reconstruction threshold `t`, bound to `(clusterId, epoch,
|
|
161
|
-
* rosterHash)`. Draws a fresh body key for every call (nonce safety rests
|
|
162
|
-
* on body-key freshness, not nonce uniqueness - see the crate invariants),
|
|
163
|
-
* GF(256) Shamir `t`-of-`n` splits it, and ML-KEM-encapsulates one share
|
|
164
|
-
* to each operator's encapsulation key under a KDF-bound member KEK.
|
|
165
|
-
*
|
|
166
|
-
* The result is the `LythiumSealEnvelope` (scheme 3) that nests inside the
|
|
167
|
-
* outer `EncryptedEnvelope.ciphertext`. Recovering the plaintext requires
|
|
168
|
-
* `t` operators to each decapsulate their own slot; no single operator can.
|
|
169
|
-
*
|
|
170
|
-
* @param rng deterministic source for the KAT; defaults to a CSPRNG.
|
|
171
|
-
*/
|
|
172
|
-
declare function sealToCluster(args: {
|
|
173
|
-
plaintext: Uint8Array;
|
|
174
|
-
recipientEks: ReadonlyArray<Uint8Array>;
|
|
175
|
-
t: number;
|
|
176
|
-
clusterId: number;
|
|
177
|
-
epoch: bigint;
|
|
178
|
-
rosterHash: Uint8Array;
|
|
179
|
-
rng?: SealRandomSource;
|
|
180
|
-
}): LythiumSealEnvelope;
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* Client-side scheme-3 LythiumSeal seal path for the wallet/SDK.
|
|
184
|
-
*
|
|
185
|
-
* `getClusterSealKeys` reads the cluster seal roster (per-operator ML-KEM-768
|
|
186
|
-
* encapsulation keys + `(t, n)` + roster hash + epoch). `sealTransaction`
|
|
187
|
-
* turns a signed inner transaction into the scheme-3 `LythiumSealEnvelope`,
|
|
188
|
-
* wraps it in an `EncryptedEnvelope` with the outer ML-DSA-65 signature, and
|
|
189
|
-
* yields the wire bytes mono-core's `lyth_submitEncrypted` accepts.
|
|
190
|
-
*
|
|
191
|
-
* Byte-compatibility with the chain is proven by the cross-language KAT in
|
|
192
|
-
* `tests/lythiumseal-kat.test.ts`.
|
|
193
|
-
*/
|
|
194
|
-
|
|
195
|
-
/** Algorithm tag the node serves for the scheme-3 seal path. */
|
|
196
|
-
declare const CLUSTER_MLKEM_SHAMIR_ALGO = "cluster-mlkem768-shamir";
|
|
197
|
-
/**
|
|
198
|
-
* The cluster seal roster the SDK seals a transaction body to.
|
|
199
|
-
*
|
|
200
|
-
* Built from the `lyth_getClusterSealKeys(clusterId)` RPC response (or read
|
|
201
|
-
* from genesis when that RPC is disabled on the public profile): the ordered
|
|
202
|
-
* per-operator ML-KEM-768 encapsulation keys + the `(t, n)` threshold + the
|
|
203
|
-
* roster hash + the epoch.
|
|
204
|
-
*/
|
|
205
|
-
interface ClusterSealKeys {
|
|
206
|
-
algo: string;
|
|
207
|
-
clusterId: number;
|
|
208
|
-
epoch: bigint;
|
|
209
|
-
/** 32-byte roster hash the seal context binds. */
|
|
210
|
-
rosterHash: Uint8Array;
|
|
211
|
-
/** Reconstruction threshold `t`. */
|
|
212
|
-
t: number;
|
|
213
|
-
/** Total operators `n`. */
|
|
214
|
-
n: number;
|
|
215
|
-
/** Per-operator 1184-byte ML-KEM-768 encapsulation keys, ordered `1..=n`. */
|
|
216
|
-
recipientEks: Uint8Array[];
|
|
217
|
-
}
|
|
218
|
-
/** One operator's entry in a roster source (RPC JSON or genesis). */
|
|
219
|
-
interface ClusterSealKeyEntryInput {
|
|
220
|
-
operatorIndex: number;
|
|
221
|
-
/** `0x`-hex of the operator's 1184-byte ML-KEM-768 encapsulation key. */
|
|
222
|
-
mlKemEk: string;
|
|
223
|
-
}
|
|
224
|
-
/** A cluster seal roster as served by the RPC or read from genesis. */
|
|
225
|
-
interface ClusterSealKeysSource {
|
|
226
|
-
algo?: string;
|
|
227
|
-
clusterId: number;
|
|
228
|
-
epoch: number | string | bigint;
|
|
229
|
-
/** `0x`-hex of the 32-byte roster hash (optional; recomputed + verified). */
|
|
230
|
-
rosterHash?: string;
|
|
231
|
-
t: number;
|
|
232
|
-
n: number;
|
|
233
|
-
roster: ClusterSealKeyEntryInput[];
|
|
234
|
-
}
|
|
235
|
-
/**
|
|
236
|
-
* Normalize a roster source into the typed {@link ClusterSealKeys} the SDK
|
|
237
|
-
* seals against. The roster hash is RECOMPUTED from the ordered ek set via
|
|
238
|
-
* the canonical `seal_roster_hash` and, when the source carries one, the
|
|
239
|
-
* recomputed value must match - so a wallet can never seal under a roster
|
|
240
|
-
* hash that does not commit to the exact recipient set it is sealing to.
|
|
241
|
-
*
|
|
242
|
-
* @throws if the roster is empty, an ek has the wrong length, the operator
|
|
243
|
-
* indices are not the contiguous `1..=n` order, the threshold is out of
|
|
244
|
-
* `2 <= t <= n`, or a supplied roster hash does not match the recomputed one.
|
|
245
|
-
*/
|
|
246
|
-
declare function parseClusterSealKeys(source: ClusterSealKeysSource): ClusterSealKeys;
|
|
247
|
-
/**
|
|
248
|
-
* Fetch the cluster seal roster from a running node via
|
|
249
|
-
* `lyth_getClusterSealKeys(clusterId)`.
|
|
250
|
-
*
|
|
251
|
-
* NOTE: this RPC is DISABLED on the public node profile. When it returns
|
|
252
|
-
* "method not found" / "unavailable", read the roster from genesis instead
|
|
253
|
-
* and pass it through {@link parseClusterSealKeys} - the roster lives in the
|
|
254
|
-
* genesis `[[clusters.members]]` `seal_ek` fields, which is exactly what the
|
|
255
|
-
* RPC would otherwise serve.
|
|
256
|
-
*
|
|
257
|
-
* @throws if the RPC is unavailable (carry the roster as input instead) or
|
|
258
|
-
* the served roster does not validate.
|
|
259
|
-
*/
|
|
260
|
-
declare function getClusterSealKeys(client: RpcClient, clusterId?: number): Promise<ClusterSealKeys>;
|
|
261
|
-
/** A built scheme-3 encrypted submission, ready for `lyth_submitEncrypted`. */
|
|
262
|
-
interface SealedSubmission {
|
|
263
|
-
/** Bincode `EncryptedEnvelope` wire bytes, `0x`-prefixed hex. */
|
|
264
|
-
envelopeWireHex: string;
|
|
265
|
-
/** Bincode `EncryptedEnvelope` wire bytes. */
|
|
266
|
-
envelopeWireBytes: Uint8Array;
|
|
267
|
-
/** Length of the inner scheme-3 ciphertext body in bytes. */
|
|
268
|
-
ciphertextBytes: number;
|
|
269
|
-
}
|
|
270
|
-
/**
|
|
271
|
-
* Seal a signed inner transaction to the cluster and wrap it in an
|
|
272
|
-
* `EncryptedEnvelope` with the outer ML-DSA-65 signature.
|
|
273
|
-
*
|
|
274
|
-
* `signedTxBincode` is the bincode `SignedTransaction` wire bytes (the body
|
|
275
|
-
* `mesh_submitTx` would otherwise carry in the clear). `aad` is the
|
|
276
|
-
* authenticated envelope header; per Law §3.6 / R3-H08 its fee fields MUST
|
|
277
|
-
* mirror the inner tx's fee fields exactly, so the chain's `verify_inner_match`
|
|
278
|
-
* passes on reveal - the caller is responsible for building it from the same
|
|
279
|
-
* fields it signed.
|
|
280
|
-
*
|
|
281
|
-
* The outer signature is taken over the canonical preimage
|
|
282
|
-
* `keccak256(bincode(aad) || ciphertext || bincode(hint) || sender_pubkey)`,
|
|
283
|
-
* identical to mono-core's `EncryptedEnvelope::signed_digest`.
|
|
284
|
-
*
|
|
285
|
-
* @param rng deterministic source for the KAT; defaults to a CSPRNG.
|
|
286
|
-
*/
|
|
287
|
-
declare function sealTransaction(args: {
|
|
288
|
-
signedTxBincode: Uint8Array;
|
|
289
|
-
clusterSealKeys: ClusterSealKeys;
|
|
290
|
-
aad: NonceAad;
|
|
291
|
-
senderAddress: Uint8Array;
|
|
292
|
-
senderPubkey: Uint8Array;
|
|
293
|
-
signOuterDigest: (digest: Uint8Array) => Promise<Uint8Array> | Uint8Array;
|
|
294
|
-
rng?: SealRandomSource;
|
|
295
|
-
}): Promise<SealedSubmission>;
|
|
296
|
-
/**
|
|
297
|
-
* Submit a built scheme-3 encrypted envelope through `lyth_submitEncrypted`.
|
|
298
|
-
*
|
|
299
|
-
* @returns the mempool tx hash the node assigns on admission.
|
|
300
|
-
*/
|
|
301
|
-
declare function submitSealedTransaction(client: RpcClient, submission: SealedSubmission): Promise<string>;
|
|
302
|
-
|
|
303
|
-
export { BincodeWriter, CLUSTER_MLKEM_SHAMIR, CLUSTER_MLKEM_SHAMIR_ALGO, type ClusterSealKeyEntryInput, type ClusterSealKeys, type ClusterSealKeysSource, type LythiumSealEnvelope, MlDsa65Backend, NonceAad, PQM1_ALGO_TAG_FALCON512_RESERVED, PQM1_ALGO_TAG_MLDSA65, PQM1_ALGO_TAG_MLDSA87_RESERVED, PQM1_ALGO_TAG_SLHDSA128S_RESERVED, PQM1_ENTROPY_LEN, PQM1_PAYLOAD_LEN, PQM1_V1_MLDSA65_DOMAIN_TAG, PQM1_V1_MNEMONIC_WORDS, PQM1_VERSION_V1, Pqm1Error, type Pqm1ErrorKind, type Pqm1Payload, type Pqm1Rng, SEAL_COMMIT_LEN, SEAL_DK_LEN, SEAL_EK_LEN, SEAL_KEM_CT_LEN, SEAL_KEM_SEED_LEN, SEAL_KEY_LEN, SEAL_NONCE_LEN, SEAL_SHARE_LEN, SEAL_TAG_LEN, type SealRandomSource, type SealRecipient, type SealedSubmission, assemblePqm1Payload, bytesToHex, concatBytes, cryptoRandomSource, derivePqm1MlDsa65SeedFromPayload, encodeSealEnvelope, expectBytes, generatePqm1Mnemonic, getClusterSealKeys, hexToBytes, parseClusterSealKeys, parsePqm1Payload, pqm1MnemonicToAddress, pqm1MnemonicToMlDsa65Backend, pqm1MnemonicToMlDsa65Seed, pqm1MnemonicToPayload, pqm1PayloadToMnemonic, sealRosterHash, sealToCluster, sealTransaction, submitSealedTransaction };
|
|
54
|
+
export { BincodeWriter, MlDsa65Backend, PQM1_ALGO_TAG_FALCON512_RESERVED, PQM1_ALGO_TAG_MLDSA65, PQM1_ALGO_TAG_MLDSA87_RESERVED, PQM1_ALGO_TAG_SLHDSA128S_RESERVED, PQM1_ENTROPY_LEN, PQM1_PAYLOAD_LEN, PQM1_V1_MLDSA65_DOMAIN_TAG, PQM1_V1_MNEMONIC_WORDS, PQM1_VERSION_V1, Pqm1Error, type Pqm1ErrorKind, type Pqm1Payload, type Pqm1Rng, assemblePqm1Payload, bytesToHex, concatBytes, derivePqm1MlDsa65SeedFromPayload, expectBytes, generatePqm1Mnemonic, hexToBytes, parsePqm1Payload, pqm1MnemonicToAddress, pqm1MnemonicToMlDsa65Backend, pqm1MnemonicToMlDsa65Seed, pqm1MnemonicToPayload, pqm1PayloadToMnemonic };
|