feat(zk-protocol): structure the public signals array obtained while generating a proof from snarkjs

The generated proof using snarkjs will return an object of type PublicSignals for the public signals


Former-commit-id: deadf7159137f98343e42dbb2cfef813a3adffc3 [formerly 1f7dd580bbd27f39e0975b8bc2967dca191f2e75] [formerly d0641f8a46fd888b44d45020d8393871672759f8 [formerly 422bcbb07e3675b3c124313ce265dd661856075c]] [formerly c93bbaee62c8969bb91c9b75efe642781d740b49 [formerly d5a4c2359230f114287796b6ad502d881ec554c4] [formerly 5f155f5f9927762e8418d9930dda1d0af414af57 [formerly 462a4bb745]]]
Former-commit-id: 1f3f2470e637188e7ef3311a15c40d6f9368b1ee [formerly 884540bf7bd1e87311c7e72557e983c6bc769ee5] [formerly d060f4aacfe7f2c5bec5da817b4e785ced9de9d8 [formerly 471a8074b86fb074707ab4981f2831bcf7242a57]]
Former-commit-id: 9d93b210d84bf65134e25a970ec42af8afb50253 [formerly c1c1a33c3edd09bf908482185f3ec11914c52131]
Former-commit-id: fed1b20295686aef5fdf5597f9bcece2933d984d
This commit is contained in:
Nasi Jofce
2022-02-18 20:29:26 +01:00
parent 9d4e1824e9
commit d32bbbd7a6
6 changed files with 81 additions and 37 deletions

View File

@@ -1,10 +1,40 @@
import { MerkleProof } from "@zk-kit/incremental-merkle-tree"
import { poseidon } from "circomlibjs"
import { StrBigInt } from "./types"
import { groth16 } from "snarkjs"
import { FullProof, RLNPublicSignals, StrBigInt } from "./types"
import { Fq, genSignalHash } from "./utils"
import ZkProtocol from "./zk-protocol"
export default class RLN extends ZkProtocol {
/**
* The number of public signals that should be returned by snarkjs when generating a proof.
*/
private static PUBLIC_SIGNALS_COUNT: number = 6
/**
* Generates a SnarkJS full proof with Groth16.
* @param witness The parameters for creating the proof.
* @param wasmFilePath The WASM file path.
* @param finalZkeyPath The ZKey file path.
* @returns The full SnarkJS proof.
*/
public static async genProof(witness: any, wasmFilePath: string, finalZkeyPath: string): Promise<FullProof> {
const { proof, publicSignalsArray } = await groth16.fullProve(witness, wasmFilePath, finalZkeyPath, null)
if (publicSignalsArray.length !== RLN.PUBLIC_SIGNALS_COUNT) throw new Error("Error while generating proof")
const publicSignals: RLNPublicSignals = {
yShare: publicSignalsArray[0],
merkleRoot: publicSignalsArray[1],
internalNullifier: publicSignalsArray[2],
signalHash: publicSignalsArray[3],
epoch: publicSignalsArray[4],
rlnIdentifier: publicSignalsArray[5]
}
return { proof, publicSignals }
}
/**
* Creates witness for rln proof
* @param identitySecret identity secret

View File

@@ -1,10 +1,38 @@
import { MerkleProof } from "@zk-kit/incremental-merkle-tree"
import { poseidon } from "circomlibjs"
import { SemaphoreWitness, StrBigInt } from "./types"
import { groth16 } from "snarkjs"
import { FullProof, StrBigInt, SemaphoreWitness, SemaphorePublicSignals } from "./types"
import { genSignalHash } from "./utils"
import ZkProtocol from "./zk-protocol"
export default class Semaphore extends ZkProtocol {
/**
* The number of public signals that should be returned by snarkjs when generating a proof.
*/
private static PUBLIC_SIGNALS_COUNT: number = 6
/**
* Generates a SnarkJS full proof with Groth16.
* @param witness The parameters for creating the proof.
* @param wasmFilePath The WASM file path.
* @param finalZkeyPath The ZKey file path.
* @returns The full SnarkJS proof.
*/
public static async genProof(witness: any, wasmFilePath: string, finalZkeyPath: string): Promise<FullProof> {
const { proof, publicSignalsArray } = await groth16.fullProve(witness, wasmFilePath, finalZkeyPath, null)
if (publicSignalsArray.length !== Semaphore.PUBLIC_SIGNALS_COUNT) throw new Error("Error while generating proof")
const publicSignals: SemaphorePublicSignals = {
merkleRoot: publicSignalsArray[0],
nullifierHash: publicSignalsArray[1],
signalHash: publicSignalsArray[2],
externalNullifier: publicSignalsArray[3]
}
return { proof, publicSignals }
}
/**
* Creates a Semaphore witness for the Semaphore ZK proof.
* @param identityTrapdoor The identity trapdoor.

View File

@@ -10,10 +10,10 @@ export type Proof = {
export type FullProof = {
proof: Proof
publicSignals: PublicSignals
publicSignals: RLNPublicSignals | SemaphorePublicSignals
}
export type PublicSignals = {
export type RLNPublicSignals = {
yShare: StrBigInt
merkleRoot: StrBigInt
internalNullifier: StrBigInt
@@ -22,6 +22,13 @@ export type PublicSignals = {
rlnIdentifier: StrBigInt
}
export type SemaphorePublicSignals = {
merkleRoot: StrBigInt
nullifierHash: StrBigInt
signalHash: StrBigInt
externalNullifier: StrBigInt
}
export type SolidityProof = StrBigInt[]
export type SemaphoreWitness = {

View File

@@ -1,37 +1,8 @@
/* istanbul ignore file */
import { groth16 } from "snarkjs"
import { FullProof, PublicSignals, SolidityProof, StrBigInt } from "./types"
import { FullProof, SolidityProof, StrBigInt } from "./types"
export default class ZkProtocol {
/**
* The number of public signals that should be returned by snarkjs when generating a proof.
*/
private static PUBLIC_SIGNALS_COUNT: number = 6
/**
* Generates a SnarkJS full proof with Groth16.
* @param witness The parameters for creating the proof.
* @param wasmFilePath The WASM file path.
* @param finalZkeyPath The ZKey file path.
* @returns The full SnarkJS proof.
*/
public static async genProof(witness: any, wasmFilePath: string, finalZkeyPath: string): Promise<FullProof> {
const { proof, publicSignalsArray } = await groth16.fullProve(witness, wasmFilePath, finalZkeyPath, null)
if (publicSignalsArray.length !== ZkProtocol.PUBLIC_SIGNALS_COUNT) throw new Error("Error while generating proof")
const publicSignals: PublicSignals = {
yShare: publicSignalsArray[0],
merkleRoot: publicSignalsArray[1],
internalNullifier: publicSignalsArray[2],
signalHash: publicSignalsArray[3],
epoch: publicSignalsArray[4],
rlnIdentifier: publicSignalsArray[5]
}
return { proof, publicSignals }
}
/**
* Verifies a zero-knowledge SnarkJS proof.
* @param verificationKey The zero-knowledge verification key.

View File

@@ -4,7 +4,7 @@ import * as fs from "fs"
import * as path from "path"
import { RLN } from "../src"
import { generateMerkleProof, genExternalNullifier, genSignalHash } from "../src/utils"
import { PublicSignals } from "../src/types"
import { RLNPublicSignals } from "../src/types"
describe("RLN", () => {
const zkeyFiles = "./packages/protocols/zkeyFiles"
@@ -67,7 +67,7 @@ describe("RLN", () => {
const [y, nullifier] = RLN.calculateOutput(secretHash, BigInt(epoch), rlnIdentifier, signalHash)
const publicSignals: PublicSignals = {
const publicSignals: RLNPublicSignals = {
yShare: y,
merkleRoot: merkleProof.root,
internalNullifier: nullifier,

View File

@@ -3,6 +3,7 @@ import { getCurveFromName } from "ffjavascript"
import fs from "fs"
import path from "path"
import { Semaphore } from "../src"
import { SemaphorePublicSignals } from "../src/types"
import { generateMerkleProof, genExternalNullifier, genSignalHash } from "../src/utils"
describe("Semaphore", () => {
@@ -64,11 +65,18 @@ describe("Semaphore", () => {
const vkeyPath = path.join("./packages/protocols/zkeyFiles", "semaphore", "verification_key.json")
const vKey = JSON.parse(fs.readFileSync(vkeyPath, "utf-8"))
const nullifierHash = Semaphore.genNullifierHash(externalNullifier, identity.getNullifier())
const publicSignals = [merkleProof.root.toString(), nullifierHash, genSignalHash(signal), externalNullifier]
const publicSignals: SemaphorePublicSignals = {
merkleRoot: merkleProof.root.toString(),
nullifierHash,
signalHash: genSignalHash(signal),
externalNullifier
}
const response = await Semaphore.verifyProof(vKey, { proof: fullProof.proof, publicSignals })
expect(response).toBe(true)
expect(fullProof.publicSignals).toEqual(publicSignals)
}, 30000)
})
})