From 924189904406227ac88783269ee7177566bad2a3 Mon Sep 17 00:00:00 2001 From: Eric Mastro Date: Wed, 15 Jun 2022 17:29:47 +1000 Subject: [PATCH] WIP: rebase, add tests, update tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add correct proof in tests, but it’s not pairing correctly. Needs investigation. Add tests to test for input reverts for proof verification. Update verifyproof to test for equal array bounds in proof inputs. Fix _isOnCurve parameter order. --- contracts/Proofs.sol | 9 +++- contracts/ecc/Types.sol | 2 +- contracts/ecc/curves/Bn254.sol | 9 ++-- test/Bn254.test.js | 91 +++++++++++++++++++++++++++++++--- test/Proofs.test.js | 30 +++++++++-- 5 files changed, 125 insertions(+), 16 deletions(-) diff --git a/contracts/Proofs.sol b/contracts/Proofs.sol index 9d33063..0e6d521 100644 --- a/contracts/Proofs.sol +++ b/contracts/Proofs.sol @@ -134,6 +134,13 @@ contract Proofs { return _isProofRequired(id, currentPeriod()); } + function _willProofBeRequired(bytes32 id) internal view returns (bool) { + bool isRequired; + uint8 pointer; + (isRequired, pointer) = _getProofRequirement(id, currentPeriod()); + return isRequired && pointer < downtime; + } + function _submitProof(bytes32 id, Types.Proof calldata proof) internal { require(proof._verifyProof(), "Invalid proof"); require(!received[id][currentPeriod()], "Proof already submitted"); @@ -152,5 +159,5 @@ contract Proofs { missed[id] += 1; } - event ProofSubmitted(bytes32 id, bytes proof); + event ProofSubmitted(bytes32 id, Types.Proof proof); } diff --git a/contracts/ecc/Types.sol b/contracts/ecc/Types.sol index 32780fa..be2af32 100644 --- a/contracts/ecc/Types.sol +++ b/contracts/ecc/Types.sol @@ -28,7 +28,7 @@ library Types { struct Proof { // TODO: should `q` be bounded? QElement[] q; - uint256[10] mus; + uint256[] mus; // sigma is probably only the x coordinate // (https://github.com/supranational/blst#serialization-format) G1Point sigma; diff --git a/contracts/ecc/curves/Bn254.sol b/contracts/ecc/curves/Bn254.sol index 00def0b..e726852 100644 --- a/contracts/ecc/curves/Bn254.sol +++ b/contracts/ecc/curves/Bn254.sol @@ -76,7 +76,7 @@ library Bn254 { pure returns (bool) { - return BN256G2._isOnCurve(p1.x[0], p1.y[0], p1.x[1], p1.y[1]); + return BN256G2._isOnCurve(p1.x[0], p1.x[1], p1.y[0], p1.y[1]); } /// @dev Derives the y coordinate from a compressed-format point x [[SEC-1]](https://www.secg.org/SEC1-Ver-1.0.pdf). @@ -163,15 +163,18 @@ library Bn254 { s.x[0], // x real coordinate of point S s.x[1], // x imaginary coordinate of point S s.y[0], // y real coordinate of point S - s.y[1] // y imaginary coordinate of point S + s.y[1] // y imaginary coordinate of point S ] ); } function _verifyProof(Types.Proof memory proof) internal returns (bool) { require(_isOnCurve(proof.sigma), "proof generated incorrectly"); - require(_isOnCurve(proof.publicKey), "proof keys generated incorrectly"); + require(_isOnCurve(proof.publicKey), "public key not on Bn254 curve"); require(proof.name.length > 0, "proof name must be provided"); + require(proof.mus.length == proof.q.length && + proof.q.length == proof.u.length, + "setup, query, and proof length mismatch"); // var first: blst_p1 // for qelem in q : // var prod: blst_p1 diff --git a/test/Bn254.test.js b/test/Bn254.test.js index d47c0af..7765143 100644 --- a/test/Bn254.test.js +++ b/test/Bn254.test.js @@ -140,7 +140,7 @@ describe("Bn254", function () { { i: -2, v: 2 }, { i: -3, v: 3 }, ], - mus: [1, 2, 3, 4, 5, 6, 7, 8, 9, 0], + mus: [1, 2, 3], sigma: { x: 111, y: 222 }, // Wrong u: [ { x: 1, y: 2 }, @@ -165,7 +165,7 @@ describe("Bn254", function () { { i: -2, v: 2 }, { i: -3, v: 3 }, ], - mus: [1, 2, 3, 4, 5, 6, 7, 8, 9, 0], + mus: [1, 2, 3], sigma: { x: 1, y: 2 }, u: [ { x: 1, y: 2 }, @@ -174,12 +174,13 @@ describe("Bn254", function () { ], name: ethers.utils.toUtf8Bytes("test"), publicKey: { - x: [111, 222], // Wrong + // Wrong + x: [1, 2], y: [1, 2], }, } expect(bn254.callStatic.verifyProof(proof)).to.be.revertedWith( - "proof keys generated incorrectly" + "public key not on Bn254 curve" ) }) @@ -190,7 +191,7 @@ describe("Bn254", function () { { i: -2, v: 2 }, { i: -3, v: 3 }, ], - mus: [1, 2, 3, 4, 5, 6, 7, 8, 9, 0], + mus: [1, 2, 3], sigma: { x: 1, y: 2 }, u: [ { x: 1, y: 2 }, @@ -215,7 +216,7 @@ describe("Bn254", function () { { i: -2, v: 2 }, { i: -3, v: 3 }, ], - mus: [1, 2, 3, 4, 5, 6, 7, 8, 9, 0], + mus: [1, 2, 3], sigma: { x: 1, y: 2 }, u: [ { x: 111, y: 222 }, // Wrong @@ -232,4 +233,82 @@ describe("Bn254", function () { "incorrect proof setup" ) }) + + it("should fail proof verification with length mismatch", 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], // Wrong + sigma: { x: 1, y: 2 }, + u: [ + { x: 1, y: 2 }, + { x: 1, y: 2 }, + { x: 1, y: 2 }, + ], + name: ethers.utils.toUtf8Bytes("test"), + publicKey: { + x: [1, 2], + y: [1, 2], + }, + } + expect(bn254.callStatic.verifyProof(proof)).to.be.revertedWith( + "setup, query, and proof length mismatch" + ) + }) + + it("should fail to verify a proof with an incorrect public key", async function () { + let proof = { + q: [ + { + i: 0, + v: "0x0c31b73f16d1c31de28dd4651a9b5f62a9212938b4b041f3f4db25a65539ce9c", + }, + ], + mus: [ + "0x25920f9d4590bcb099933cae3afeda6ad9a0e4bb8602f167c31d1ab332f6718b", + ], + sigma: { + x: "0x24e9c16ab07296e7a16c06d91c10fd52eda14798ca5bf6a7e16a98d528bd199e", + y: "0x204ab8989fc6a373baa71bed526ed0f63705dd2617ae6b9f9df9e115f5e8fae4", + }, + u: [ + { + x: "0x102bd2e684495754b9ef8edd0aa70cf628fb8666c692a11ee89ad9fbfeb11a02", + y: "0x245369d1ea21fbaaea3264b9867ea74c121e72f66a94b3b785b9ce742be6c8f6", + }, + ], + name: ethers.utils.toUtf8Bytes( + "91de7326fea6823a95d65880e7d9c695de96d84e0c1292f1fe6beae6b33d26927699" + + "22796b3c2f213e2f667202babb53a97ff54443520998192b82da11a1de7c2e90875f" + + "84b4fed5f31622093fe57d89669f660e8fc731bf22293529a141ece41d4060e7a664" + + "5bd8fe0c1172ae377fdc5ae73889d34f81d2dbf105c3f756b4e0a253451a5a7a3cfb" + + "fb253b21c49c59701513b9ad9f8a9b192c3cc7232024254be4173785a7c08f32a60c" + + "3425d74c263584078604d2527ffdec60c15b050877eedd8c73700991f4efd04d7639" + + "14b73d8179e25aa6bd4ee6ae0fcd0b11f8c502baf828e0cbbd3a6dfd712894f10e8c" + + "96a90f454ef4b2a22ef19ea550555e324d69e977a9e5a8bd57b34563fb199530919a" + + "d80acd8d2f2c1eb4c9b48d2e57e6305131f1878b68c45d6b1fa35ab0e6bf44001f81" + + "1f613538f11f2efaba53e339d521074d8c14756c39c9b0b5cc68b14779cb223cd2e1" + + "c08bacc55f6499b72ea5ceca033efb6826c699d225ed772428a2153da091f6f6536c" + + "8df25e51e861526e2f9bb130f33c6d03c94f65bd3a3f4a6f0e7ab80ee5303b275667" + + "a922ae87102e6862a80fa8840ef291ec6a66a1ee94818e6b715fba1546a2aeffae38" + + "078986ecdc6df4305836e17dd4633b3b9bbd0f22d8e1a0292f4940509d98fa7ee0d5" + + "2078c85080458fdab6b4bf9a42400248e8b4e9530fa9f1cd421e98f40ee8585434e4" + + "98d2" + ), + publicKey: { + x: [ + "0x07d42b42c4eddef5a05309382acd6facd59cee75d1d811cbbcd52b1b55b8e31b", + "0x21e4617026fdf43d59893c2ad8fb00acb4167ae895e80c58a5d013928a601184", + ], + y: [ + "0x0e86e2f05fb3e72609b0cfea77633eca05f4bf34851874d84e5a2c2f2985fa7d", + "0x1d20bf4bc725cc14d0d0a8bc98b3391582c48ad99a41669a5349a5cab5864e10", + ], + }, + } + expect(await bn254.callStatic.verifyProof(proof)).to.be.equal(false) + }) }) diff --git a/test/Proofs.test.js b/test/Proofs.test.js index 1786825..47f4688 100644 --- a/test/Proofs.test.js +++ b/test/Proofs.test.js @@ -141,7 +141,25 @@ describe("Proofs", function () { }) describe("when proofs are required", function () { - const proof = hexlify(randomBytes(42)) + 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: 1, y: 2 }, + { x: 1, y: 2 }, + ], + name: ethers.utils.toUtf8Bytes("test"), + publicKey: { + x: [1, 2], + y: [1, 2], + }, + } beforeEach(async function () { await proofs.expectProofs(id, probability, duration) @@ -177,7 +195,9 @@ describe("Proofs", function () { }) it("submits a correct proof", async function () { - let proof = { + // TODO: update to a correct proof. Waiting on valid proof inputs from + // https://github.com/status-im/nim-codex/pulls/101. + proof = { q: [ { i: -1, v: 1 }, { i: -2, v: 2 }, @@ -200,7 +220,7 @@ describe("Proofs", function () { }) it("fails proof submission when proof is incorrect", async function () { - let proof = { + proof = { q: [ { i: -1, v: 1 }, { i: -2, v: 2 }, @@ -232,7 +252,7 @@ describe("Proofs", function () { it("fails proof submission when already submitted", async function () { await advanceTimeTo(periodEnd(periodOf(await currentTime()))) - let proof = { + proof = { q: [ { i: -1, v: 1 }, { i: -2, v: 2 }, @@ -286,7 +306,7 @@ describe("Proofs", function () { it("does not mark a submitted proof as missing", async function () { await waitUntilProofIsRequired(id) let submittedPeriod = periodOf(await currentTime()) - let proof = { + proof = { q: [ { i: -1, v: 1 }, { i: -2, v: 2 },