Skip to content

Commit 0989c06

Browse files
committed
feat(Bridge/Clean): FormalCircuit as ConstraintSystem + BehavioralContract
Bridge Clean's FormalCircuit to ArkLib's universal ConstraintSystem abstraction: - toConstraintSystem: wraps FormalCircuit with satisfies checking input consistency (eval env inputVar = inp) and constraint satisfaction (ConstraintsHold). - toBehavioralContract: transfers Clean's original_soundness and original_completeness into ArkLib's BehavioralContract interface. Zero sorrys. Targets upstream Verified-zkEVM/clean at 4a013fed.
1 parent bc66762 commit 0989c06

4 files changed

Lines changed: 122 additions & 12 deletions

File tree

ArkLib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import ArkLib.AGM.Basic
2+
import ArkLib.Bridge.Clean
23
import ArkLib.CommitmentScheme.Basic
34
import ArkLib.CommitmentScheme.Fold
45
import ArkLib.CommitmentScheme.KZG

ArkLib/Bridge/Clean.lean

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/-
2+
Copyright (c) 2025 ArkLib Contributors. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: XC0R
5+
-/
6+
import ArkLib.ProofSystem.ConstraintSystem.Basic
7+
import Clean.Circuit.Foundations
8+
9+
/-!
10+
# Clean ↔ ArkLib Bridge via ConstraintSystem
11+
12+
This module bridges Clean's `FormalCircuit` to ArkLib's `ConstraintSystem` and
13+
`BehavioralContract` abstractions, transferring circuit-level security guarantees
14+
(soundness and completeness) to ArkLib's universal constraint system interface.
15+
16+
A Clean `FormalCircuit F Input Output` maps to:
17+
- A `ConstraintSystem` where `satisfies` checks input consistency (`eval env inputVar = inp`)
18+
and circuit constraint satisfaction (`ConstraintsHold`).
19+
- A `BehavioralContract` where `Assumptions` and `Spec` are transferred directly from the
20+
circuit, with soundness proved via `original_soundness` and completeness via
21+
`original_completeness`.
22+
23+
## Main definitions
24+
25+
- `Clean.toConstraintSystem`: wraps a `FormalCircuit` as a `ConstraintSystem`
26+
- `Clean.toBehavioralContract`: wraps a `FormalCircuit` as a `BehavioralContract`,
27+
transferring both Clean security properties
28+
29+
## Dependencies
30+
31+
Targets upstream [Verified-zkEVM/clean](https://github.com/Verified-zkEVM/clean) at pinned
32+
commit `4a013fed` (post toolchain-bump-v4.28 merge via clean#357).
33+
-/
34+
35+
open Circuit
36+
37+
namespace Clean.Bridge
38+
39+
variable {F : Type} [Field F]
40+
{Input Output : TypeMap} [ProvableType Input] [ProvableType Output]
41+
42+
/-- The canonical variable encoding for the input type, starting at offset 0. -/
43+
abbrev canonicalInputVar (Input : TypeMap) (F : Type) [Field F] [ProvableType Input] :
44+
Var Input F :=
45+
varFromOffset Input 0
46+
47+
/-- A Clean `FormalCircuit` viewed as an ArkLib `ConstraintSystem`.
48+
49+
The single index `Unit` reflects that one circuit is one constraint system (no size family).
50+
`satisfies` checks that the environment encodes the claimed input and that all circuit
51+
constraints hold. -/
52+
def toConstraintSystem (circuit : FormalCircuit F Input Output) :
53+
ConstraintSystem where
54+
Index := Unit
55+
Stmt := fun _ => Input F
56+
OStmt := fun _ => PUnit
57+
Wit := fun _ => Environment F
58+
satisfies := fun _ inp _ env =>
59+
eval env (canonicalInputVar Input F) = inp ∧
60+
ConstraintsHold env
61+
(circuit.main (canonicalInputVar Input F) |>.operations 0)
62+
63+
/-- A Clean `FormalCircuit` viewed as an ArkLib `BehavioralContract`.
64+
65+
- **Soundness**: Clean's `original_soundness` guarantees that if assumptions hold and
66+
constraints are satisfied, the circuit output satisfies `Spec`.
67+
- **Completeness**: Clean's `original_completeness` guarantees that if assumptions hold
68+
and a witness environment exists (encoding the input with valid local witnesses),
69+
constraints are satisfied and the output meets the spec.
70+
71+
The `hWitGen` parameter asserts that for every input satisfying `Assumptions`, there exists
72+
an environment encoding that input and using the circuit's local witness generators. This
73+
is guaranteed by Clean's circuit construction (witness generators are deterministic functions
74+
over the input), but is not directly exported as an existence theorem in Clean's API. -/
75+
noncomputable def toBehavioralContract (circuit : FormalCircuit F Input Output)
76+
(hWitGen : ∀ inp, circuit.Assumptions inp → ∃ env : Environment F,
77+
eval env (canonicalInputVar Input F) = inp ∧
78+
env.UsesLocalWitnesses 0
79+
(circuit.main (canonicalInputVar Input F) |>.operations 0)) :
80+
ConstraintSystem.BehavioralContract (toConstraintSystem circuit) () where
81+
Assumptions := fun inp => circuit.Assumptions inp
82+
Spec := fun inp env =>
83+
circuit.Spec inp (eval env (circuit.output (canonicalInputVar Input F) 0))
84+
soundness := fun inp _ env hAssume ⟨hEval, hConstr⟩ =>
85+
circuit.original_soundness 0 env (canonicalInputVar Input F) inp hEval hAssume hConstr
86+
completeness := fun inp hAssume => by
87+
obtain ⟨env, hEval, hLocalWit⟩ := hWitGen inp hAssume
88+
have hConstr := circuit.original_completeness 0 env
89+
(canonicalInputVar Input F) inp hEval hAssume hLocalWit
90+
have hSpec := circuit.original_soundness 0 env
91+
(canonicalInputVar Input F) inp hEval hAssume hConstr
92+
exact ⟨PUnit.unit, env, ⟨hEval, hConstr⟩, hSpec⟩
93+
94+
end Clean.Bridge

lake-manifest.json

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,17 @@
11
{"version": "1.1.0",
22
"packagesDir": ".lake/packages",
33
"packages":
4-
[{"url": "https://github.com/Verified-zkEVM/CompPoly",
4+
[{"url": "https://github.com/Verified-zkEVM/clean",
5+
"type": "git",
6+
"subDir": null,
7+
"scope": "",
8+
"rev": "4a013fed1036ff64b978dc5f55e0af743231359c",
9+
"name": "Clean",
10+
"manifestFile": "lake-manifest.json",
11+
"inputRev": "4a013fed1036ff64b978dc5f55e0af743231359c",
12+
"inherited": false,
13+
"configFile": "lakefile.lean"},
14+
{"url": "https://github.com/Verified-zkEVM/CompPoly",
515
"type": "git",
616
"subDir": null,
717
"scope": "",
@@ -41,20 +51,10 @@
4151
"inputRev": "aa64dffef10f1c8bfaa73269557385d7fec84e81",
4252
"inherited": false,
4353
"configFile": "lakefile.lean"},
44-
{"url": "https://github.com/Verified-zkEVM/ExtTreeMapLemmas",
45-
"type": "git",
46-
"subDir": null,
47-
"scope": "",
48-
"rev": "1c21eb1270312fdcdac35d6b6bf07e0863f7ef45",
49-
"name": "ExtTreeMapLemmas",
50-
"manifestFile": "lake-manifest.json",
51-
"inputRev": "v4.28.0-patch-1",
52-
"inherited": true,
53-
"configFile": "lakefile.lean"},
5454
{"url": "https://github.com/leanprover-community/mathlib4",
5555
"type": "git",
5656
"subDir": null,
57-
"scope": "leanprover-community",
57+
"scope": "",
5858
"rev": "8f9d9cff6bd728b17a24e163c9402775d9e6a365",
5959
"name": "mathlib",
6060
"manifestFile": "lake-manifest.json",
@@ -141,6 +141,16 @@
141141
"inputRev": "v4.28.0",
142142
"inherited": true,
143143
"configFile": "lakefile.toml"},
144+
{"url": "https://github.com/Verified-zkEVM/ExtTreeMapLemmas",
145+
"type": "git",
146+
"subDir": null,
147+
"scope": "",
148+
"rev": "1c21eb1270312fdcdac35d6b6bf07e0863f7ef45",
149+
"name": "ExtTreeMapLemmas",
150+
"manifestFile": "lake-manifest.json",
151+
"inputRev": "v4.28.0-patch-1",
152+
"inherited": true,
153+
"configFile": "lakefile.lean"},
144154
{"url": "https://github.com/fgdorais/lean4-unicode-basic",
145155
"type": "git",
146156
"subDir": null,

lakefile.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,10 @@ name = "CompPoly"
3232
git = "https://github.com/Verified-zkEVM/CompPoly"
3333
rev = "fe33688378befe303df16c91189df9aff14bb105"
3434

35+
[[require]]
36+
name = "Clean"
37+
git = "https://github.com/Verified-zkEVM/clean"
38+
rev = "4a013fed1036ff64b978dc5f55e0af743231359c"
39+
3540
[[lean_lib]]
3641
name = "ArkLib"

0 commit comments

Comments
 (0)