You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/zkEVM/concepts/circom-intro-brief.md
+24-25Lines changed: 24 additions & 25 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,4 +1,3 @@
1
-
2
1
!!!info
3
2
In this document, we describe the CIRCOM component of the zkProver. It is one of the four main components of the zkProver, as outlined [here](../architecture/zkprover/index.md). These principal components are; the Executor or Main SM, STARK Recursion, CIRCOM, and Rapid SNARK.
4
3
@@ -38,7 +37,7 @@ Once obtained, the R1CS can later be used by a zk-SNARK protocol to generate ver
38
37
39
38
A valid proof attests to the fact that the prover knows an assignment to all wires of the circuit that fulfills all the constraints of the R1CS.
40
39
41
-
An issue that arises, when applying Zero-Knowledge protocols to complex computations such as a circuit describing the logic of a ZK-rollup, is that the number of constraints to be verified can be extremely large.
40
+
An issue that arises, when applying zero-Knowledge protocols to complex computations such as a circuit describing the logic of a ZK-rollup, is that the number of constraints to be verified can be extremely large.
42
41
43
42
CIRCOM was developed for the very purpose of scaling complex Arithmetic circuits by realizing them as combined instantiations of smaller Arithmetic circuits.
44
43
@@ -77,25 +76,25 @@ The CIRCOM compiler is mainly written in Rust and it is open source.
77
76
78
77
The CIRCOM language has its own peculiarities. The focus in this subsection is on a few features characteristic of CIRCOM.
79
78
80
-
Consider as an example, the `Multiplier` circuit with input signals $\texttt{a}$ and $\texttt{b}$, and an output signal $\texttt{c}$ satisfying the constraint $\texttt{a} \times \texttt{b} \texttt{ - c = 0}$.
79
+
Consider as an example, the _Multiplier_ circuit with input signals $\texttt{a}$ and $\texttt{b}$, and an output signal $\texttt{c}$ satisfying the constraint $\texttt{a} \times \texttt{b} \texttt{ - c = 0}$.
The figure above depicts a simple `Multiplier` Arithmetic circuit with input wires labeled $\texttt{a}$ and $\texttt{b}$ and an output wire labeled $\texttt{c}$ such that $\texttt{a} \times \texttt{b\ = } \texttt{c}$. The wires are referred to as signals. The constraint related to this Multiplier circuit is:
83
+
The figure above depicts a simple _Multiplier_ Arithmetic circuit with input wires labeled $\texttt{a}$ and $\texttt{b}$ and an output wire labeled $\texttt{c}$ such that $\texttt{a} \times \texttt{b\ = } \texttt{c}$. The wires are referred to as signals. The constraint related to this Multiplier circuit is:
85
84
86
85
$$
87
86
\texttt{a} \times \texttt{b} \texttt{ - c = 0}
88
87
$$
89
88
90
-
### The `pragma` instruction
89
+
### The _pragma_ instruction
91
90
92
-
The `pragma` instruction specifies the version of the CIRCOM compiler being used. It is meant to ensure compatibility between the circuit and the compiler version. If the two are incompatible, the compiler throws a warning.
91
+
The _pragma_ instruction specifies the version of the CIRCOM compiler being used. It is meant to ensure compatibility between the circuit and the compiler version. If the two are incompatible, the compiler throws a warning.
93
92
94
93
```
95
94
pragma circom 2.0.0;
96
95
```
97
96
98
-
As a precautionary measure, all files with the `.circom` extension should start with a `pragma` instruction. In the absence of this instruction, it is assumed that the code is compatible with the latest compiler version.
97
+
As a precautionary measure, all files with the _.circom_ extension should start with a _pragma_ instruction. In the absence of this instruction, it is assumed that the code is compatible with the latest compiler version.
99
98
100
99
### Declaration of signals
101
100
@@ -130,7 +129,7 @@ Templates are parametrizable in the sense that their outputs depend on free inpu
130
129
131
130
They are general descriptions of circuits, that have some input and output signals, as well as a relation between the inputs and the outputs.
132
131
133
-
The following code shows how a `Multiplier template` is created:
132
+
The following code shows how a _Multiplier template_ is created:
134
133
135
134
```
136
135
pragma circom 2.0.0;
@@ -147,15 +146,15 @@ template Multiplier () {
147
146
148
147
### Instantiation of templates
149
148
150
-
Although the above code succeeds in creating the `Multiplier template`, the template is yet to be instantiated.
149
+
Although the above code succeeds in creating the _Multiplier template_, the template is yet to be instantiated.
151
150
152
151
In CIRCOM, the instantiation of a template is called a component, and it is created as follows:
153
152
154
153
```
155
154
component main = Multiplier();
156
155
```
157
156
158
-
The `Multiplier template` does not depend on any parameter.
157
+
The _Multiplier template_ does not depend on any parameter.
159
158
160
159
However, it is possible to initially create a generic, parametrizable template that can later be instantiated using specific parameters to construct the circuit.
161
160
@@ -165,7 +164,7 @@ Small circuits can be defined which can be combined to create larger circuits by
165
164
166
165
### Compiling a circuit
167
166
168
-
As previously mentioned, the use of the operator "<==" in the `Multiplier template` has dual functionality:
167
+
As previously mentioned, the use of the operator "<==" in the _Multiplier template_ has dual functionality:
169
168
170
169
- It captures the arithmetic relation between signals, and
171
170
- It also provides a way to compute $\texttt{c}$ from $\texttt{a}$ and $\texttt{b}$.
@@ -174,13 +173,13 @@ In general, the description of a CIRCOM circuit also keeps dual functionality. T
174
173
175
174
This enables the compiler to easily generate the R1CS describing a circuit, together with instructions to compute intermediate and output values of a circuit.
176
175
177
-
Given a circuit with the `multiplier.circom` extension, the following line of code instructs the compiler to carry out the two types of tasks:
176
+
Given a circuit with the _multiplier.circom_ extension, the following line of code instructs the compiler to carry out the two types of tasks:
178
177
179
178
```
180
179
circom multiplier.circom --r1cs --c --wasm --sym
181
180
```
182
181
183
-
After compiling the `.circom` circuit, the compiler returns four files:
182
+
After compiling the _.circom_ circuit, the compiler returns four files:
184
183
185
184
- A file with the R1CS constraints (symbolic task)
186
185
- A C++ program for computing values of the circuit wires (computational task)
@@ -195,47 +194,47 @@ Recall that a valid set of circuit input, intermediate and output values is call
195
194
196
195
### Private and public signals
197
196
198
-
Depending on the `template` being used, some signals are `private` while others are `public`.
197
+
Depending on the _template_ being used, some signals are _private_ while others are _public_.
199
198
200
-
In the case of the `Multiplier template`, a signal is `private` by default, unless it is declared to be `public` in the instantiation of the template as shown below.
199
+
In the case of the _Multiplier template_, a signal is _private_ by default, unless it is declared to be _public_ in the instantiation of the template as shown below.
201
200
202
201
```
203
202
component main {public [a]} = Multiplier();
204
203
```
205
204
206
-
According to the above line, the input signal $\texttt{a}$ is `public`, while $\texttt{b}$ is `private` by default.
205
+
According to the above line, the input signal $\texttt{a}$ is _public_, while $\texttt{b}$ is _private_ by default.
207
206
208
207
### Main component
209
208
210
-
The CIRCOM compiler needs a specific component as an entry point. And this initial component is called `main`.
209
+
The CIRCOM compiler needs a specific component as an entry point. And this initial component is called _main_.
211
210
212
-
In the same way the `Multiplier template` needed instantiation as a component, so does the `main` component.
211
+
In the same way the _Multiplier template_ needed instantiation as a component, so does the _main_ component.
213
212
214
-
However, unlike other intermediate components, the `main` component defines the global input and output signals of a circuit.
213
+
However, unlike other intermediate components, the _main_ component defines the global input and output signals of a circuit.
215
214
216
215
Denote a list of $\texttt{n}$ signals by $\{\mathtt{ s1, s2, \dots , sn }\}$.
217
216
218
-
The general syntax to specify the `main` component is the following:
217
+
The general syntax to specify the _main_ component is the following:
219
218
220
219
```
221
220
component main {public [s1,..,sn]} = templateID(v1,..,vn);
222
221
```
223
222
224
-
Specifying the list of public signals of the circuit, indicated as `{public [s1,..,sn]}`, is optional.
223
+
Specifying the list of public signals of the circuit, indicated as _{public [s1,..,sn]}_, is optional.
225
224
226
-
Note that global inputs are considered `private` signals while global outputs are considered `public`.
225
+
Note that global inputs are considered _private_ signals while global outputs are considered _public_.
227
226
228
-
However, the `main` component has a special attribute to set a list of global inputs as public signals.
227
+
However, the _main_ component has a special attribute to set a list of global inputs as public signals.
229
228
230
-
The rule of thumb is: Any other input signal not included in this list `{public [s1,..,sn]}`, is considered private.
229
+
The rule of thumb is: Any other input signal not included in this list _{public [s1,..,sn]}_, is considered private.
231
230
232
231
### Concluding CIRCOM's features
233
232
234
233
There are many more features that distinguish CIRCOM from other known ZK tools. The rest of these features delineated in the original [CIRCOM paper](https://www.techrxiv.org/articles/preprint/CIRCOM_A_Robust_and_Scalable_Language_for_Building_Complex_Zero-Knowledge_Circuits/19374986/1).
235
234
236
235
We conclude this document by putting together the mentioned CIRCOM features in one code example.
237
236
238
-
The `Multiplier template` is again used as an example. But the `pragma` instruction is omitted for simplicity's sake.
237
+
The _Multiplier template_ is again used as an example. But the _pragma_ instruction is omitted for simplicity's sake.
This section contains specifications of other zkEVM features not covered in the Architecture section of this documentation.
2
2
3
-
First are the two novel languages: The zero-knowledge Assembly (zkASM) language which interprets the firmware of microprocessor-type state machines, and the Polynomial Identity Language (PIL) which is instrumental in enabling verification of state transitions.
3
+
First are the two novel languages: The _zero-knowledge Assembly_ (zkASM) language which interprets the firmware of microprocessor-type state machines, and the _Polynomial Identity Language_ (PIL) which is instrumental in enabling verification of state transitions.
4
4
5
5
Second are some of the differences between Polygon zkEVM and the EVM. These are differences in terms of opcodes, supported precompiled contracts, newly added features and other variances.
Copy file name to clipboardExpand all lines: docs/zkEVM/spec/pil/connection-arguments.md
+4-4Lines changed: 4 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,7 +4,7 @@ This document describes the connection arguments and how they are used in Polyno
4
4
5
5
Given a vector $a = ( a_1 , \dots , a_n) \in \mathbb{F}_n$ and a partition ${\large{\S}} = \{ S_1, \dots , S_t \}$ of $[n]$, we say "$a$ $\textit{copy-satisfies}$ ${\large{\S}}$" if for each $S_k \in {\large{\S}}$, we have that $a_i = a_j$ whenever $i, j \in S_k$ , with $i, j \in [n]$ and $k \in [t]$.
6
6
7
-
Moreover, we say that a protocol $(\mathcal{P}, \mathcal{V})$ is a **connection argument** if the protocol can be used by $\mathcal{P}$ to prove to $\mathcal{V}$ that a vector $\textit{copy-satisfies}$ a partition of $[n]$.
7
+
Moreover, we say that a protocol $(\mathcal{P}, \mathcal{V})$ is a _connection argument_ if the protocol can be used by $\mathcal{P}$ to prove to $\mathcal{V}$ that a vector $\textit{copy-satisfies}$ a partition of $[n]$.
8
8
9
9
!!! info
10
10
@@ -48,7 +48,7 @@ Observe that, since the singleton $\{2\}$ is in ${\large{\S}}$, then $\mathtt{a}
48
48
49
49
Also, the vector $\mathtt{b}$ does not $\textit{copy-satisfies}\ {\large{\S}}$ because $\mathtt{b}_1 = \mathtt{b}_5 =3 \not= 7 = \mathtt{b}_3$.
50
50
51
-
In the context of programs, connection arguments can be written easily in PIL by introducing a column associated with the chosen partition. This is also done in [GWC19](https://eprint.iacr.org/2019/953).
51
+
In the context of programs, connection arguments can be written easily in PIL by introducing a column associated with the chosen partition. This is also done in [[GWC19]](https://eprint.iacr.org/2019/953).
52
52
53
53
Recall that column values are evaluations of a polynomial at $G = \langle g \rangle$ and $\texttt{N}$ is the length of the execution trace.
54
54
@@ -80,7 +80,7 @@ A valid execution trace for this example was shown in Table 1 above.
80
80
81
81
!!! info Remark
82
82
83
-
The column $\texttt{SA}$ does not need to be declared as a constant polynomial. The **connection argument** will still hold true even if it is declared as committed.
83
+
The column $\texttt{SA}$ does not need to be declared as a constant polynomial. The _connection argument_ still holds true even if it is declared as committed.
84
84
85
85
## Multiple copy satisfiability
86
86
@@ -106,7 +106,7 @@ $$
106
106
107
107
where $k_1, k_2 \in \mathbb{F}$ are introduced here as a way of obtaining more elements (in a group $G$ of size $n$) and enabling correct encoding of the $[3n] \to [3n]$ permutation $\sigma$.
108
108
109
-
See [GWC19](https://eprint.iacr.org/2019/953) for more details on this encoding.
109
+
See [[GWC19]](https://eprint.iacr.org/2019/953) for more details on this encoding.
110
110
111
111
The below table shows how to compute the polynomials $\texttt{SA}$, $\texttt{SB}$ and $\texttt{SC}$ encoding the permutation of the above example:
**But in order to keep the PIL code simple and easily relatable to the execution trace**, we replace the $P$ and $Q$ with $\texttt{a}$ and $\texttt{b}$, respectively. The above $\text{eqn}$ will therefore be seen written as,
37
+
But in order to keep the PIL code simple and easily relatable to the execution trace, we replace the $P$ and $Q$ with $\texttt{a}$ and $\texttt{b}$, respectively. The above $\text{eqn}$ is therefore seen written as,
Copy file name to clipboardExpand all lines: docs/zkEVM/spec/pil/filling-polynomials.md
+15-15Lines changed: 15 additions & 15 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,14 +1,14 @@
1
1
This document describes how to fill Polynomials in PIL using JavaScript and Pilcom.
2
2
3
-
In this document, we are going to use **Javascript** and **pilcom** to generate a specific execution trace for a given PIL.
3
+
In this document, we are going to use _Javascript_ and _pilcom_ to generate a specific execution trace for a given PIL.
4
4
5
5
To do so, we are going to use the execution trace of a program previously discussed in the [Connection arguments](connection-arguments.md) section.
6
6
7
-
We will also use the **pil-stark** library, which is a utility that provides a framework for setup, generation and verification of proofs. It uses an FGL class which mimics a finite field, and it is required by some functions that provide the **pilcom** package.
7
+
We also use the _pil-stark_ library, which is a utility that provides a framework for setup, generation and verification of proofs. It uses an FGL class which mimics a finite field, and it is required by some functions that provide the _pilcom_ package.
8
8
9
9
## Execute code
10
10
11
-
First of all, under the scope of an asynchronous function called `execute`, we parse the provided PIL code (which is, in our case, `main.pil`) into a **Javascript** object using the `compile` function of **pilcom**.
11
+
First of all, under the scope of an asynchronous function called _execute_, we parse the provided PIL code (which is, in our case, _main.pil_) into a _Javascript_ object using the _compile_ function of _pilcom_.
12
12
13
13
In code, we obtain the following;
14
14
@@ -24,12 +24,12 @@ async function execute() {
24
24
25
25
## Pilcom package
26
26
27
-
The **pilcom** package also provides two functions; `newConstPolsArray` and `newCommitPolsArray`. Both these functions use the `pil` object in order to create two crucial objects:
27
+
The _pilcom_ package also provides two functions; _newConstPolsArray_ and _newCommitPolsArray_. Both these functions use the _pil_ object in order to create two crucial objects:
28
28
29
-
1. First is the constant polynomials object `constPols`, which is created by the `newConstPolsArray` function, and
30
-
2. Second is the committed polynomials object `cmPols`, created by `newCommitPolsArray`.
29
+
1. First is the constant polynomials object _constPols_, which is created by the _newConstPolsArray_ function, and
30
+
2. Second is the committed polynomials object _cmPols_, created by _newCommitPolsArray_.
The above-mentioned objects contain useful information about the PIL itself, such as the provided length of the program `N`, the total number of constant polynomials and the total number of committed polynomials. Accessing these objects will allow us to fill the entire execution trace for that PIL.
48
+
The above-mentioned objects contain useful information about the PIL itself, such as the provided length of the program N, the total number of constant polynomials and the total number of committed polynomials. Accessing these objects allows us to fill the entire execution trace for that PIL.
49
49
50
50
A specific position of the execution trace can be accessed by using the syntax:
51
51
@@ -55,16 +55,16 @@ pols.Namespace.Polynomial[i]
55
55
56
56
Note that;
57
57
58
-
-`pols` points to one of the above-mentioned objects; `constPols` and `cmPols` objects
59
-
-`Namespace` is a specific `namespace` among the ones defined by the PIL files
60
-
-`Polynomial` refers to one of the polynomials defined under the scope of the `namespace`
58
+
-_pols_ points to one of the above-mentioned objects; _constPols_ and _cmPols_ objects
59
+
-_Namespace_ is a specific _namespace_ among the ones defined by the PIL files
60
+
-_Polynomial_ refers to one of the polynomials defined under the scope of the _namespace_
61
61
- index $i$ is an integer in the range $[0, N − 1]$, representing the row of the current polynomial
62
62
63
63
Using these, the polynomials can now be filled.
64
64
65
-
## `Main.pil` code example
65
+
## _Main.pil_ code example
66
66
67
-
In our example, we recall the `main.pil` seen in the [Connection arguments](connection-arguments.md) section about $4$-bit integers.
67
+
In our example, we recall the _main.pil_ seen in the [Connection arguments](connection-arguments.md) section about $4$-bit integers.
68
68
69
69
Since we are only allowed to use $4$-bit integers, inputs for the trace, which are also the ones introduced in the $\mathtt{Main.a}$ polynomial, is a chain of integers n ascending cyclically from $0$ to $15$.
70
70
@@ -117,9 +117,9 @@ async function buildcommittedPolynomials(cmPols, polDeg) {
117
117
}
118
118
```
119
119
120
-
Once the constant and committed polynomials have been filled in, we can check whether these polynomials actually satisfy the constraints defined in the PIL file, by using a function called `verifyPil`.
120
+
Once the constant and committed polynomials have been filled in, we can check whether these polynomials actually satisfy the constraints defined in the PIL file, by using a function called _verifyPil_.
121
121
122
-
Below is the piece of code that constructs the polynomials and checks the constraints. If the verification procedure fails, we should not proceed to the proof generation because it will lead to false proof. For the sake of brevity, we simply use the line ```// ... Previous Code``` to indicate where the PIL code being verified would be inserted.
122
+
Below is the piece of code that constructs the polynomials and checks the constraints. If the verification procedure fails, we should not proceed to the proof generation because it leads to false proof. For the sake of brevity, we simply use the line `// ... Previous Code` to indicate where the PIL code being verified would be inserted.
0 commit comments