|
| 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