Skip to content

zkML + Circuit Stack

This is where AI meets cryptography. zkde.fi uses zero-knowledge machine learning to turn model inference into verifiable, policy-aware signals. The output of a model isn't a recommendation — it's a proof. And that proof can be verified on-chain before capital moves.

The system includes 31 Circom circuits, 2 EZKL ML models, and a bridge layer (ModelBridge) that converts arbitrary ONNX model outputs into on-chain-verifiable commitments via Garaga. Each piece serves a specific role in the pipeline.

The EZKL pipeline

Here's what happens when an ML model goes from training to on-chain verification:

flowchart LR
  ONNX["1. ONNX model<br/><i>trained offline</i>"] --> EZKL["2. EZKL compile<br/><i>quantize + circuit</i>"]
  EZKL --> KZG["3. KZG commitment<br/><i>weights → on-chain</i>"]
  KZG --> INFER["4. Inference<br/><i>private inputs</i>"]
  INFER --> G16["5. Groth16 proof<br/><i>correct execution</i>"]
  G16 --> BRIDGE["6. ModelBridge<br/><i>format bridge</i>"]
  BRIDGE --> GAR["7. Garaga verify<br/><i>on-chain in Cairo</i>"]

Walking through it:

  1. Model training — a standard ML model is trained using whatever framework (PyTorch, scikit-learn, etc.) and exported as ONNX. Nothing special here — this is the model's normal lifecycle.

  2. EZKL compilation — EZKL takes the ONNX model and converts it into a Halo2 arithmetic circuit. It quantizes the floating-point weights into fixed-point representations that work inside a ZK circuit. This is a build-time step, not a runtime step — the compiled artifacts are reusable.

  3. KZG commitment — the model's quantized weights are committed via KZG polynomial commitment scheme. This commitment is registered on-chain, binding the model's identity to a specific set of weights. If someone swaps the model, the commitment won't match and verification fails.

  4. Inference — at runtime, the model runs on user-provided inputs. The inputs stay private — they never leave the user's control. The prover generates a witness (inputs + intermediate values + outputs) that will be used to construct the proof.

  5. Groth16 proof — EZKL generates a proof that the correct model, with the committed weights, ran correctly on the given inputs and produced the given output. This is the mathematical guarantee.

  6. ModelBridge — a Circom circuit that takes the EZKL proof output and reformats it for Garaga's BN254 pairing check. Think of it as a format adapter between EZKL's proof system and Starknet's verification infrastructure.

  7. On-chain verification — Garaga verifies the Groth16 proof natively in Cairo on Starknet. The verification is a single contract call that either passes or fails. No oracle, no committee, just math.

One important distinction: the "EZKL compilation" step happens at build time against pre-prepared model artifacts. The current stack relies on pre-built circuits and runtime proving services, not on-demand model compilation per request.

The two ML models

ModelArchitectureOutput classesWhat it does
yield_forecastLinear(12→32) → ReLU → Linear(32→16) → ReLU → Linear(16→4)declining / stable / growing / surgingPredicts yield trajectory for a pool. Used in allocation decisions — "should capital go here?"
anomaly_detectorLinear(8→24) → ReLU → Linear(24→12) → ReLU → Linear(12→3)safe / warning / criticalDetects anomalous pool behavior before capital enters. Safety check, not a trading signal.

Both models are deliberately simple — small enough to compile into efficient ZK circuits, but expressive enough to capture the patterns that matter. A 50-layer transformer would be more powerful but impossible to prove in reasonable time. These models hit the sweet spot.

Both are compiled via EZKL into Halo2 circuits with KZG polynomial commitments. Proofs are verified on Ethereum Sepolia via the Halo2Verifier and bridged to Starknet via L1→L2 messaging or the ModelBridge circuit path.

The 13-circuit agent screening bundle

Before any execution path surfaces in Trade Desk, the relevant circuits from this bundle evaluate the action. Not all 13 fire every time — the system picks the circuits relevant to the action type. A swap triggers different circuits than a lending operation.

#CircuitWhat it proves
1RiskScoreAggregate risk rating for a pool or position
2AnomalyDetectorWhether pool behavior deviates from safe baselines
3YieldOptimalityWhether the yield justifies the risk at current conditions
4StrategyIntegrityWhether the proposed strategy matches committed parameters
5ExecutionIntegrityWhether execution respected declared constraints (slippage, timing)
6ImpermanentLossPredictorEstimated IL exposure for LP positions
7SlippageBoundWhether expected slippage stays within acceptable bounds
8MEVResistanceProofWhether the execution route has MEV protection characteristics
9LiquidationRiskProximity to liquidation threshold for leveraged positions
10CorrelationRiskCross-asset correlation risk in portfolio context
11CreditEligibilityWhether collateral posture meets lending thresholds
12SolvencyProofVerifiable solvency attestation — "I can pay what I owe"
13AgentReputationScoreComposite trust score from execution history

Each circuit is compiled to WASM + zkey for fast client-side proof generation. The circuits are small enough to prove in seconds, which matters for UX — you don't want users waiting 30 seconds for a risk check.

FICO-pack verifiers

Five of these circuits have dedicated on-chain verifier contracts (the "FICO pack" — think of them as the credit score proofs of DeFi):

VerifierAddress
SolvencyProofVerifier0x043b2...9c9b
RiskPassportTierVerifier0x05e71...7788
TraderPerformanceVerifier0x04c80...0769
StrategyIntegrityVerifier0x00c94...e549
ExecutionIntegrityVerifier0x03bb2...873b

The full 31-circuit set

Beyond the 13 agent screening circuits, the system has circuits for privacy, governance, bridging, and attestations:

CategoryCircuitsWhat they're for
PrivacyFullPrivacyWithdraw, FullPrivacyWithdrawHashed, FullPrivacyWithdrawWithChange, PrivateDeposit, PrivateWithdraw, PoolMembershipShielded pool operations — deposits, withdrawals, membership proofs. See Privacy Rails.
BridgeModelBridge, ModelBridgeHeavyFormat adapters — bridge EZKL proof outputs to Garaga-verifiable Groth16
Governanceprivate_voteCast a DAO vote without revealing voting power or direction
PositionTWAPPosition, RebalanceTimingCommitmentTime-weighted average price tracking and rebalance timing proofs
AttestationHistoricalPerformanceAttestation, RobustnessCertificate, SafetyDiversificationProvable track record — "I performed well over 30 days" without revealing the equity curve
ThresholdBalanceAboveThreshold, TenureAboveThresholdSelective disclosure — "my balance is above X" without revealing X
DeFiCrossProtocolArbitrage, RiskPassportTier, TraderPerformanceProofCross-protocol risk and performance proofs

Plus a Noir circuit (noir_ezkl_bridge/) for the Noir HONK proving lane — a different proving system that serves as an alternative verification path.

ModelBridge vs ModelBridgeHeavy

ModelBridgeModelBridgeHeavy
Artifact size~2MB zkey~8MB zkey
Proving time~3–5 seconds~10–15 seconds
Use caseDefault bridge for standard model outputsComplex model outputs with more constraint capacity
VerifierSame Garaga infrastructureSame Garaga infrastructure

Both produce Groth16 proofs. The difference is constraint capacity — ModelBridgeHeavy can handle larger model outputs at the cost of a heavier proving key and longer proving time.

The on-chain entry point for verifying bridged EZKL proofs: 0x037c4...626f (Starknet Sepolia).

zkML API endpoints

MethodEndpointWhat it does
POST/api/v1/zkdefi/zkml/risk_scoreRun risk score inference with proof generation
POST/api/v1/zkdefi/zkml/anomalyRun anomaly detection
POST/api/v1/zkdefi/zkml/combinedCombined risk + anomaly in one call
GET/api/v1/zkdefi/zkml/statuszkML subsystem health
GET/api/v1/zkdefi/zkml/pool-safetyPool safety snapshot (aggregated)
POST/api/v1/zkdefi/zkml/scanGeneral-purpose model scan
GET/api/v1/zkdefi/zkml/circuitsCircuit metadata — what's compiled and available

Next: Privacy Rails · Proof Pipeline · API Reference

Built by Obsqra Labs