Skip to content

Commit 161d1e4

Browse files
authored
Merge pull request #20 from ConsenSys/zkp-tutorial
zkp-tutorial with even/odd numbers
2 parents 8d06225 + d0ea527 commit 161d1e4

File tree

1 file changed

+214
-0
lines changed

1 file changed

+214
-0
lines changed
Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
Zero Knowledge Proofs involve proving that a set of values have *some property* without revealing anything else about those values.
2+
This is done by running some function over the private values, and then making the result of that function public.
3+
4+
5+
The purpose of this example is to show how we can use simple algebra to prove a specific property about a set of numbers without revealing anything else about those numbers.
6+
7+
8+
Suppose you are in posession of two numbers, $a$ and $b$.
9+
10+
The property about $a$ and $b$ you are trying to prove is that one of them is even, and the other one is odd.
11+
You want to do this without leaking anything else about $a$ or $b$.
12+
13+
### The Intuition Behind the Proof
14+
15+
Lets say you start out with one even number and one odd number. For clarity's sake, lets suppose that $a$ is odd and that $b$ is even.
16+
17+
In step 1, I will give you two odd numbers and you calculate the two values of $x*a$ and $y*b$.
18+
19+
Since both $x$ and $a$ are odd, it follows that $x*a$ is odd.
20+
*This follows from the fact that the product of two odd numbers is always odd.*
21+
22+
On the other hand, since $y$ is odd, but $b$ is even, $y*b$ must be even.
23+
*This follows from the fact that any number multiplied by an even number is even.*
24+
25+
In other words, multiplying any number by an odd number *maintains its parity*. Therefore, after step 1, you have the same amount of odd numbers and the same amount of even numbers that you started with.
26+
27+
28+
Now, you compute $final\_result = x*a + y*b$ and hand that value over to the verifier. The verifier cannot glean information about the values of $a$ and $b$ but they can still verify your claim about $a$ and $b$ by checking whether or not $final\_result$ is odd.
29+
30+
If $final\_result$ is odd, then either $x*a$ is odd and $y*b$ is even or vica-versa.
31+
*This follows from the fact that the sum of two integers is always even unless exactly one of its summands is odd and the other one is even.*
32+
33+
If $final\_result$ is odd, then the verifier **accepts** the proof. Otherwise, the verifier **rejects** the proof.
34+
35+
### The Interaction Between the Prover and the Verifier
36+
37+
### Commitment Functions
38+
In order for the zero-knowledge proof to work, we will need something called a **commitment**. I won't be explaining much about commitments for right now (read more about them here).
39+
All you need to know about **commitments** right now is the following:
40+
41+
42+
a `commitment` is a function whose input and output are both positive integers.
43+
44+
`````go
45+
func commitment(uint x) uint{
46+
var y uint;
47+
...
48+
return y;
49+
}
50+
`````
51+
52+
Keep this in mind, we'll be coming back to commitments later.
53+
54+
### The Back And Forth between Prover and Verifier
55+
In the following back and forth, the prover and the verifier will be sharing information with eachother. In real life, they would be sending the information
56+
to a shared database such as a smart contract. For this example, we will convey this idea by creating a map that the user and the verifier will pass back and forth between eachother.
57+
The prover will be passing their private values into functions and only inserting the **return** values of those functions into the shared map.
58+
59+
Each party will use values put into the shared map to compute their respective sides of the proof.
60+
61+
62+
63+
````go
64+
shared_info := map[string]int{
65+
"prover_commitment_a": 0,
66+
"prover_commitment_b": 0,
67+
"verifier_oddInt_x": 0,
68+
"verifier_oddInt_y": 0,
69+
"prover_finalResult":0,
70+
"verifier_acceptOrReject": 0,
71+
}
72+
````
73+
74+
**You (The Prover)**: You start out by picking two numbers, `a` and `b`. One of these numbers is even. One of them is odd. You do the following:
75+
76+
`````go
77+
var comm_a := commitment(a);
78+
var comm_b := commitment(b);
79+
shared_info["prover_commitment_a"] := comm_a;
80+
shared_info["prover_commitment_b"] := comm_b;
81+
`````
82+
Now, the shared map looks as follows:
83+
84+
````go
85+
shared_info := map[string]int{
86+
"prover_commitment_a": comm_a,
87+
"prover_commitment_b": comm_b,
88+
"verifier_oddInt_x": 0,
89+
"verifier_oddInt_y": 0,
90+
"prover_finalResult":0,
91+
"verifier_acceptOrReject": 0,
92+
}
93+
````
94+
95+
**Me (The verifier)**:I pick two *odd* random numbers. Let's call these random odd numbers `x` and `y`.I add `x` and `y` to the shared map.
96+
````go
97+
shared_info := map[string]int{
98+
"prover_commitment_a": comm_a,
99+
"prover_commitment_b": comm_b,
100+
"verifier_oddInt_x": x,
101+
"verifier_oddInt_y": y,
102+
"prover_finalResult":0,
103+
"verifier_acceptOrReject": 0,
104+
}
105+
````
106+
107+
**You (The prover)**: You do the following:
108+
````go
109+
var proof := a*shared_info["verifier_oddInt_x"] + b*shared_info["verifier_oddInt_y"];
110+
shared_info["prover_finalResult"] = proof;
111+
````
112+
Now the shared map looks like this:
113+
114+
````go
115+
shared_info := map[string]int{
116+
"prover_commitment_a": comm_a,
117+
"prover_commitment_b": comm_b,
118+
"verifier_oddInt_x": x,
119+
"verifier_oddInt_y": y,
120+
"prover_finalResult":proof,
121+
"verifier_acceptOrReject": 0,
122+
}
123+
````
124+
**Me**: Next, I verify that you computed your proof correctly, by doing the following:
125+
````go
126+
func check_final_result(int final_result) bool{
127+
return (commitment(shared_info["prover_finalResult"]) == x*shared_info["prover_commitment_a"] + y*shared_info["prover_commitment_b"]);
128+
129+
**/
130+
131+
}
132+
````
133+
Now is a good time to talk about the other properties of `commitment` that I failed to mention above. The following two statements must be true for the `commitment` function:
134+
````go
135+
commitment(x) + commitment(y) == commitment(x+y) // True
136+
a*commitment(x) == commitment(a*x) // True
137+
````
138+
Given these properties, you can see that :
139+
140+
`````go
141+
commitment(shared_info[prover_finalResult])
142+
= commitment(x*a + y*b)
143+
= commitment(x*a) + commitment(y*b)
144+
= x*commitment(a) + y*commitment(b)
145+
= x*shared_info[prover_commitment_a] + y*shared_info[prover_commitment_b];`
146+
`````
147+
148+
149+
150+
151+
The next step is checking the parity of `prover_finalResult`. If `prover_finalResult` is odd, I accept your proof. If `prover_finalResult` is even, I reject your proof.
152+
153+
`````go
154+
func is_proof_valid(int final_result) bool{
155+
if(check_final_result(final_result)){
156+
return (final_result % 2 != 0); //return true if final_result is odd, else return false
157+
}
158+
return false;
159+
}
160+
var proofValiditiy:=is_proof_valid(shared_info["prover_finalResult"]);
161+
shared_info["verifier_acceptOrReject"]:=proofValidity;
162+
`````
163+
The final object will look like this:
164+
165+
````go
166+
shared_info := map[string]int{
167+
"prover_commitment_a": comm_a,
168+
"prover_commitment_b": comm_b,
169+
"verifier_oddInt_x": x,
170+
"verifier_oddInt_y": y,
171+
"prover_finalResult":proof,
172+
"verifier_acceptOrReject": proofValidity
173+
}
174+
````
175+
176+
### Logic Table for Summing Integers of Different Parity
177+
178+
+:----:+:----:+:----:+:----:+:----:+
179+
| even | $+$ | odd | = | even |
180+
+------+------+------+------+------+
181+
| even | $+$ | even | = | even |
182+
+------+------+------+------+------+
183+
| odd | $*$ | even | = | odd |
184+
+------+------+------+------+------+
185+
| odd | $*$ | odd | = | even |
186+
+------+------+------+------+------+
187+
188+
+:----:+:---:+:----:+
189+
| even | odd | odd |
190+
+------+-----+------+
191+
| even | even| even |
192+
+------+-----+------+
193+
| odd | even| odd |
194+
+------+-----+------+
195+
| odd | odd | even |
196+
+------+-----+------+
197+
198+
199+
200+
201+
202+
+:----:+:----:+:----:+:----:+:----:+
203+
| even | $*$ | odd | = | even |
204+
+------+------+------+------+------+
205+
| even | $*$ | even | = | even |
206+
+------+------+------+------+------+
207+
| odd | $*$ | even | = | odd |
208+
+------+------+------+------+------+
209+
| odd | $*$ | odd | = | even |
210+
+------+------+------+------+------+
211+
212+
213+
214+

0 commit comments

Comments
 (0)