precompiles

package
v1.3.12 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 20, 2026 License: BSD-3-Clause Imports: 8 Imported by: 0

Documentation

Index

Constants

View Source
const (
	VerifierTypeGroth16 = 0x01
	VerifierTypePLONK   = 0x02
	VerifierTypeSTARK   = 0x03
	VerifierTypeHalo2   = 0x04
	VerifierTypeNova    = 0x05
)

Verifier type identifiers used in cross-chain routing.

View Source
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.

View Source
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

func DecodeWarpPayload(data []byte) (zChainID ids.ID, targetAddr byte, payload []byte, err error)

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

type CrossChainZKVerifier struct {
	ZChainID ids.ID
	StrictPQ bool
}

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:

  1. Caller on C-Chain (or any subnet EVM) invokes this precompile
  2. Precompile constructs a Warp message addressed to Z-Chain
  3. Z-Chain receives the message and invokes the appropriate verifier
  4. 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

func (*CrossChainZKVerifier) Run

func (v *CrossChainZKVerifier) Run(input []byte) ([]byte, error)

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

func (*Groth16Verifier) Run

func (v *Groth16Verifier) Run(input []byte) ([]byte, error)

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

func (*Halo2Verifier) Run

func (v *Halo2Verifier) Run(input []byte) ([]byte, error)

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

func (*NovaVerifier) Run

func (v *NovaVerifier) Run(input []byte) ([]byte, error)

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

func (*PLONKVerifier) Run

func (v *PLONKVerifier) Run(input []byte) ([]byte, error)

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

func (*STARKVerifier) Run

func (v *STARKVerifier) Run(input []byte) ([]byte, error)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL