Submit proof as Groth16Proof struct

This commit is contained in:
Mark Spanbroek 2024-01-18 13:50:54 +01:00 committed by markspanbroek
parent ae03690d51
commit e6a918fed9
6 changed files with 53 additions and 33 deletions

18
contracts/Groth16.sol Normal file
View File

@ -0,0 +1,18 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
struct G1Point {
uint x;
uint y;
}
struct G2Point {
uint[2] x;
uint[2] y;
}
struct Groth16Proof {
G1Point a;
G2Point b;
G1Point c;
}

View File

@ -9,6 +9,7 @@ import "./Requests.sol";
import "./Proofs.sol";
import "./StateRetrieval.sol";
import "./Verifier.sol";
import "./Groth16.sol";
contract Marketplace is Proofs, StateRetrieval {
using EnumerableSet for EnumerableSet.Bytes32Set;
@ -100,7 +101,7 @@ contract Marketplace is Proofs, StateRetrieval {
function fillSlot(
RequestId requestId,
uint256 slotIndex,
uint256[8] calldata proof
Groth16Proof calldata proof
) public requestIsKnown(requestId) {
Request storage request = _requests[requestId];
require(slotIndex < request.ask.slots, "Invalid slot");

View File

@ -5,6 +5,7 @@ import "./Configuration.sol";
import "./Requests.sol";
import "./Periods.sol";
import "./Verifier.sol";
import "./Groth16.sol";
abstract contract Proofs is Periods {
ProofConfig private _config;
@ -108,19 +109,8 @@ abstract contract Proofs is Periods {
return isRequired && pointer < _config.downtime;
}
function submitProof(SlotId id, uint256[8] calldata proof) public {
function submitProof(SlotId id, Groth16Proof calldata proof) public {
require(!_received[id][_blockPeriod()], "Proof already submitted");
uint256[2] memory a;
uint256[2][2] memory b;
uint256[2] memory c;
a[0] = proof[0];
a[1] = proof[1];
b[0][0] = proof[2];
b[0][1] = proof[3];
b[1][0] = proof[4];
b[1][1] = proof[5];
c[0] = proof[6];
c[1] = proof[7];
// TODO: The `pubSignals` should be constructed from information that we already know:
// - external entropy (for example some fresh ethereum block header) - this gives us the unbiased randomness we use to sample which cells to prove
@ -133,7 +123,15 @@ abstract contract Proofs is Periods {
] = 16074246370508166450132968585287196391860062495017081813239200574579640171677;
pubSignals[2] = 3;
require(_verifier.verifyProof(a, b, c, pubSignals), "Invalid proof");
require(
_verifier.verifyProof(
[proof.a.x, proof.a.y],
[proof.b.x, proof.b.y],
[proof.c.x, proof.c.y],
pubSignals
),
"Invalid proof"
);
_received[id][_blockPeriod()] = true;
emit ProofSubmitted(id);
}

View File

@ -14,6 +14,7 @@ const { periodic } = require("./time")
const { loadProof } = require("./proof")
const { SlotState } = require("./requests")
const binomialTest = require("@stdlib/stats-binomial-test")
const { exampleProof } = require("./examples")
describe("Proofs", function () {
const slotId = hexlify(randomBytes(32))
@ -204,8 +205,7 @@ describe("Proofs", function () {
})
it("fails proof submission when proof is incorrect", async function () {
let invalid = new Uint8Array(proof)
invalid[42] = 42
let invalid = exampleProof()
await expect(proofs.submitProof(slotId, invalid)).to.be.reverted
})

View File

@ -39,6 +39,10 @@ const exampleRequest = async () => {
}
}
const exampleProof = () => ([1, 2, 3, 4, 5, 6, 7, 8])
const exampleProof = () => ({
a: { x: 1, y: 2 },
b: { x: [3, 4], y: [5, 6]},
c: { x: 7, y: 8 }
})
module.exports = { exampleConfiguration, exampleRequest, exampleProof }

View File

@ -5,30 +5,29 @@ const { BigNumber } = ethers
const BASE_PATH = __dirname + "/../verifier/networks"
const PROOF_FILE_NAME = "example-proof/proof.json"
function G1ToUInts(point) {
return [
point[0],
point[1]
]
function G1ToStruct(point) {
return {
x: point[0],
y: point[1]
}
}
function G2ToUInts(point) {
return [
point[0][1],
point[0][0],
point[1][1],
point[1][0]
]
function G2ToStruct(point) {
return {
x: [ point[0][1], point[0][0] ],
y: [ point[1][1], point[1][0] ]
}
}
function loadProof(name) {
const proof = JSON.parse(
fs.readFileSync(`${BASE_PATH}/${name}/${PROOF_FILE_NAME}`)
)
return []
.concat(G1ToUInts(proof['pi_a']))
.concat(G2ToUInts(proof['pi_b']))
.concat(G1ToUInts(proof['pi_c']))
return {
a: G1ToStruct(proof['pi_a']),
b: G2ToStruct(proof['pi_b']),
c: G1ToStruct(proof['pi_c'])
}
}
module.exports = { loadProof }