Skip to content

Commit

Permalink
Merge pull request #481 from iden3/pi_check
Browse files Browse the repository at this point in the history
PI check and additional tests
  • Loading branch information
OBrezhniev authored Apr 8, 2024
2 parents fcfa802 + a9f2243 commit a29acef
Show file tree
Hide file tree
Showing 10 changed files with 1,068 additions and 9 deletions.
38 changes: 38 additions & 0 deletions smart_contract_tests/test/smart_contracts.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@ describe("Smart contracts test suite", function () {
)).to.be.equal(true);
});

it("Groth16 smart contract 1 aliased input", async () => {
expect(
await groth16VerifyAliased(
path.join("../test", "groth16", "circuit.r1cs"),
path.join("../test", "groth16", "witness.wtns")
)
).to.be.equal(false);
});

it("Groth16 smart contract 3 inputs", async () => {
expect(await groth16Verify(
path.join("../test", "circuit2", "circuit.r1cs"),
Expand Down Expand Up @@ -100,6 +109,35 @@ describe("Smart contracts test suite", function () {
return await verifierContract.verifyProof(proofA, proofB, proofC, publicInputs);
}

async function groth16VerifyAliased(r1csFilename, wtnsFilename) {
const solidityVerifierFilename = path.join("contracts", "groth16.sol");

const zkeyFilename = { type: "mem" };

await snarkjs.zKey.newZKey(r1csFilename, ptauFilename, zkeyFilename);
const { proof: proof, publicSignals: publicInputs } = await snarkjs.groth16.prove(zkeyFilename, wtnsFilename);

const proofA = [proof.pi_a[0], proof.pi_a[1]];
const proofB = [[proof.pi_b[0][1], proof.pi_b[0][0]], [proof.pi_b[1][1], proof.pi_b[1][0]],];
const proofC = [proof.pi_c[0], proof.pi_c[1]];

// Generate groth16 verifier solidity file from groth16 template + zkey
const verifierCode = await snarkjs.zKey.exportSolidityVerifier(zkeyFilename, templates);
fs.writeFileSync(solidityVerifierFilename, verifierCode, "utf-8");

// Compile the groth16 verifier smart contract
await run("compile");

let pi_with_alias = [...publicInputs];
pi_with_alias[1] = BigInt(publicInputs[1]) + 21888242871839275222246405745257275088548364400416034343698204186575808495617n;

// Deploy mock groth16 verifier
const VerifierFactory = await ethers.getContractFactory("Groth16Verifier");
verifierContract = await VerifierFactory.deploy();

return await verifierContract.verifyProof(proofA, proofB, proofC, pi_with_alias);
}

async function plonkVerify(r1csFilename, wtnsFilename) {
const solidityVerifierFilename = path.join("contracts", "plonk.sol");

Expand Down
15 changes: 10 additions & 5 deletions test/fullprocess.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ describe("Full process", function () {
const wtns = {type: "mem"};
let proof;
let publicSignals;
let publicSignalsWithAlias;

before( async () => {
curve = await getCurveFromName("bn128");
Expand Down Expand Up @@ -70,7 +71,7 @@ describe("Full process", function () {
});

it ("groth16 setup", async () => {
await snarkjs.zKey.newZKey(path.join("test", "circuit", "circuit.r1cs"), ptau_final, zkey_0);
await snarkjs.zKey.newZKey(path.join("test", "groth16", "circuit.r1cs"), ptau_final, zkey_0);
});

it ("zkey contribute ", async () => {
Expand All @@ -94,7 +95,7 @@ describe("Full process", function () {
});

it ("zkey verify r1cs", async () => {
const res = await snarkjs.zKey.verifyFromR1cs(path.join("test", "circuit", "circuit.r1cs"), ptau_final, zkey_final);
const res = await snarkjs.zKey.verifyFromR1cs(path.join("test", "groth16", "circuit.r1cs"), ptau_final, zkey_final);
assert(res);
});

Expand All @@ -108,23 +109,27 @@ describe("Full process", function () {
});

it ("witness calculate", async () => {
await snarkjs.wtns.calculate({a: 11, b:2}, path.join("test", "circuit", "circuit.wasm"), wtns);
await snarkjs.wtns.calculate({a: 11, b:2}, path.join("test", "groth16", "circuit.wasm"), wtns);
});

it ("checks witness complies with r1cs", async () => {
await snarkjs.wtns.check(path.join("test", "circuit", "circuit.r1cs"), wtns);
await snarkjs.wtns.check(path.join("test", "groth16", "circuit.r1cs"), wtns);
});

it ("groth16 proof", async () => {
const res = await snarkjs.groth16.prove(zkey_final, wtns);
proof = res.proof;
publicSignals = res.publicSignals;
publicSignalsWithAlias = [...res.publicSignals];
publicSignalsWithAlias[1] = BigInt(res.publicSignals[1]) + 21888242871839275222246405745257275088548364400416034343698204186575808495617n;
});


it ("groth16 verify", async () => {
const res = await snarkjs.groth16.verify(vKey, publicSignals, proof);
assert(res == true);

const res2 = await snarkjs.groth16.verify(vKey, publicSignalsWithAlias, proof);
assert(res2 == false);
});

it ("plonk setup", async () => {
Expand Down
16 changes: 16 additions & 0 deletions test/groth16/circuit.circom
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
template Multiplier(n) {
signal input a;
signal input b;
signal output c;

signal int[n];

int[0] <== a*a + b;
for (var i=1; i<n; i++) {
int[i] <== int[i-1]*int[i-1] + b;
}

c <== int[n-1];
}

component main {public [a]} = Multiplier(1000);
Binary file modified test/groth16/circuit.r1cs
Binary file not shown.
Loading

0 comments on commit a29acef

Please sign in to comment.