fix verifier.sol bugs, port it to Solidity 6
This commit is contained in:
parent
88a722981f
commit
27ad5eb7c5
@ -256,7 +256,7 @@ pub fn create_verifier_sol(params: &Parameters<Bn256>) -> String {
|
|||||||
let x_c1 = repr_to_big(x.c1.into_repr());
|
let x_c1 = repr_to_big(x.c1.into_repr());
|
||||||
let y_c0 = repr_to_big(y.c0.into_repr());
|
let y_c0 = repr_to_big(y.c0.into_repr());
|
||||||
let y_c1 = repr_to_big(y.c1.into_repr());
|
let y_c1 = repr_to_big(y.c1.into_repr());
|
||||||
format!("[{}, {}], [{}, {}]", x_c0, x_c1, y_c0, y_c1)
|
format!("[{}, {}], [{}, {}]", x_c1, x_c0, y_c1, y_c0)
|
||||||
};
|
};
|
||||||
|
|
||||||
let template = template.replace("<%vk_alfa1%>", &*p1_to_str(¶ms.vk.alpha_g1));
|
let template = template.replace("<%vk_alfa1%>", &*p1_to_str(¶ms.vk.alpha_g1));
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
// fixed linter warnings
|
// fixed linter warnings
|
||||||
// added require error messages
|
// added require error messages
|
||||||
//
|
//
|
||||||
pragma solidity ^0.5.0;
|
pragma solidity ^0.6.0;
|
||||||
library Pairing {
|
library Pairing {
|
||||||
struct G1Point {
|
struct G1Point {
|
||||||
uint X;
|
uint X;
|
||||||
@ -52,7 +52,7 @@ library Pairing {
|
|||||||
return G1Point(0, 0);
|
return G1Point(0, 0);
|
||||||
return G1Point(p.X, q - (p.Y % q));
|
return G1Point(p.X, q - (p.Y % q));
|
||||||
}
|
}
|
||||||
/// @return the sum of two points of G1
|
/// @return r the sum of two points of G1
|
||||||
function addition(G1Point memory p1, G1Point memory p2) internal view returns (G1Point memory r) {
|
function addition(G1Point memory p1, G1Point memory p2) internal view returns (G1Point memory r) {
|
||||||
uint[4] memory input;
|
uint[4] memory input;
|
||||||
input[0] = p1.X;
|
input[0] = p1.X;
|
||||||
@ -62,13 +62,13 @@ library Pairing {
|
|||||||
bool success;
|
bool success;
|
||||||
// solium-disable-next-line security/no-inline-assembly
|
// solium-disable-next-line security/no-inline-assembly
|
||||||
assembly {
|
assembly {
|
||||||
success := staticcall(sub(gas, 2000), 6, input, 0xc0, r, 0x60)
|
success := staticcall(sub(gas(), 2000), 6, input, 0xc0, r, 0x60)
|
||||||
// Use "invalid" to make gas estimation work
|
// Use "invalid" to make gas estimation work
|
||||||
switch success case 0 { invalid() }
|
switch success case 0 { invalid() }
|
||||||
}
|
}
|
||||||
require(success,"pairing-add-failed");
|
require(success,"pairing-add-failed");
|
||||||
}
|
}
|
||||||
/// @return the product of a point on G1 and a scalar, i.e.
|
/// @return r the product of a point on G1 and a scalar, i.e.
|
||||||
/// p == p.scalar_mul(1) and p.addition(p) == p.scalar_mul(2) for all points p.
|
/// p == p.scalar_mul(1) and p.addition(p) == p.scalar_mul(2) for all points p.
|
||||||
function scalar_mul(G1Point memory p, uint s) internal view returns (G1Point memory r) {
|
function scalar_mul(G1Point memory p, uint s) internal view returns (G1Point memory r) {
|
||||||
uint[3] memory input;
|
uint[3] memory input;
|
||||||
@ -78,7 +78,7 @@ library Pairing {
|
|||||||
bool success;
|
bool success;
|
||||||
// solium-disable-next-line security/no-inline-assembly
|
// solium-disable-next-line security/no-inline-assembly
|
||||||
assembly {
|
assembly {
|
||||||
success := staticcall(sub(gas, 2000), 7, input, 0x80, r, 0x60)
|
success := staticcall(sub(gas(), 2000), 7, input, 0x80, r, 0x60)
|
||||||
// Use "invalid" to make gas estimation work
|
// Use "invalid" to make gas estimation work
|
||||||
switch success case 0 { invalid() }
|
switch success case 0 { invalid() }
|
||||||
}
|
}
|
||||||
@ -106,7 +106,7 @@ library Pairing {
|
|||||||
bool success;
|
bool success;
|
||||||
// solium-disable-next-line security/no-inline-assembly
|
// solium-disable-next-line security/no-inline-assembly
|
||||||
assembly {
|
assembly {
|
||||||
success := staticcall(sub(gas, 2000), 8, add(input, 0x20), mul(inputSize, 0x20), out, 0x20)
|
success := staticcall(sub(gas(), 2000), 8, add(input, 0x20), mul(inputSize, 0x20), out, 0x20)
|
||||||
// Use "invalid" to make gas estimation work
|
// Use "invalid" to make gas estimation work
|
||||||
switch success case 0 { invalid() }
|
switch success case 0 { invalid() }
|
||||||
}
|
}
|
||||||
@ -181,43 +181,45 @@ contract Verifier {
|
|||||||
vk.IC = new Pairing.G1Point[](<%vk_ic_length%>);
|
vk.IC = new Pairing.G1Point[](<%vk_ic_length%>);
|
||||||
<%vk_ic_pts%>
|
<%vk_ic_pts%>
|
||||||
}
|
}
|
||||||
function verify(uint[] memory input, Proof memory proof) internal view returns (uint) {
|
function verify(Proof memory proof, uint[<%vk_input_length%>] memory input) internal view returns (bool) {
|
||||||
uint256 snark_scalar_field = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
|
uint256 snark_scalar_field = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
|
||||||
VerifyingKey memory vk = verifyingKey();
|
VerifyingKey memory vk = verifyingKey();
|
||||||
require(input.length + 1 == vk.IC.length, "verifier-bad-input");
|
require(input.length + 1 == vk.IC.length, "verifier-bad-input");
|
||||||
// Compute the linear combination vk_x
|
// Compute the linear combination vk_x
|
||||||
Pairing.G1Point memory vk_x = Pairing.G1Point(0, 0);
|
Pairing.G1Point memory vk_x = Pairing.G1Point(0, 0);
|
||||||
|
vk_x = Pairing.addition(vk_x, vk.IC[0]);
|
||||||
for (uint i = 0; i < input.length; i++) {
|
for (uint i = 0; i < input.length; i++) {
|
||||||
require(input[i] < snark_scalar_field, "verifier-gte-snark-scalar-field");
|
require(input[i] < snark_scalar_field, "verifier-gte-snark-scalar-field");
|
||||||
vk_x = Pairing.addition(vk_x, Pairing.scalar_mul(vk.IC[i + 1], input[i]));
|
vk_x = Pairing.addition(vk_x, Pairing.scalar_mul(vk.IC[i + 1], input[i]));
|
||||||
}
|
}
|
||||||
vk_x = Pairing.addition(vk_x, vk.IC[0]);
|
return Pairing.pairingProd4(
|
||||||
if (!Pairing.pairingProd4(
|
|
||||||
Pairing.negate(proof.A), proof.B,
|
Pairing.negate(proof.A), proof.B,
|
||||||
vk.alfa1, vk.beta2,
|
vk.alfa1, vk.beta2,
|
||||||
vk_x, vk.gamma2,
|
vk_x, vk.gamma2,
|
||||||
proof.C, vk.delta2
|
proof.C, vk.delta2
|
||||||
)) return 1;
|
);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
function verifyProof(
|
function verifyProof(
|
||||||
uint[2] memory a,
|
uint[2] memory a,
|
||||||
uint[2][2] memory b,
|
uint[2][2] memory b,
|
||||||
uint[2] memory c,
|
uint[2] memory c,
|
||||||
uint[<%vk_input_length%>] memory input
|
uint[<%vk_input_length%>] memory input
|
||||||
) public view returns (bool r) {
|
) public view returns (bool) {
|
||||||
Proof memory proof;
|
Proof memory _proof;
|
||||||
proof.A = Pairing.G1Point(a[0], a[1]);
|
_proof.A = Pairing.G1Point(a[0], a[1]);
|
||||||
proof.B = Pairing.G2Point([b[0][0], b[0][1]], [b[1][0], b[1][1]]);
|
_proof.B = Pairing.G2Point([b[0][0], b[0][1]], [b[1][0], b[1][1]]);
|
||||||
proof.C = Pairing.G1Point(c[0], c[1]);
|
_proof.C = Pairing.G1Point(c[0], c[1]);
|
||||||
return verify(input, proof);
|
return verify(_proof, input);
|
||||||
}
|
}
|
||||||
function verifyProof(bytes memory proof, uint[<%vk_input_length%>] memory inputs) public view returns (bool r) {
|
function verifyProof(
|
||||||
|
bytes memory proof,
|
||||||
|
uint[<%vk_input_length%>] memory input
|
||||||
|
) public view returns (bool) {
|
||||||
uint[8] memory p = abi.decode(proof, (uint[8]));
|
uint[8] memory p = abi.decode(proof, (uint[8]));
|
||||||
Proof memory proof;
|
Proof memory _proof;
|
||||||
proof.A = Pairing.G1Point(p[0], p[1]);
|
_proof.A = Pairing.G1Point(p[0], p[1]);
|
||||||
proof.B = Pairing.G2Point([p[2], p[3]], [p[4], p[5]]);
|
_proof.B = Pairing.G2Point([p[2], p[3]], [p[4], p[5]]);
|
||||||
proof.C = Pairing.G1Point(p[6], c[7]);
|
_proof.C = Pairing.G1Point(p[6], p[7]);
|
||||||
return verify(inputs, proof) == 0;
|
return verify(_proof, input);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user