Documentation
¶
Index ¶
- Constants
- func DecodeWarpPayload(data []byte) (zChainID ids.ID, targetAddr byte, payload []byte, err error)
- func RegisterZKPrecompiles(registry PrecompileRegistry, strictPQ bool)
- type CrossChainZKVerifier
- type Groth16Verifier
- type Halo2Verifier
- type MapRegistry
- type NovaVerifier
- type PLONKVerifier
- type PrecompileRegistry
- type PrecompiledContract
- type STARKVerifier
Constants ¶
const ( VerifierTypeGroth16 = 0x01 VerifierTypePLONK = 0x02 VerifierTypeSTARK = 0x03 VerifierTypeHalo2 = 0x04 VerifierTypeNova = 0x05 )
Verifier type identifiers used in cross-chain routing.
const ( Groth16VerifierAddr = 0x80 PLONKVerifierAddr = 0x81 STARKVerifierAddr = 0x82 Halo2VerifierAddr = 0x83 NovaVerifierAddr = 0x84 )
Precompile addresses for Z-Chain ZK verifiers. These live in the Z-Chain EVM precompile space.
const CrossChainZKVerifierAddr = 0x0F20
CrossChainZKVerifierAddr is deployed on every EVM chain to route ZK verification requests to Z-Chain via Warp messaging.
Variables ¶
This section is empty.
Functions ¶
func DecodeWarpPayload ¶
DecodeWarpPayload decodes a cross-chain ZK verification request.
func RegisterZKPrecompiles ¶
func RegisterZKPrecompiles(registry PrecompileRegistry, strictPQ bool)
RegisterZKPrecompiles registers the Z-Chain ZK verifier precompiles.
strictPQ gates the classical (quantum-breakable) verifiers. The PrecompiledContract.Run([]byte) interface carries no AccessibleState, so a strict-PQ chain cannot refuse at call time the way the AccessibleState-aware precompile/zk path does (RefuseUnderStrictPQ). Instead the decision is made HERE, at genesis registration: on a strict-PQ chain the classical Groth16 (0x80) and PLONK (0x81) verifiers are simply NOT REGISTERED, so any call to those addresses hits "no precompile at address" — fail-closed by absence. The post-quantum STARK/FRI verifier (0x82) is the only accepted proof system. Halo2 (0x83) and Nova (0x84) are stubs that already fail-closed (errNotImplemented) on every chain.
On a non-strict chain every verifier is registered: Groth16/PLONK are kept as an OPTIONAL building block for cross-chain verification of classical proofs, never deleted.
Types ¶
type CrossChainZKVerifier ¶
CrossChainZKVerifier routes ZK verification from any EVM chain to Z-Chain.
Input format:
verifier_type (1 byte) proof_data (remaining bytes — forwarded to Z-Chain verifier)
The routing works via Warp messaging:
- Caller on C-Chain (or any subnet EVM) invokes this precompile
- Precompile constructs a Warp message addressed to Z-Chain
- Z-Chain receives the message and invokes the appropriate verifier
- Result is returned via Warp response
Gas: base 100K (includes Warp relay overhead).
StrictPQ, when set, makes this router refuse the classical (quantum-breakable) verifier types Groth16 and PLONK: on a strict-PQ chain only the post-quantum STARK/FRI path (VerifierTypeSTARK) may be routed. This mirrors the registration-time gate in RegisterZKPrecompiles — a strict-PQ chain wires this router with StrictPQ=true so it cannot relay a classical proof to Z-Chain.
func (*CrossChainZKVerifier) RequiredGas ¶
func (v *CrossChainZKVerifier) RequiredGas(input []byte) uint64
type Groth16Verifier ¶
type Groth16Verifier struct{}
Groth16Verifier verifies Groth16 proofs on Z-Chain using bn254 pairings.
Input format (all points uncompressed):
vk_len (4 bytes, big-endian) vk (vk_len bytes): Alpha(64) | Beta(128) | Gamma(128) | Delta(128) | numK(4) | K[](64*numK) proof (256 bytes): Ar(64) | Bs(128) | Krs(64) num_inputs (4 bytes, big-endian) inputs (32 * num_inputs bytes): field elements
Output: 0x01 if valid, 0x00 if invalid.
func (*Groth16Verifier) RequiredGas ¶
func (v *Groth16Verifier) RequiredGas(input []byte) uint64
type Halo2Verifier ¶
type Halo2Verifier struct{}
Halo2Verifier will verify Halo2 proofs with IPA commitments. Currently returns an error indicating the verifier is not yet available.
func (*Halo2Verifier) RequiredGas ¶
func (v *Halo2Verifier) RequiredGas(input []byte) uint64
type MapRegistry ¶
type MapRegistry struct {
// contains filtered or unexported fields
}
MapRegistry is a simple map-based precompile registry for testing.
func NewMapRegistry ¶
func NewMapRegistry() *MapRegistry
func (*MapRegistry) Get ¶
func (r *MapRegistry) Get(addr byte) (PrecompiledContract, error)
func (*MapRegistry) Register ¶
func (r *MapRegistry) Register(addr byte, contract PrecompiledContract)
type NovaVerifier ¶
type NovaVerifier struct{}
NovaVerifier will verify Nova IVC proofs. Currently returns an error indicating the verifier is not yet available.
func (*NovaVerifier) RequiredGas ¶
func (v *NovaVerifier) RequiredGas(input []byte) uint64
type PLONKVerifier ¶
type PLONKVerifier struct{}
PLONKVerifier verifies PLONK proofs using KZG polynomial commitments on bn254.
Input format:
vk_len (4 bytes) vk (vk_len bytes) proof_len (4 bytes) proof (proof_len bytes) num_inputs (4 bytes) inputs (32 * num_inputs bytes)
Output: 0x01 if valid, 0x00 if invalid.
func (*PLONKVerifier) RequiredGas ¶
func (v *PLONKVerifier) RequiredGas(input []byte) uint64
type PrecompileRegistry ¶
type PrecompileRegistry interface {
Register(addr byte, contract PrecompiledContract)
}
PrecompileRegistry allows registering precompiled contracts at fixed addresses.
type PrecompiledContract ¶
type PrecompiledContract interface {
RequiredGas(input []byte) uint64
Run(input []byte) ([]byte, error)
}
PrecompiledContract is the interface that EVM precompiles must satisfy.
type STARKVerifier ¶
type STARKVerifier struct{}
STARKVerifier verifies post-quantum STARK / FRI proofs on Z-Chain by delegating to the strict-PQ STARK verifier in precompile/starkfri (a Plonky3 fork: cSHAKE256 Merkle commitments over the Goldilocks 64-bit prime field, FRI low-degree test — NO KZG, NO pairings, NO trusted setup). This is the quantum-safe replacement for the pairing-based Groth16Verifier on the Z-Chain MLDSA-rollup path: a quantum adversary that breaks bn254 cannot forge a STARK/FRI proof, whose soundness rests only on the collision resistance of cSHAKE256 and the Reed–Solomon proximity gap (no algebraic-group assumption).
Input format:
proof_len (4 bytes, big-endian) proof (proof_len bytes) — must begin with MagicHeader "P3Q1" pub_len (4 bytes, big-endian) inputs (pub_len bytes) — serialized public inputs
Output: 0x01 if valid, 0x00 if invalid.
Verifier binding. The actual FRI verifier runs out-of-band (Rust, behind the `starkfri_p3q` cgo build tag) and self-registers via starkfri.RegisterVerifier. When no verifier is bound (CGO_ENABLED=0 or the tag is absent) starkfri.Verify returns ErrVerifierNotRegistered and this precompile FAILS CLOSED — it returns errVerifierUnavailable and NEVER accepts an unverified proof. There is no forgery oracle in the unbound configuration.
func (*STARKVerifier) RequiredGas ¶
func (v *STARKVerifier) RequiredGas(input []byte) uint64