Refactor verifier contract: set verifying key in constructor

This commit is contained in:
Mark Spanbroek 2024-01-23 11:48:01 +01:00 committed by markspanbroek
parent ef32ad9c1b
commit d30dff1781
3 changed files with 30 additions and 32 deletions

View File

@ -146,6 +146,7 @@ library Pairing {
contract Verifier { contract Verifier {
using Pairing for *; using Pairing for *;
uint256 constant private snark_scalar_field = 21888242871839275222246405745257275088548364400416034343698204186575808495617; uint256 constant private snark_scalar_field = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
VerifyingKey private verifyingKey;
struct VerifyingKey { struct VerifyingKey {
Pairing.G1Point alpha1; Pairing.G1Point alpha1;
Pairing.G2Point beta2; Pairing.G2Point beta2;
@ -158,32 +159,30 @@ contract Verifier {
Pairing.G2Point B; Pairing.G2Point B;
Pairing.G1Point C; Pairing.G1Point C;
} }
function verifyingKey() internal pure returns (VerifyingKey memory vk) { constructor() {
vk.alpha1 = Pairing.G1Point(20491192805390485299153009773594534940189261866228447918068658471970481763042, 9383485363053290200918347156157836566562967994039712273449902621266178545958); verifyingKey.alpha1 = Pairing.G1Point(20491192805390485299153009773594534940189261866228447918068658471970481763042, 9383485363053290200918347156157836566562967994039712273449902621266178545958);
vk.beta2 = Pairing.G2Point([4252822878758300859123897981450591353533073413197771768651442665752259397132,6375614351688725206403948262868962793625744043794305715222011528459656738731], [21847035105528745403288232691147584728191162732299865338377159692350059136679,10505242626370262277552901082094356697409835680220590971873171140371331206856]); verifyingKey.beta2 = Pairing.G2Point([4252822878758300859123897981450591353533073413197771768651442665752259397132,6375614351688725206403948262868962793625744043794305715222011528459656738731], [21847035105528745403288232691147584728191162732299865338377159692350059136679,10505242626370262277552901082094356697409835680220590971873171140371331206856]);
vk.gamma2 = Pairing.G2Point([11559732032986387107991004021392285783925812861821192530917403151452391805634,10857046999023057135944570762232829481370756359578518086990519993285655852781], [4082367875863433681332203403145435568316851327593401208105741076214120093531,8495653923123431417604973247489272438418190587263600148770280649306958101930]); verifyingKey.gamma2 = Pairing.G2Point([11559732032986387107991004021392285783925812861821192530917403151452391805634,10857046999023057135944570762232829481370756359578518086990519993285655852781], [4082367875863433681332203403145435568316851327593401208105741076214120093531,8495653923123431417604973247489272438418190587263600148770280649306958101930]);
vk.delta2 = Pairing.G2Point([16947967852917776612242666765339055140004530219040719566241973405926209896589,9526465944650138768726332063321262597514193803543146241262920033512923206833], [8391255886665123549932056926338579244742743577262957977406729945277596579696,19350668523204772149977938696677933779621485674406066708436704188235339847628]); verifyingKey.delta2 = Pairing.G2Point([16947967852917776612242666765339055140004530219040719566241973405926209896589,9526465944650138768726332063321262597514193803543146241262920033512923206833], [8391255886665123549932056926338579244742743577262957977406729945277596579696,19350668523204772149977938696677933779621485674406066708436704188235339847628]);
vk.IC = new Pairing.G1Point[](4); verifyingKey.IC.push(Pairing.G1Point(2685717341061384289974985759706305556965509240536260442727245444252129889599, 21827535600902499280458695057256182457185285685995970634461174274051979800815));
vk.IC[0] = Pairing.G1Point(2685717341061384289974985759706305556965509240536260442727245444252129889599, 21827535600902499280458695057256182457185285685995970634461174274051979800815); verifyingKey.IC.push(Pairing.G1Point(13158415194355348546090070151711085027834066488127676886518524272551654481129, 18831701962118195025265682681702066674741422770850028135520336928884612556978));
vk.IC[1] = Pairing.G1Point(13158415194355348546090070151711085027834066488127676886518524272551654481129, 18831701962118195025265682681702066674741422770850028135520336928884612556978); verifyingKey.IC.push(Pairing.G1Point(20882269691461568155321689204947751047717828445545223718893788782534717197527, 11996193054822748526485644723594571195813487505803351159052936325857690315211));
vk.IC[2] = Pairing.G1Point(20882269691461568155321689204947751047717828445545223718893788782534717197527, 11996193054822748526485644723594571195813487505803351159052936325857690315211); verifyingKey.IC.push(Pairing.G1Point(18155166643053044822201627105588517913195535693446564472247126736722594445000, 13816319482622393060406816684195314200198627617641073470088058848129378231754));
vk.IC[3] = Pairing.G1Point(18155166643053044822201627105588517913195535693446564472247126736722594445000, 13816319482622393060406816684195314200198627617641073470088058848129378231754);
} }
function verify(uint[] memory input, Proof memory proof) internal view returns (uint) { function verify(uint[] memory input, Proof memory proof) internal view returns (uint) {
VerifyingKey memory vk = verifyingKey(); require(input.length + 1 == verifyingKey.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);
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(verifyingKey.IC[i + 1], input[i]));
} }
vk_x = Pairing.addition(vk_x, vk.IC[0]); vk_x = Pairing.addition(vk_x, verifyingKey.IC[0]);
if (!Pairing.pairingProd4( if (!Pairing.pairingProd4(
Pairing.negate(proof.A), proof.B, Pairing.negate(proof.A), proof.B,
vk.alpha1, vk.beta2, verifyingKey.alpha1, verifyingKey.beta2,
vk_x, vk.gamma2, vk_x, verifyingKey.gamma2,
proof.C, vk.delta2 proof.C, verifyingKey.delta2
)) return 1; )) return 1;
return 0; return 0;
} }

View File

@ -34,10 +34,10 @@ for (const network of await readdir(networksPath)) {
let icParts = '' let icParts = ''
for (let index = 0; index < icLength; index++) { for (let index = 0; index < icLength; index++) {
if (index > 0) { if (index > 0) {
icParts = icParts + '\n ' icParts = icParts + '\n '
} }
let ic = verificationKey['IC'][index] let ic = verificationKey['IC'][index]
icParts = icParts + 'vk.IC[' + index + '] = Pairing.G1Point(' + G1ToSolidity(ic) + ');' icParts = icParts + 'verifyingKey.IC.push(Pairing.G1Point(' + G1ToSolidity(ic) + '));'
} }
const inputLength = verificationKey['nPublic'] const inputLength = verificationKey['nPublic']

View File

@ -146,6 +146,7 @@ library Pairing {
contract Verifier { contract Verifier {
using Pairing for *; using Pairing for *;
uint256 constant private snark_scalar_field = 21888242871839275222246405745257275088548364400416034343698204186575808495617; uint256 constant private snark_scalar_field = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
VerifyingKey private verifyingKey;
struct VerifyingKey { struct VerifyingKey {
Pairing.G1Point alpha1; Pairing.G1Point alpha1;
Pairing.G2Point beta2; Pairing.G2Point beta2;
@ -158,29 +159,27 @@ contract Verifier {
Pairing.G2Point B; Pairing.G2Point B;
Pairing.G1Point C; Pairing.G1Point C;
} }
function verifyingKey() internal pure returns (VerifyingKey memory vk) { constructor() {
vk.alpha1 = Pairing.G1Point(<%vk_alpha1%>); verifyingKey.alpha1 = Pairing.G1Point(<%vk_alpha1%>);
vk.beta2 = Pairing.G2Point(<%vk_beta2%>); verifyingKey.beta2 = Pairing.G2Point(<%vk_beta2%>);
vk.gamma2 = Pairing.G2Point(<%vk_gamma2%>); verifyingKey.gamma2 = Pairing.G2Point(<%vk_gamma2%>);
vk.delta2 = Pairing.G2Point(<%vk_delta2%>); verifyingKey.delta2 = Pairing.G2Point(<%vk_delta2%>);
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(uint[] memory input, Proof memory proof) internal view returns (uint) {
VerifyingKey memory vk = verifyingKey(); require(input.length + 1 == verifyingKey.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);
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(verifyingKey.IC[i + 1], input[i]));
} }
vk_x = Pairing.addition(vk_x, vk.IC[0]); vk_x = Pairing.addition(vk_x, verifyingKey.IC[0]);
if (!Pairing.pairingProd4( if (!Pairing.pairingProd4(
Pairing.negate(proof.A), proof.B, Pairing.negate(proof.A), proof.B,
vk.alpha1, vk.beta2, verifyingKey.alpha1, verifyingKey.beta2,
vk_x, vk.gamma2, vk_x, verifyingKey.gamma2,
proof.C, vk.delta2 proof.C, verifyingKey.delta2
)) return 1; )) return 1;
return 0; return 0;
} }