The witness vector is a
By convention, the first element is always
Let's take the polynomial
R1CS requires one multiplication per constraint.
Our example must be written as:
Our witness vector would be:
For example,
The main goal is to produce a list of formulas that contain exactly one multiplication per formula.
It will have the form:
Matrix
Witness has 4 elements, each of our matrices will have 4 columns. The number of rows corresponds to the number of constraints in the circuit. 1 row in our case.
A Python script is available for this example.
R1CS requires one multiplication per constraint.
Our example must be written as:
Our witness vector will have 8 elements:
As the example is written, there are:
- an output term for each constraint (here
$v_1, v_2, out$ ) - a left term (here
$x, v_1, v_2$ ) - a right term (here
$y, z, u$ )
Each term will be represented by the matrix
The r1cs-ex2.py Python script is available for this example.
"Addition is free" in ZK SNARKs. We don't have to create additional constraint for addition operation.
The r1cs-ex3.py Python script is available for this example.
Note: To multiply by a constant, the same can be done (if multiply by 2, then set 2 in the matrix value).
Let's use:
This expression will be divided into:
Our
The r1cs-ex4.py Python script is available for this example.
Real-world implementations use modular arithmetic instead of traditional arithmetic.
So, encoding for example
See the r1cs-modular.py Python script for further testing.
In the circom language, math is done modulo
So, as the r1cs-negativeCircom.py script shows,
Let's retake Example 1 with circom.
The file [circom-ex1.circom] can be compiled using circom circom-ex1.circom --r1cs --sym
.
Then, details of the R1CS circuit can be seen with snarkjs r1cs print circom-ex1.r1cs
.
The results will look different that our previous result. Circom solution is:
The form is a little bit different. It is now
To test the example, we will recompile it with --wasm
. Then, we create the solution we want to test. We will test
# compile and create directory
circom circom-ex1.circom --r1cs --sym --wasm
# enter dir
pushd circom-ex1_js
# Write our x and y inputs
echo '{"x": "41", "y": "103"}' > input.json
# Generate the witness
node generate_witness.js circom-ex1.wasm input.json witness.wtns
# Export the witness as JSON
snarkjs wtns export json witness.wtns witness.json
# Check the witness against the R1CS circuit
snarkjs wtns check ../circom-ex1.r1cs witness.wtns
# print the witness
cat witness.json
# quit dir
popd
The circom-ex2.circom file translates this example in Circom language.
Let's use:
This expression will be divided into:
The circom-ex4.circom file translates those constraints in Circom language.
# compile and create directory
circom circom-ex4.circom --r1cs --sym --wasm
# enter dir
pushd circom-ex4_js
# Write our x and y inputs
echo '{"x": "1", "y": "2"}' > input.json
# Generate the witness
node generate_witness.js circom-ex4.wasm input.json witness.wtns
# Export the witness as JSON
snarkjs wtns export json witness.wtns witness.json
# Check the witness against the R1CS circuit
snarkjs wtns check ../circom-ex4.r1cs witness.wtns
# print the witness
cat witness.json
# quit dir
popd