|
1 | | -# How to create a Gnark Plonk proof |
| 1 | +# How to create a Gnark Plonk proof |
2 | 2 |
|
3 | | - ## Step 1 : Set up your enviroment |
| 3 | +## Step 1: Set up your environment |
4 | 4 |
|
5 | | - - 1 Install Go: Make suere you have Go installed. You can download it from [here](https://go.dev/doc/install) |
| 5 | +- 1 Install Go: Make sure you have Go installed. You can download it from [here](https://go.dev/doc/install) |
6 | 6 |
|
7 | | - - 2 Initialize a Go Module: Create a new directory for your project and initializa a Go module |
| 7 | +- 2 Initialize a Go Module: Create a new directory for your project and initialize a Go module |
8 | 8 |
|
9 | 9 | ```bash= |
10 | 10 | mkdir gnark_plonk_circuit |
11 | 11 | cd gnark_plonk_circuit |
12 | 12 | go mod init gnark_plonk_circuit |
13 | 13 | ``` |
14 | 14 |
|
15 | | - - 3 Install Gnark: Add the library to your project |
| 15 | +- 3 Install Gnark: Add the library to your project |
16 | 16 |
|
17 | 17 | ```bash= |
18 | 18 | go get github.com/consensys/gnark@v0.10.0 |
19 | 19 | ``` |
20 | 20 |
|
21 | | - |
22 | | - |
23 | | - ## Step 2: Import dependencies |
| 21 | +## Step 2: Import dependencies |
24 | 22 |
|
25 | 23 | ```bash= |
26 | 24 | import ( |
|
36 | 34 | ) |
37 | 35 | ``` |
38 | 36 |
|
39 | | - Here's what each package is used for: |
40 | | - |
41 | | - |
| 37 | +Here's what each package is used for: |
42 | 38 |
|
43 | 39 | ```fmt```: Standard Go library for formatted input/output. |
44 | 40 |
|
45 | 41 | ```log```: Standard Go library for event logging. |
46 | 42 |
|
47 | | - ```os```: Standard Go library for interacting with the operating system. |
48 | | - |
49 | | - ```path/filepath```: Standard Go library for portable file path manipulation. |
| 43 | +```os```: Standard Go library for interacting with the operating system. |
50 | 44 |
|
51 | | - ```github.com/consensys/gnark-crypto/ecc```: Provides cryptographic operations over elliptic curves. |
| 45 | +```path/filepath```: Standard Go library for portable file path manipulation. |
52 | 46 |
|
53 | | - ```github.com/consensys/gnark/backend/plonk``` Gnark backend for the PLONK proving system. |
| 47 | +```github.com/consensys/gnark-crypto/ecc```: Provides cryptographic operations over elliptic curves. |
54 | 48 |
|
55 | | - ```github.com/consensys/gnark/constraint/bn254```: Provides types and functions to work with constraint systems specifically for the BN254 curve. |
| 49 | +```github.com/consensys/gnark/backend/plonk``` Gnark backend for the PLONK proving system. |
56 | 50 |
|
57 | | - ```github.com/consensys/gnark/frontend```: Provides the API for defining constraints and creating witness data. |
| 51 | +```github.com/consensys/gnark/constraint/bn254```: Provides types and functions to work with constraint systems |
| 52 | +specifically for the BN254 curve. |
58 | 53 |
|
59 | | - ```github.com/consensys/gnark/test/unsafekzg```: Gnark testing utilities for KZG commitments. |
60 | | - |
61 | | - ```github.com/consensys/gnark/frontend/cs/scs```: Gnark frontend for the SCS (Sparse Constraint System) builder. |
| 54 | +```github.com/consensys/gnark/frontend```: Provides the API for defining constraints and creating witness data. |
62 | 55 |
|
| 56 | +```github.com/consensys/gnark/test/unsafekzg```: Gnark testing utilities for KZG commitments. |
63 | 57 |
|
64 | | - ## Step 3: Define the circuit |
| 58 | +```github.com/consensys/gnark/frontend/cs/scs```: Gnark frontend for the SCS (Sparse Constraint System) builder. |
65 | 59 |
|
66 | | - The circuit structure is defined in this case using the equation |
| 60 | +## Step 3: Define the circuit |
67 | 61 |
|
68 | | - $x^3 + x + 5 = y$ |
| 62 | +The circuit structure is defined in this case using the equation |
69 | 63 |
|
| 64 | +$x^3 + x + 5 = y$ |
70 | 65 |
|
71 | 66 | ```bash= |
72 | 67 | // CubicCircuit defines a simple circuit |
|
76 | 71 | Y frontend.Variable `gnark:",public"` |
77 | 72 | } |
78 | 73 | ``` |
79 | | - Here |
80 | 74 |
|
81 | | - ```CubicCircuit```struct contains the variables ```X``` and ```Y``` |
| 75 | +Here |
82 | 76 |
|
83 | | - ```X``` is a secret input, annotated as ```'gnark:"x"'``` |
| 77 | +```CubicCircuit```struct contains the variables ```X``` and ```Y``` |
84 | 78 |
|
85 | | - ```Y``` is a public input, annotated as ```'gnark:",public"'``` |
| 79 | +```X``` is a secret input, annotated as ```'gnark:"x"'``` |
86 | 80 |
|
87 | | - ## Step 4: Define the circuit constraints: |
| 81 | +```Y``` is a public input, annotated as ```'gnark:",public"'``` |
88 | 82 |
|
89 | | - Establish constraints that the circuit must satisfy. Here you define the logic that relates inputs to outputs, encapsulating the computation: |
| 83 | +## Step 4: Define the circuit constraints: |
| 84 | + |
| 85 | +Establish constraints that the circuit must satisfy. |
| 86 | +Here you define the logic that relates inputs to outputs, |
| 87 | +encapsulating the computation: |
90 | 88 |
|
91 | 89 | ```bash= |
92 | 90 | // Define declares the circuit constraints |
|
98 | 96 | } |
99 | 97 | ``` |
100 | 98 |
|
101 | | - The ```Define``` method specifies the constraints for the circuit. |
102 | | - |
103 | | - ```x3 := api.Mul(circuit.X, circuit.X, circuit.X)``` computes X**3 |
| 99 | +The ```Define``` method specifies the constraints for the circuit. |
104 | 100 |
|
| 101 | +```x3 := api.Mul(circuit.X, circuit.X, circuit.X)``` computes X**3 |
105 | 102 |
|
106 | | - ```api.AssertIsEqual(circuit.Y, api.Add(x3, circuit.X, 5)``` asserts that X**3 + X + 5 == Y |
| 103 | +```api.AssertIsEqual(circuit.Y, api.Add(x3, circuit.X, 5)``` asserts that X**3 + X + 5 == Y |
107 | 104 |
|
108 | | - There are other options that we migth use like ```ÀssertDifferent``` ```AssertIsLessOrEqual``` |
| 105 | +There are other options that we might use like ```ÀssertDifferent``` ```AssertIsLessOrEqual``` |
109 | 106 |
|
110 | | - ## Step 5: Compile the circuit and generate the proof |
| 107 | +## Step 5: Compile the circuit and generate the proof |
111 | 108 |
|
112 | | - Detail the steps to compile the circuit, generate a witness, create a proof, and verify it: |
| 109 | +Detail the steps to compile the circuit, generate a witness, create a proof, and verify it: |
113 | 110 |
|
114 | | - |
115 | | - we need to specify the directory where the proof, verification key and the public key will be saved |
| 111 | +we need to specify the directory where the proof, verification key and the public key will be saved |
116 | 112 |
|
117 | 113 | ```bash |
118 | 114 | outputDir := "gnark_plonk_circuit/" |
119 | 115 | ``` |
120 | 116 |
|
121 | | - To compile the circuit we do |
| 117 | +To compile the circuit, we do |
122 | 118 |
|
123 | 119 | ```bash= |
124 | 120 | var circuit CubicCircuit |
|
128 | 124 | panic("circuit compilation error") |
129 | 125 | } |
130 | 126 | ``` |
131 | | - where |
132 | 127 |
|
| 128 | +where |
133 | 129 |
|
134 | | - The ```frontend.Compile``` function compiles the circuit using the SCS |
135 | | - constraint system. |
| 130 | +The ```frontend.Compile``` function compiles the circuit using the SCS |
| 131 | +constraint system. |
136 | 132 |
|
137 | | - ```ecc.BN254.ScalarField()``` specifies the scalar field, in this case for the BN254 curve. |
| 133 | +```ecc.BN254.ScalarField()``` specifies the scalar field, in this case for the BN254 curve. |
138 | 134 |
|
139 | | - ```scs.NewBuilder``` is used to build the sparse constraint system. |
| 135 | +```scs.NewBuilder``` is used to build the sparse constraint system. |
140 | 136 |
|
141 | | - The we generate the SRS (Structured Reference String) |
| 137 | +We generate the SRS (Structured Reference String) |
142 | 138 |
|
143 | 139 | ```bash= |
144 | 140 | // Generate the SRS and its Lagrange interpolation |
|
149 | 145 | } |
150 | 146 | ``` |
151 | 147 |
|
152 | | - ```r1cs := ccs.(*cs.SparseR1CS)``` converts the compiled circuit to a sparse R1CS(Rank-1 Constraint Systems) format required by the SRS generation. |
153 | | - |
154 | | - ```unsafekzg.NewSRS``` generates the structured reference string (SRS) and its Lagrange interpolation. |
| 148 | +```r1cs := ccs.(*cs.SparseR1CS)``` converts the compiled circuit to a sparse R1CS(Rank-1 Constraint Systems) format |
| 149 | +required by the SRS generation. |
155 | 150 |
|
| 151 | +```unsafekzg.NewSRS``` generates the structured reference string (SRS) and its Lagrange interpolation. |
156 | 152 |
|
157 | | - Next we need to setup PLONK |
| 153 | +Next, we need to set up PLONK |
158 | 154 |
|
159 | 155 | ```bash= |
160 | 156 | pk, vk, _ := plonk.Setup(ccs, srs, srsLagrangeInterpolation) |
161 | 157 | ``` |
162 | 158 |
|
163 | | - ```plonk.Setup``` initializes the PLONK proving system with the constraint system, SRS, and its Lagrange interpolation. |
164 | | - This generates the proving key ```pk``` and verification key ```vk``` |
| 159 | +```plonk.Setup``` initializes the PLONK proving system with the constraint system, SRS, and its Lagrange interpolation. |
| 160 | +This generates the proving key ```pk``` and verification key ```vk``` |
165 | 161 |
|
166 | | - Then the Witness is created |
| 162 | +Then the Witness is created |
167 | 163 |
|
168 | 164 | ```bash= |
169 | 165 | assignment := CubicCircuit{X: 3, Y: 35} |
|
177 | 173 | } |
178 | 174 | ``` |
179 | 175 |
|
180 | | - An assignment to the circuit variables is created: ```X = 3``` and ```Y = 35```. |
| 176 | +An assignment to the circuit variables is created: ```X = 3``` and ```Y = 35```. |
181 | 177 |
|
182 | | - ```frontend.NewWitness``` creates the full witness including all variables. |
| 178 | +```frontend.NewWitness``` creates the full witness including all variables. |
183 | 179 |
|
184 | | - ```frontend.NewWitness``` with ```frontend.PublicOnly()``` creates the public witness including only the public variables. |
| 180 | +```frontend.NewWitness``` with ```frontend.PublicOnly()``` creates the public witness including only the public |
| 181 | +variables. |
185 | 182 |
|
186 | | - Generate the Proof: |
| 183 | +Generate the Proof: |
187 | 184 |
|
188 | 185 | ```bash= |
189 | 186 | proof, err := plonk.Prove(ccs, pk, fullWitness) |
|
192 | 189 | } |
193 | 190 | ``` |
194 | 191 |
|
195 | | - ```plonk.Prove``` generates a proof using the compilated circuit,proving key and full witness |
| 192 | +```plonk.Prove``` generates a proof using the compiled circuit, proving key and full witness |
196 | 193 |
|
197 | | - Then to Verify |
| 194 | +Then to Verify |
198 | 195 |
|
199 | 196 | ```bash= |
200 | 197 | // Verify the proof |
|
204 | 201 | } |
205 | 202 | ``` |
206 | 203 |
|
207 | | - ```plonk.Verify``` verifies the proof using the compilated circuit,proving key and full witness |
| 204 | +```plonk.Verify``` verifies the proof using the compiled circuit, proving key and full witness |
208 | 205 |
|
209 | | - Finally we have to serialize and save outputs |
| 206 | +Finally, we have to serialize and save outputs |
210 | 207 |
|
211 | 208 | ```bash= |
212 | 209 | // Open files for writing the proof, the verification key, and the public witness |
|
246 | 243 | } |
247 | 244 | ``` |
248 | 245 |
|
249 | | - Files are created for the proof, verification key, and public witness. |
| 246 | +Files are created for the proof, verification key, and public witness. |
250 | 247 |
|
251 | | - The proof, verification key, and public witness are written to these files. |
| 248 | +The proof, verification key, and public witness are written to these files. |
252 | 249 |
|
253 | | - This ensures that the proof and related data are saved for later use or verification. |
| 250 | +This ensures that the proof and related data are saved for later use or verification. |
254 | 251 |
|
255 | | - The complete code is: |
| 252 | +The complete code is: |
256 | 253 |
|
257 | 254 | ```bash= |
258 | 255 | package main |
|
0 commit comments