Skip to content

Commit ffe5242

Browse files
authored
one (#96)
1 parent 32fc01a commit ffe5242

File tree

1 file changed

+128
-0
lines changed

1 file changed

+128
-0
lines changed
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
// Take a look at some other code,which is taken from https://github.com/JacobEberhardt/ZoKrates
2+
3+
pragma solidity ^0.5.0;
4+
5+
library Verifier
6+
{
7+
function ScalarField ()
8+
internal pure returns (uint256)
9+
{
10+
return 21888242871839275222246405745257275088548364400416034343698204186575808495617;
11+
}
12+
13+
14+
function NegateY( uint256 Y )
15+
internal pure returns (uint256)
16+
{
17+
uint q = 21888242871839275222246405745257275088696311157297823662689037894645226208583;
18+
return q - (Y % q);
19+
}
20+
21+
22+
/*
23+
* This implements the Solidity equivalent of the following Python code:
24+
25+
from py_ecc.bn128 import *
26+
27+
data = # ... arguments to function [in_vk, vk_gammaABC, in_proof, proof_inputs]
28+
29+
vk = [int(_, 16) for _ in data[0]]
30+
ic = [FQ(int(_, 16)) for _ in data[1]]
31+
proof = [int(_, 16) for _ in data[2]]
32+
inputs = [int(_, 16) for _ in data[3]]
33+
34+
it = iter(ic)
35+
ic = [(_, next(it)) for _ in it]
36+
vk_alpha = [FQ(_) for _ in vk[:2]]
37+
vk_beta = (FQ2(vk[2:4][::-1]), FQ2(vk[4:6][::-1]))
38+
vk_gamma = (FQ2(vk[6:8][::-1]), FQ2(vk[8:10][::-1]))
39+
vk_delta = (FQ2(vk[10:12][::-1]), FQ2(vk[12:14][::-1]))
40+
41+
assert is_on_curve(vk_alpha, b)
42+
assert is_on_curve(vk_beta, b2)
43+
assert is_on_curve(vk_gamma, b2)
44+
assert is_on_curve(vk_delta, b2)
45+
46+
proof_A = [FQ(_) for _ in proof[:2]]
47+
proof_B = (FQ2(proof[2:4][::-1]), FQ2(proof[4:-2][::-1]))
48+
proof_C = [FQ(_) for _ in proof[-2:]]
49+
50+
assert is_on_curve(proof_A, b)
51+
assert is_on_curve(proof_B, b2)
52+
assert is_on_curve(proof_C, b)
53+
54+
vk_x = ic[0]
55+
for i, s in enumerate(inputs):
56+
vk_x = add(vk_x, multiply(ic[i + 1], s))
57+
58+
check_1 = pairing(proof_B, proof_A)
59+
check_2 = pairing(vk_beta, neg(vk_alpha))
60+
check_3 = pairing(vk_gamma, neg(vk_x))
61+
check_4 = pairing(vk_delta, neg(proof_C))
62+
63+
ok = check_1 * check_2 * check_3 * check_4
64+
assert ok == FQ12.one()
65+
*/
66+
function Verify ( uint256[14] memory in_vk, uint256[] memory vk_gammaABC, uint256[8] memory in_proof, uint256[] memory proof_inputs )
67+
internal view returns (bool)
68+
{
69+
uint256 snark_scalar_field = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
70+
require( ((vk_gammaABC.length / 2) - 1) == proof_inputs.length );
71+
72+
// Compute the linear combination vk_x
73+
uint256[3] memory mul_input;
74+
uint256[4] memory add_input;
75+
bool success;
76+
uint m = 2;
77+
78+
// First two fields are used as the sum
79+
add_input[0] = vk_gammaABC[0];
80+
add_input[1] = vk_gammaABC[1];
81+
82+
// Performs a sum of gammaABC[0] + sum[ gammaABC[i+1]^proof_inputs[i] ]
83+
for (uint i = 0; i < proof_inputs.length; i++)
84+
{
85+
require( proof_inputs[i] < snark_scalar_field );
86+
mul_input[0] = vk_gammaABC[m++];
87+
mul_input[1] = vk_gammaABC[m++];
88+
mul_input[2] = proof_inputs[i];
89+
90+
assembly {
91+
// ECMUL, output to last 2 elements of `add_input`
92+
success := staticcall(sub(gas, 2000), 7, mul_input, 0x80, add(add_input, 0x40), 0x60)
93+
}
94+
require( success );
95+
96+
assembly {
97+
// ECADD
98+
success := staticcall(sub(gas, 2000), 6, add_input, 0xc0, add_input, 0x60)
99+
}
100+
require( success );
101+
}
102+
103+
uint[24] memory input = [
104+
// (proof.A, proof.B)
105+
in_proof[0], in_proof[1], // proof.A (G1)
106+
in_proof[2], in_proof[3], in_proof[4], in_proof[5], // proof.B (G2)
107+
108+
// (-vk.alpha, vk.beta)
109+
in_vk[0], NegateY(in_vk[1]), // -vk.alpha (G1)
110+
in_vk[2], in_vk[3], in_vk[4], in_vk[5], // vk.beta (G2)
111+
112+
// (-vk_x, vk.gamma)
113+
add_input[0], NegateY(add_input[1]), // -vk_x (G1)
114+
in_vk[6], in_vk[7], in_vk[8], in_vk[9], // vk.gamma (G2)
115+
116+
// (-proof.C, vk.delta)
117+
in_proof[6], NegateY(in_proof[7]), // -proof.C (G1)
118+
in_vk[10], in_vk[11], in_vk[12], in_vk[13] // vk.delta (G2)
119+
];
120+
121+
uint[1] memory out;
122+
assembly {
123+
success := staticcall(sub(gas, 2000), 8, input, 768, out, 0x20)
124+
}
125+
require(success);
126+
return out[0] != 0;
127+
}
128+
}

0 commit comments

Comments
 (0)