WIP: Add test for verifier

Needs valid values to test points that exist on the curve as well as a valid proof. Waiting on https://github.com/status-im/nim-codex/pull/101 to get valid values.

TODO: Convert Bn254.sol contract to a generic witnet EllipticCurve.sol contract and fill in values as needed for the Bn254 curve.
This commit is contained in:
Eric Mastro 2022-06-02 17:14:48 +10:00
parent 976ae66cab
commit 32ff556691
No known key found for this signature in database
GPG Key ID: 141E3048D95A4E63
4 changed files with 98 additions and 17 deletions

View File

@ -61,7 +61,7 @@ contract TestBn254 {
uint p = 21888242871839275222246405745257275088696311157297823662689037894645226208583;
Curve.G1Point[] memory g1points = new Curve.G1Point[](2);
Curve.G2Point[] memory g2points = new Curve.G2Point[](2);
// // check e(5 P1, P2)e(-P1, 5 P2) == 1
// check e(5 P1, P2)e(-P1, 5 P2) == 1
g1points[0] = Bn254.P1().g1mul(5);
g1points[1] = Bn254.P1();
g1points[1].Y = p - g1points[1].Y;
@ -78,7 +78,7 @@ contract TestBn254 {
return false;
return true;
}
function verifyingKey() internal pure returns (VerifyingKey memory vk) {
function _verifyingKey() internal pure returns (VerifyingKey memory vk) {
vk.A = Curve.G2Point([0x209dd15ebff5d46c4bd888e51a93cf99a7329636c63514396b4a452003a35bf7, 0x04bf11ca01483bfa8b34b43561848d28905960114c8ac04049af4b6315a41678], [0x2bb8324af6cfc93537a2ad1a445cfd0ca2a71acd7ac41fadbf933c2a51be344d, 0x120a2a4cf30c1bf9845f20c6fe39e07ea2cce61f0c9bb048165fe5e4de877550]);
vk.B = Curve.G1Point(0x2eca0c7238bf16e83e7a1e6c5d49540685ff51380f309842a98561558019fc02, 0x03d3260361bb8451de5ff5ecd17f010ff22f5c31cdf184e9020b06fa5997db84);
vk.C = Curve.G2Point([0x2e89718ad33c8bed92e210e81d1853435399a271913a6520736a4729cf0d51eb, 0x01a9e2ffa2e92599b68e44de5bcf354fa2642bd4f26b259daa6f7ce3ed57aeb3], [0x14a9a87b789a58af499b314e13c3d65bede56c07ea2d418d6874857b70763713, 0x178fb49a2d6cd347dc58973ff49613a20757d0fcc22079f9abd10c3baee24590]);
@ -98,8 +98,8 @@ contract TestBn254 {
vk.IC[8] = Curve.G1Point(0x0a6de0e2240aa253f46ce0da883b61976e3588146e01c9d8976548c145fe6e4a, 0x04fbaa3a4aed4bb77f30ebb07a3ec1c7d77a7f2edd75636babfeff97b1ea686e);
vk.IC[9] = Curve.G1Point(0x111e2e2a5f8828f80ddad08f9f74db56dac1cc16c1cb278036f79a84cf7a116f, 0x1d7d62e192b219b9808faa906c5ced871788f6339e8d91b83ac1343e20a16b30);
}
function verify(uint[] memory input, Proof memory proof) internal view returns (uint) {
VerifyingKey memory vk = verifyingKey();
function _verify(uint[] memory input, Proof memory proof) internal view returns (uint) {
VerifyingKey memory vk = _verifyingKey();
require(input.length + 1 == vk.IC.length);
// Compute the linear combination vk_x
Curve.G1Point memory vk_x = Curve.G1Point(0, 0);
@ -121,8 +121,8 @@ contract TestBn254 {
)) return 5;
return 0;
}
event Verified(string);
function verifyTx() internal returns (bool r) {
function verifyTx() public view returns (bool r) {
uint[] memory input = new uint[](9);
Proof memory proof;
proof.A = Curve.G1Point(12873740738727497448187997291915224677121726020054032516825496230827252793177, 21804419174137094775122804775419507726154084057848719988004616848382402162497);
@ -144,11 +144,6 @@ contract TestBn254 {
input[6] = 5613571677741714971687805233468747950848449704454346829971683826953541367271;
input[7] = 9643208548031422463313148630985736896287522941726746581856185889848792022807;
input[8] = 18066496933330839731877828156604;
if (verify(input, proof) == 0) {
emit Verified("Transaction successfully verified.");
return true;
} else {
return false;
}
return _verify(input, proof) == 0;
}
}

View File

@ -0,0 +1,35 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./ecc/verifiers/Bn254Verifier.sol";
import "./ecc/Verifier.sol";
// exposes internal functions of Proofs for testing
contract TestBn254Verifier {
using Bn254Verifier for Verifier.Proof;
function verifyProof(Verifier.Proof memory p) public view returns (bool) {
// Proof memory p;
// p.q = [
// Curve.QElement(i, v),
// Curve.QElement(i, v),
// Curve.QElement(i, v)
// ];
// p.mus = [];
// p.sigma = Curve.G1Point(x, y);
// p.u = [
// Curve.G1Point(x, y),
// Curve.G1Point(x, y),
// Curve.G1Point(x, y)
// ];
// p.publicKey = Curve.G2Point(
// [
// 11559732032986387107991004021392285783925812861821192530917403151452391805634,
// 10857046999023057135944570762232829481370756359578518086990519993285655852781
// ],
// [
// 4082367875863433681332203403145435568316851327593401208105741076214120093531,
// 8495653923123431417604973247489272438418190587263600148770280649306958101930
// ]
return p._verifyProof();
}
}

View File

@ -4,11 +4,8 @@ const {
snapshot,
revert,
ensureMinimumBlockHeight,
currentTime,
advanceTime,
advanceTimeTo,
} = require("./evm")
const { periodic } = require("./time")
describe("Bn254", function () {
let bn254
@ -32,7 +29,13 @@ describe("Bn254", function () {
expect(await bn254.g()).to.be.true
})
it("multiplication along BN254 emits expected values", async function () {
expect(await bn254.testMul()).to.be.true
it("points should be paired correctly", async function () {
expect(await bn254.pair()).to.be.true
})
it("can verify proof", async function () {
let result = await bn254.verifyTx()
console.log("verify result: " + JSON.stringify(result, null, 2))
expect(await bn254.verifyTx()).to.be.true
})
})

View File

@ -0,0 +1,48 @@
const { expect } = require("chai")
const { ethers } = require("hardhat")
const {
snapshot,
revert,
ensureMinimumBlockHeight,
advanceTime,
} = require("./evm")
describe("Bn254Verifier", function () {
let bn254
beforeEach(async function () {
await snapshot()
await ensureMinimumBlockHeight(256)
const Bn254Verifier = await ethers.getContractFactory("TestBn254Verifier")
verifier = await Bn254Verifier.deploy()
})
afterEach(async function () {
await revert()
})
it("fails when first point is not on Bn254 curve", async function () {
let proof = {
q: [
{ i: -1, v: 1 },
{ i: -2, v: 2 },
{ i: -3, v: 3 },
],
mus: [1, 2, 3, 4, 5, 6, 7, 8, 9, 0],
sigma: { X: 1, Y: 2 },
u: [
{ X: 1, Y: 2 },
{ X: 2, Y: 2 },
{ X: 3, Y: 3 },
],
name: ethers.utils.toUtf8Bytes("test"),
publicKey: {
X: [1, 2],
Y: [1, 2],
},
}
await expect(verifier.verifyProof(proof)).to.be.revertedWith(
"must be on Bn254 curve"
)
})
})