Skip to content
This repository was archived by the owner on Oct 28, 2024. It is now read-only.

Commit b6f960d

Browse files
HarryRHarryR
HarryR
authored and
HarryR
committed
Fixed Miximus tests
1 parent 3a443a9 commit b6f960d

File tree

5 files changed

+182
-177
lines changed

5 files changed

+182
-177
lines changed

contracts/Miximus.sol

+11-18
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
*/
1919

2020
pragma solidity 0.4.24;
21-
pragma experimental ABIEncoderV2;
2221

2322
import "./Verifier.sol";
2423
import "./SnarkUtils.sol";
@@ -74,6 +73,7 @@ contract Miximus
7473
return tree.GetProof(leaf);
7574
}
7675

76+
7777
function GetExtHash()
7878
public view returns (uint256)
7979
{
@@ -92,40 +92,32 @@ contract Miximus
9292
}
9393

9494

95-
function VerifyProof( uint256 in_root, uint256 in_nullifier, uint256 in_exthash, uint256[2] proof_A, uint256[2][2] proof_B, uint256[2] proof_C )
95+
function VerifyProof( uint256 in_root, uint256 in_nullifier, uint256 in_exthash, uint256[8] proof )
9696
public view returns (bool)
9797
{
9898
uint256[] memory snark_input = new uint256[](3);
99-
10099
snark_input[0] = in_root;
101100
snark_input[1] = in_nullifier;
102101
snark_input[2] = in_exthash;
103102

104-
Verifier.Proof memory proof = Verifier.Proof(
105-
Pairing.G1Point(proof_A[0], proof_A[1]),
106-
Pairing.G2Point(proof_B[0], proof_B[1]),
107-
Pairing.G1Point(proof_C[0], proof_C[1])
108-
);
103+
uint256[14] memory vk;
104+
uint256[] memory vk_gammaABC;
105+
(vk, vk_gammaABC) = GetVerifyingKey();
109106

110-
Verifier.VerifyingKey memory vk;
111-
GetVerifyingKey(vk);
112-
113-
return Verifier.Verify( vk, proof, snark_input );
107+
return Verifier.Verify( vk, vk_gammaABC, proof, snark_input );
114108
}
115109

116110

117111
function Withdraw(
118112
uint256 in_root,
119113
uint256 in_nullifier,
120-
uint256[2] proof_A,
121-
uint256[2][2] proof_B,
122-
uint256[2] proof_C
114+
uint256[8] proof
123115
)
124116
public
125117
{
126118
require( false == nullifiers[in_nullifier] );
127119

128-
bool is_valid = VerifyProof(in_root, in_nullifier, GetExtHash(), proof_A, proof_B, proof_C);
120+
bool is_valid = VerifyProof(in_root, in_nullifier, GetExtHash(), proof);
129121

130122
require( is_valid );
131123

@@ -134,6 +126,7 @@ contract Miximus
134126
msg.sender.transfer(AMOUNT);
135127
}
136128

137-
function GetVerifyingKey (Verifier.VerifyingKey memory out_vk)
138-
internal view;
129+
130+
function GetVerifyingKey ()
131+
public view returns (uint256[14] out_vk, uint256[] out_gammaABC);
139132
}

contracts/TestableMiximus.sol

+9-128
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
pragma solidity 0.4.24;
2-
pragma experimental ABIEncoderV2;
3-
42

53
import "./Miximus.sol";
64
import "./Verifier.sol";
@@ -12,144 +10,27 @@ import "./Verifier.sol";
1210

1311
contract TestableMiximus is Miximus
1412
{
15-
Verifier.VerifyingKey internal m_vk;
13+
uint256[14] m_vk;
14+
uint256[] m_gammaABC;
1615

17-
constructor( uint256[2] alpha, uint256[2][2] beta, uint256[2][2] gamma, uint256[2][2] delta, uint256[] gammaABC )
16+
constructor( uint256[14] in_vk, uint256[] in_gammaABC )
1817
public
1918
{
20-
m_vk.alpha = Pairing.G1Point(alpha[0], alpha[1]);
21-
m_vk.beta = Pairing.G2Point(beta[0], beta[1]);
22-
m_vk.gamma = Pairing.G2Point(gamma[0], beta[1]);
23-
m_vk.delta = Pairing.G2Point(delta[0], delta[1]);
24-
25-
uint n_abc = gammaABC.length / 2;
26-
for (uint i = 0; i < n_abc; i += 2)
27-
{
28-
m_vk.gammaABC.push( Pairing.G1Point(gammaABC[i], gammaABC[i+1]) );
29-
}
19+
m_vk = in_vk;
20+
m_gammaABC = in_gammaABC;
3021
}
3122

32-
function NegateY( uint256 Y )
33-
internal pure returns (uint256)
34-
{
35-
uint q = 21888242871839275222246405745257275088696311157297823662689037894645226208583;
36-
return q - (Y % q);
37-
}
38-
39-
/*
40-
* This implements the Solidity equivalent of the following Python code:
41-
42-
from py_ecc.bn128 import *
43-
44-
data = # ... arguments to function [in_vk, vk_gammaABC, in_proof, proof_inputs]
4523

46-
vk = [int(_, 16) for _ in data[0]]
47-
ic = [FQ(int(_, 16)) for _ in data[1]]
48-
it = iter(ic)
49-
ic = [(_, next(it)) for _ in it]
50-
proof = [int(_, 16) for _ in data[2]]
51-
inputs = [int(_, 16) for _ in data[3]]
52-
53-
vk_alpha = [FQ(_) for _ in vk[:2]]
54-
vk_beta = (FQ2(vk[2:4]), FQ2(vk[4:6]))
55-
vk_gamma = (FQ2(vk[6:8]), FQ2(vk[8:10]))
56-
vk_delta = (FQ2(vk[10:12]), FQ2(vk[12:14]))
57-
58-
proof_A = [FQ(_) for _ in proof[:2]]
59-
proof_B = (FQ2(proof[2:4]), FQ2(proof[4:-2]))
60-
proof_C = [FQ(_) for _ in proof[-2:]]
61-
62-
vk_x = ic[0]
63-
for i, s in enumerate(inputs):
64-
vk_x = add(vk_x, multiply(ic[i + 1], s))
65-
66-
check_1 = pairing(proof_B, proof_A)
67-
check_2 = pairing(vk_beta, neg(vk_alpha))
68-
check_3 = pairing(vk_gamma, neg(vk_x))
69-
check_4 = pairing(vk_delta, neg(proof_C))
70-
71-
ok = check_1 * check_2 * check_3 * check_4
72-
assert ok == FQ12.one()
73-
*/
7424
function TestVerify ( uint256[14] in_vk, uint256[] vk_gammaABC, uint256[8] in_proof, uint256[] proof_inputs )
7525
public view returns (bool)
7626
{
77-
require( ((vk_gammaABC.length / 2) - 1) == proof_inputs.length );
78-
79-
// Compute the linear combination vk_x
80-
uint256[3] memory mul_input;
81-
uint256[4] memory add_input;
82-
bool success;
83-
uint m = 2;
84-
85-
// First two fields are used as the sum
86-
add_input[0] = vk_gammaABC[0];
87-
add_input[1] = vk_gammaABC[1];
88-
89-
// Performs a sum of gammaABC[0] + sum[ gammaABC[i+1]^proof_inputs[i] ]
90-
for (uint i = 0; i < proof_inputs.length; i++) {
91-
mul_input[0] = vk_gammaABC[m++];
92-
mul_input[1] = vk_gammaABC[m++];
93-
mul_input[2] = proof_inputs[i];
94-
95-
assembly {
96-
// ECMUL, output to last 2 elements of `add_input`
97-
success := staticcall(sub(gas, 2000), 7, mul_input, 0x80, add(add_input, 0x40), 0x60)
98-
}
99-
require( success );
100-
101-
assembly {
102-
// ECADD
103-
success := staticcall(sub(gas, 2000), 6, add_input, 0xc0, add_input, 0x60)
104-
}
105-
require( success );
106-
}
107-
108-
uint[24] memory input = [
109-
// (proof.A, proof.B)
110-
in_proof[0], in_proof[1], // proof.A (G1)
111-
in_proof[2], in_proof[3], in_proof[4], in_proof[5], // proof.B (G2)
112-
113-
// (-vk.alpha, vk.beta)
114-
in_vk[0], NegateY(in_vk[1]), // -vk.alpha (G1)
115-
in_vk[2], in_vk[3], in_vk[4], in_vk[5], // vk.beta (G2)
116-
117-
// (-vk_x, vk.gamma)
118-
add_input[0], NegateY(add_input[1]), // -vk_x (G1)
119-
in_vk[6], in_vk[7], in_vk[8], in_vk[9], // vk.gamma (G2)
120-
121-
// (-proof.C, vk.delta)
122-
in_proof[6], NegateY(in_proof[7]), // -proof.C (G1)
123-
in_vk[10], in_vk[11], in_vk[12], in_vk[13] // vk.delta (G2)
124-
];
125-
126-
uint[1] memory out;
127-
assembly {
128-
success := staticcall(sub(gas, 2000), 8, input, 768, out, 0x20)
129-
}
130-
require(success);
131-
return out[0] != 0;
27+
return Verifier.Verify(in_vk, vk_gammaABC, in_proof, proof_inputs);
13228
}
13329

134-
/*
135-
function GetVerifyingKey ()
136-
internal view returns (Verifier.VerifyingKey memory)
137-
{
138-
return m_vk;
139-
}
140-
*/
14130

142-
function GetVerifyingKey (Verifier.VerifyingKey memory vk)
143-
internal view
31+
function GetVerifyingKey ()
32+
public view returns (uint256[14] out_vk, uint256[] out_gammaABC)
14433
{
145-
vk.beta = Pairing.G2Point([0x23df5e88ef8c695a936273071fc2e9a5879000d8f2913c8005671f61a4a70450, 0x5bae69b8321c67e66a879485bd5aac2dd12ceeafd7f00f66b26321fbdeef2f], [0x1ca5a54c39f533a764a6aa55f419f7096154efc87f5c1ffb5d6f42635de7b377, 0x1642c8f546b5c22aab6c845becf1fbb51324de210f03dd9b2168e54e79d2ac98]);
146-
vk.gamma = Pairing.G2Point([0x283cbe4ec00a7643c188241d4fd9f355a5ef5152da1e9c3c9d63944497f6bd48, 0x17f03d61d33e192a13685aa92f16ae4e91e9e0161668dd851ebbdc93407ac45e], [0x2e852427ff695a858b4c3b3f92a37902c289d2a349115433202f9051469f24b, 0xf89dcea40987650ab1d6ef61b56e20eba020ee242b37ca410ef0707adf28491]);
147-
vk.delta = Pairing.G2Point([0x6df26e0f964cca91b63ff08fc3ff88afbf7987112a7a744b5212414de1d19c0, 0x224dd01e810047dd4c2cd6d9e61971d428d8be3fd4f905f773c1b5bf65ad39f8], [0x1d6d2db772e306fd6c4c7ff6b6a600d4858ef3ce916bac197f771e2e2df1fdea, 0x20b6776ea70b71d14608bac3aa8138bb929b33eec13f7b2fb14c98a08f5ee7b1]);
148-
vk.alpha = Pairing.G1Point(0x1ce2c55eb08dfa89aa5a6d4c6e154dc061b7e8957d8fe85a5f70844836bf8894, 0x1f1f893a9c27e8291657d34201af9b067d51d1a8ef3db7c22187395513c8178);
149-
vk.gammaABC = new Pairing.G1Point[](4);
150-
vk.gammaABC[0] = Pairing.G1Point(0x2a35065121197a468d9df1f24d9dd651ba24eadcc6751af5dae267072530a8d8, 0x515b91005d65dcc5bbc0d565724ad9cd0319c455555d45c74a3d23bee6e0848);
151-
vk.gammaABC[1] = Pairing.G1Point(0x2d8b52c31635db7c7121be2deee1f5ed8f7a138d55f311b84cc86159694973bb, 0x103f5af198ae40847d0b49d229116a26eee0e381050fee767cd6672f672adcd2);
152-
vk.gammaABC[2] = Pairing.G1Point(0x13fba7f73646725d4e8e68795c453b2661db11339aabfa09a3e3fbee34d72ebe, 0x49da6ff964ac686ca98e31b8c17539c8d55438d12fdde26fe6aac5a729d239a);
153-
vk.gammaABC[3] = Pairing.G1Point(0x2059f55d13bf8182e68e3d173584cebbb6dbcc4e9b8374f68473b81709c0b88b, 0x2647c112c905d12c414a7c5d7bb64b2dc42df9a61d9a74ecc44f140f461d65eb);
34+
return (m_vk, m_gammaABC);
15435
}
15536
}

contracts/Verifier.sol

+114
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,120 @@ library Verifier
3737
uint256[] input;
3838
}
3939

40+
41+
function NegateY( uint256 Y )
42+
internal pure returns (uint256)
43+
{
44+
uint q = 21888242871839275222246405745257275088696311157297823662689037894645226208583;
45+
return q - (Y % q);
46+
}
47+
48+
49+
/*
50+
* This implements the Solidity equivalent of the following Python code:
51+
52+
from py_ecc.bn128 import *
53+
54+
data = # ... arguments to function [in_vk, vk_gammaABC, in_proof, proof_inputs]
55+
56+
vk = [int(_, 16) for _ in data[0]]
57+
ic = [FQ(int(_, 16)) for _ in data[1]]
58+
proof = [int(_, 16) for _ in data[2]]
59+
inputs = [int(_, 16) for _ in data[3]]
60+
61+
it = iter(ic)
62+
ic = [(_, next(it)) for _ in it]
63+
vk_alpha = [FQ(_) for _ in vk[:2]]
64+
vk_beta = (FQ2(vk[2:4][::-1]), FQ2(vk[4:6][::-1]))
65+
vk_gamma = (FQ2(vk[6:8][::-1]), FQ2(vk[8:10][::-1]))
66+
vk_delta = (FQ2(vk[10:12][::-1]), FQ2(vk[12:14][::-1]))
67+
68+
assert is_on_curve(vk_alpha, b)
69+
assert is_on_curve(vk_beta, b2)
70+
assert is_on_curve(vk_gamma, b2)
71+
assert is_on_curve(vk_delta, b2)
72+
73+
proof_A = [FQ(_) for _ in proof[:2]]
74+
proof_B = (FQ2(proof[2:4][::-1]), FQ2(proof[4:-2][::-1]))
75+
proof_C = [FQ(_) for _ in proof[-2:]]
76+
77+
assert is_on_curve(proof_A, b)
78+
assert is_on_curve(proof_B, b2)
79+
assert is_on_curve(proof_C, b)
80+
81+
vk_x = ic[0]
82+
for i, s in enumerate(inputs):
83+
vk_x = add(vk_x, multiply(ic[i + 1], s))
84+
85+
check_1 = pairing(proof_B, proof_A)
86+
check_2 = pairing(vk_beta, neg(vk_alpha))
87+
check_3 = pairing(vk_gamma, neg(vk_x))
88+
check_4 = pairing(vk_delta, neg(proof_C))
89+
90+
ok = check_1 * check_2 * check_3 * check_4
91+
assert ok == FQ12.one()
92+
*/
93+
function Verify ( uint256[14] in_vk, uint256[] vk_gammaABC, uint256[8] in_proof, uint256[] proof_inputs )
94+
internal view returns (bool)
95+
{
96+
require( ((vk_gammaABC.length / 2) - 1) == proof_inputs.length );
97+
98+
// Compute the linear combination vk_x
99+
uint256[3] memory mul_input;
100+
uint256[4] memory add_input;
101+
bool success;
102+
uint m = 2;
103+
104+
// First two fields are used as the sum
105+
add_input[0] = vk_gammaABC[0];
106+
add_input[1] = vk_gammaABC[1];
107+
108+
// Performs a sum of gammaABC[0] + sum[ gammaABC[i+1]^proof_inputs[i] ]
109+
for (uint i = 0; i < proof_inputs.length; i++) {
110+
mul_input[0] = vk_gammaABC[m++];
111+
mul_input[1] = vk_gammaABC[m++];
112+
mul_input[2] = proof_inputs[i];
113+
114+
assembly {
115+
// ECMUL, output to last 2 elements of `add_input`
116+
success := staticcall(sub(gas, 2000), 7, mul_input, 0x80, add(add_input, 0x40), 0x60)
117+
}
118+
require( success );
119+
120+
assembly {
121+
// ECADD
122+
success := staticcall(sub(gas, 2000), 6, add_input, 0xc0, add_input, 0x60)
123+
}
124+
require( success );
125+
}
126+
127+
uint[24] memory input = [
128+
// (proof.A, proof.B)
129+
in_proof[0], in_proof[1], // proof.A (G1)
130+
in_proof[2], in_proof[3], in_proof[4], in_proof[5], // proof.B (G2)
131+
132+
// (-vk.alpha, vk.beta)
133+
in_vk[0], NegateY(in_vk[1]), // -vk.alpha (G1)
134+
in_vk[2], in_vk[3], in_vk[4], in_vk[5], // vk.beta (G2)
135+
136+
// (-vk_x, vk.gamma)
137+
add_input[0], NegateY(add_input[1]), // -vk_x (G1)
138+
in_vk[6], in_vk[7], in_vk[8], in_vk[9], // vk.gamma (G2)
139+
140+
// (-proof.C, vk.delta)
141+
in_proof[6], NegateY(in_proof[7]), // -proof.C (G1)
142+
in_vk[10], in_vk[11], in_vk[12], in_vk[13] // vk.delta (G2)
143+
];
144+
145+
uint[1] memory out;
146+
assembly {
147+
success := staticcall(sub(gas, 2000), 8, input, 768, out, 0x20)
148+
}
149+
require(success);
150+
return out[0] != 0;
151+
}
152+
153+
40154
function Verify (VerifyingKey memory vk, ProofWithInput memory pwi)
41155
internal view returns (bool)
42156
{

migrations/2_deploy_contracts.js

+22-5
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,35 @@ const Verifier = artifacts.require('Verifier.sol');
22
const TestableMiximus = artifacts.require('TestableMiximus.sol');
33

44

5+
6+
let list_flatten = (l) => {
7+
return [].concat.apply([], l);
8+
};
9+
10+
11+
let vk_to_flat = (vk) => {
12+
return [
13+
list_flatten([
14+
vk.alpha[0], vk.alpha[1],
15+
list_flatten(vk.beta),
16+
list_flatten(vk.gamma),
17+
list_flatten(vk.delta),
18+
]),
19+
list_flatten(vk.gammaABC)
20+
];
21+
};
22+
23+
524
async function doDeploy( deployer, network )
625
{
726
await deployer.deploy(Verifier);
827
await deployer.link(Verifier, TestableMiximus);
928

1029
var vk = require('../zksnark_element/miximus.vk.json');
30+
let [vk_flat, vk_flat_IC] = vk_to_flat(vk);
1131
await deployer.deploy(TestableMiximus,
12-
vk.alpha,
13-
vk.beta,
14-
vk.gamma,
15-
vk.delta,
16-
[].concat(...vk.gammaABC)
32+
vk_flat,
33+
vk_flat_IC
1734
);
1835
}
1936

0 commit comments

Comments
 (0)