| Safe Haskell | Safe-Inferred |
|---|---|
| Language | GHC2021 |
Hydra.Contract.KZGTrustedSetup
Description
KZG trusted setup parameters for Hydra's accumulator-based partial fanout.
Background
Hydra's partial fanout uses KZG polynomial commitments to prove on-chain that a distributed batch of UTxOs is a genuine subset of the UTxOs committed in the Closed head datum. The accumulator polynomial encodes all snapshot UTxOs as roots:
A(X) = ∏ (X − sᵢ) where sᵢ = hash(TxOutᵢ)
The accumulator commitment is A(τ)·G1 — a single G1 point (48 bytes) stored
in the Closed datum. The membership proof for a distributed subset S is the
quotient Q(X) = A(X) / P_S(X) committed as Q(τ)·G1. The on-chain validator
verifies the pairing identity:
e(A(τ)·G1, G2) = e(Q(τ)·G1, P_S(τ)·G2)
where P_S(τ)·G2 is computed on-chain via a G2 MSM using the on-chain G2 CRS.
The Trusted Setup
Computing A(τ)·G1 and Q(τ)·G1 off-chain, and P_S(τ)·G2 on-chain, all
require the same secret τ (powers of tau). We embed the __EIP-4844 KZG
trusted setup__ produced by the Ethereum KZG ceremony (2023):
- Source: https://github.com/ethereum/kzg-ceremony-verifier/tree/master/output_setups
- Ceremony: https://ceremony.ethereum.org/
- ~140,000 independent participants; secure as long as one destroyed their secret
- We use the
g1_monomialandg2_monomialkeys (notg1_lagrange, which is for Ethereum blob commitments and is unsuitable here)
The setup provides:
- 4096 G1 points
[G1, τ·G1, ..., τ^4095·G1]— used off-chain to build the accumulator commitment and membership proofs - 65 G2 points
[G2, τ·G2, ..., τ^64·G2]— used as the on-chain verification CRS (G2 MSM to evaluateP_S(τ)·G2)
Accumulator size limit
The accumulator polynomial has degree n (one root per UTxO). Computing A(τ)·G1
off-chain needs n+1 G1 points. EIP-4844 provides 4096 G1 points, so a head can
hold up to 4095 UTxOs. This is enforced by maxAccumulatorSize.
The on-chain G2 CRS only needs batch-size-many points per partial fanout step,
so the 65 G2 points do not constrain the accumulator size.
Synopsis
- data KZGSetupError
- = IntegrityCheckFailed {
- expectedHash :: Text
- actualHash :: Text
- | JsonDecodeFailed
- | JsonParseFailed {
- parseError :: Text
- | InvalidG1Point {
- hexPoint :: Text
- | InvalidG2Point {
- hexPoint :: Text
- = IntegrityCheckFailed {
- warmup :: Either KZGSetupError Int
- g1Points :: Either KZGSetupError [Point1]
- g2Points :: Either KZGSetupError [Point2]
- g1BuiltinPoints :: Either KZGSetupError [BuiltinBLS12_381_G1_Element]
- g2BuiltinPoints :: Either KZGSetupError [BuiltinBLS12_381_G2_Element]
- maxAccumulatorSize :: Int
- maxFanoutBatchSize :: Int
- defaultItems :: Int
- canonicalG2Points :: [BuiltinBLS12_381_G2_Element]
Documentation
data KZGSetupError Source #
Errors that can occur when loading the embedded KZG trusted setup.
In practice these should never occur — the trusted setup JSON is embedded at
compile time and its integrity is validated by the test suite. A Left here
would indicate binary tampering (IntegrityCheckFailed) or a corrupted
build artefact.
Constructors
| IntegrityCheckFailed | SHA-256 digest of the embedded file does not match the known-good value. |
Fields
| |
| JsonDecodeFailed | The embedded bytes could not be decoded as JSON at all. |
| JsonParseFailed | The JSON decoded but failed the structural parser (missing keys etc.). |
Fields
| |
| InvalidG1Point | A G1 point hex string could not be hex-decoded or BLS-decompressed. |
Fields
| |
| InvalidG2Point | A G2 point hex string could not be hex-decoded or BLS-decompressed. |
Fields
| |
Instances
warmup :: Either KZGSetupError Int Source #
Force the whole embedded trusted setup into memory, yielding the number of G1 points loaded.
Both halves are forced: the G1 CRS the off-chain commitment path consumes,
and the G2 CRS behind canonicalG2Points, which the head validator binds.
A caller gets a corrupt setup as a Left here rather than as the error
those two would otherwise raise from pure code, mid-session.
The forcing lives in this module on purpose. g1Points currently
decompresses every point just to decide between Left and Right, so any
WHNF happens to do the work — but that is a property of the
representation, not a promise. Should either list become a lazy structure,
this is the one place obliged to keep forcing, rather than a caller's
length silently degenerating into a spine walk.
g1Points :: Either KZGSetupError [Point1] Source #
G1 powers of tau [G1, τ·G1, ..., τ^4095·G1] from the EIP-4844 ceremony (monomial form). 4096 points; used off-chain to build accumulator commitments and membership proofs.
g2Points :: Either KZGSetupError [Point2] Source #
G2 powers of tau [G2, τ·G2, ..., τ^64·G2] from the EIP-4844 ceremony (monomial form).
65 points; used as the on-chain verification CRS (G2 MSM to evaluate P_S(τ)·G2).
g1BuiltinPoints :: Either KZGSetupError [BuiltinBLS12_381_G1_Element] Source #
G1 points as Plutus built-in type, for use in off-chain accumulator commitment.
Derived from g1Points by re-compressing to bytes; shares the same parsed data.
g2BuiltinPoints :: Either KZGSetupError [BuiltinBLS12_381_G2_Element] Source #
G2 points as Plutus built-in type, for use in on-chain verification CRS.
Derived from g2Points by re-compressing to bytes; shares the same parsed data.
maxAccumulatorSize :: Int Source #
Maximum accumulator element count supported by the currently embedded G1 CRS. The EIP-4844 setup provides exactly 4096 G1 monomial points [G1, τ·G1, ..., τ^4095·G1], so the accumulator supports up to 4095 elements (n elements need n+1 G1 points).
maxFanoutBatchSize :: Int Source #
Theoretical upper bound on partial fanout batch size, derived from the embedded EIP-4844 trusted setup: 65 G2 monomial points give room for a polynomial of degree 64 (one (X - sᵢ) factor per fanned-out element).
NOTE: this is the ceiling implied by the trusted-setup file, not the
deployed cap. The on-chain CRS UTxO only embeds the first
defaultItems G2 points, so the production batch
limit is currently defaultItems - 1. Raising the deployed cap requires
re-publishing the CRS UTxO with more G2 points (bounded above by this
value).
defaultItems :: Int Source #
Number of G2 monomial points published in the on-chain CRS reference UTxO
(see createCRSG2Datum), hence the size of the canonical CRS
datum the head validator binds. Bounded above by maxFanoutBatchSize + 1; raising
it requires re-publishing the CRS UTxO.
canonicalG2Points :: [BuiltinBLS12_381_G2_Element] Source #
The canonical on-chain CRS datum: the first defaultItems G2 monomial points of
the embedded EIP-4844 setup, as the on-chain builtin element type. This is exactly
what createCRSG2Datum publishes and what the head validator
binds via its baked datum hash. Errors only if the embedded setup is corrupt.