feat: create semaphore proofs, test

This commit is contained in:
rymnc 2022-11-28 18:23:59 +05:30
parent 9ec26069f0
commit 1224edffb9
No known key found for this signature in database
GPG Key ID: C740033EE3F41EBD
6 changed files with 727 additions and 19 deletions

View File

@ -1,11 +1,17 @@
import { utils } from "ethers";
import { Signer, utils } from "ethers";
import createIdentity from "@interep/identity";
import { Group, Member } from "@semaphore-protocol/group";
import { generateProof, packToSolidityProof } from "@semaphore-protocol/proof";
import type { Identity } from "@semaphore-protocol/identity";
// import createProof from '@interep/proof'
import type { SnarkArtifacts } from "@interep/proof/dist/types/types";
export const sToBytes32 = (str: string): string => {
return utils.formatBytes32String(str);
};
// zerokit can only use 15, 19, and 20 depth
export const merkleTreeDepth = 15;
export const merkleTreeDepth = 20;
export const SNARK_SCALAR_FIELD = BigInt(
"21888242871839275222246405745257275088548364400416034343698204186575808495617"
@ -43,3 +49,59 @@ export const getGroups = () => {
export const getValidGroups = () => {
return getGroups().filter((group) => group.name !== sToBytes32("bronze"));
};
export const createInterepIdentity = (signer: Signer, provider: string) => {
if (!providers.includes(provider))
throw new Error(`Invalid provider: ${provider}`);
const sign = (message: string) => signer.signMessage(message);
return createIdentity(sign, provider);
};
interface ProofCreationArgs {
identity: Identity;
members: Member[];
groupProvider: typeof providers[0];
groupTier: typeof tiers[0];
externalNullifier: number;
signal: string;
snarkArtifacts: SnarkArtifacts;
}
// Similar to https://github.com/interep-project/interep.js/blob/ae7d19f560a63fef08b71ecba7a926729538011c/packages/proof/src/createProof.ts#L21,
// but without the api interactions
// Note: An aribitrary set of members is passed in, without validation
// when this function is called, ensure that the membership set passed in is a valid representation of onchain membership
export const createInterepProof = async (args: ProofCreationArgs) => {
const group = new Group(merkleTreeDepth);
const idCommitment = args.identity.getCommitment();
group.addMembers(args.members);
const memberIndex = group.indexOf(idCommitment);
if (memberIndex === -1) {
throw new Error("The semaphore identity is not yet verifiable onchain");
}
const merkleProof = group.generateProofOfMembership(memberIndex);
const { publicSignals, proof } = await generateProof(
args.identity,
merkleProof,
BigInt(args.externalNullifier),
args.signal,
args.snarkArtifacts
);
const solidityProof = packToSolidityProof(proof);
const groupId = createGroupId(args.groupProvider, args.groupTier).toString();
return {
groupId,
signal: args.signal,
publicSignals,
proof,
solidityProof,
};
};

View File

@ -20,6 +20,8 @@
"@nomiclabs/hardhat-etherscan": "^3.1.0",
"@nomiclabs/hardhat-waffle": "^2.0.3",
"@semaphore-protocol/contracts": "2.0.0",
"@interep/identity": "0.3.0",
"@interep/proof": "0.7.0",
"@types/mocha": "^9.1.1",
"chai": "^4.3.6",
"ethereum-waffle": "^3.4.4",

View File

@ -1,7 +1,12 @@
import { expect, assert } from "chai";
import { BigNumber } from "ethers";
import { ethers, deployments } from "hardhat";
import { createGroupId, sToBytes32 } from "../common";
import {
createGroupId,
createInterepIdentity,
createInterepProof,
sToBytes32,
} from "../common";
describe("RLN", () => {
beforeEach(async () => {
@ -134,6 +139,32 @@ describe("RLN", () => {
expect(pubkey.toHexString() === dummyPubkey.toHexString());
});
it.only("[interep] should generate proof for registration", async () => {
const signer = ethers.provider.getSigner(0);
const identity = await createInterepIdentity(signer, "github");
// create a proof to test
const proof = await createInterepProof({
identity,
members: [identity.getCommitment()],
groupProvider: "github",
groupTier: "silver",
signal: "foo",
externalNullifier: 1,
snarkArtifacts: {
wasmFilePath: "./test/snarkArtifacts/semaphore.wasm",
zkeyFilePath: "./test/snarkArtifacts/semaphore.zkey",
},
});
expect(proof.groupId).to.eql(
"19580063316323634959827976785370507245708993886389832860880129572471638471998"
);
expect(proof.publicSignals.merkleRoot).to.eql(
"10738127364751233254031334835017982823925916365031589705155005906674724477907"
);
});
it("[interep] should withdraw membership", () => {
// TODO
});

Binary file not shown.

Binary file not shown.

645
yarn.lock

File diff suppressed because it is too large Load Diff