mirror of
https://github.com/privacy-scaling-explorations/zk-kit.git
synced 2026-04-22 03:00:15 -04:00
Merge pull request #16 from appliedzkp/feat/structured_public_signals
feat(zk-protocol): structure the public signals array obtained while generating a proof from snarkjs
Former-commit-id: ef1e31e83f0fc7093ff967cddb4c104156bf4f46 [formerly 257d03e01d2395aa1bebcc83f35ff19c784ed942] [formerly 0a14f53831ac1f633564c121de2cd52a80249ef2 [formerly 56204bf4695cee1c51aa9a6661be8dc281da0771]] [formerly f0cc2c9b7b319e58b4b97da17115b45fadea9014 [formerly c41a83c20d080db3d3a6372380bc2ecbf450b2f4] [formerly 43b4f30154f215514969af37bd08d1624a377206 [formerly 89d6d730e3]]]
Former-commit-id: 184e42d23dc71e66f0961805929766bb88fa657b [formerly 35a3b1646ade9f78d68c38e6c166bd394fd30002] [formerly cedc0eb9d78e56ceb14b66a71910bd3c50fd2317 [formerly b42e068fd090e4925d374b0411f28a8bcf0647fa]]
Former-commit-id: 001d9ec2da39fc13970db3c4cdf3b1526a29275a [formerly 32eb83c3ec842164d2797665076f8ad8d98a03de]
Former-commit-id: 06bb43dd5f3fa2320fc085487eccb3114e7f182d
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -10,7 +10,23 @@ export type Proof = {
|
||||
|
||||
export type FullProof = {
|
||||
proof: Proof
|
||||
publicSignals: StrBigInt[]
|
||||
publicSignals: RLNPublicSignals | SemaphorePublicSignals
|
||||
}
|
||||
|
||||
export type RLNPublicSignals = {
|
||||
yShare: StrBigInt
|
||||
merkleRoot: StrBigInt
|
||||
internalNullifier: StrBigInt
|
||||
signalHash: StrBigInt
|
||||
epoch: StrBigInt
|
||||
rlnIdentifier: StrBigInt
|
||||
}
|
||||
|
||||
export type SemaphorePublicSignals = {
|
||||
merkleRoot: StrBigInt
|
||||
nullifierHash: StrBigInt
|
||||
signalHash: StrBigInt
|
||||
externalNullifier: StrBigInt
|
||||
}
|
||||
|
||||
export type SolidityProof = StrBigInt[]
|
||||
|
||||
@@ -1,20 +1,8 @@
|
||||
/* istanbul ignore file */
|
||||
import { groth16 } from "snarkjs"
|
||||
import { FullProof, SolidityProof } from "./types"
|
||||
import { FullProof, SolidityProof, StrBigInt } from "./types"
|
||||
|
||||
export default class ZkProtocol {
|
||||
/**
|
||||
* 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, publicSignals } = await groth16.fullProve(witness, wasmFilePath, finalZkeyPath, null)
|
||||
return { proof, publicSignals }
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies a zero-knowledge SnarkJS proof.
|
||||
* @param verificationKey The zero-knowledge verification key.
|
||||
@@ -24,7 +12,9 @@ export default class ZkProtocol {
|
||||
public static verifyProof(verificationKey: string, fullProof: FullProof): Promise<boolean> {
|
||||
const { proof, publicSignals } = fullProof
|
||||
|
||||
return groth16.verify(verificationKey, publicSignals, proof)
|
||||
const publicSignalsArray: StrBigInt[] = Object.values(publicSignals)
|
||||
|
||||
return groth16.verify(verificationKey, publicSignalsArray, proof)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,6 +4,7 @@ import * as fs from "fs"
|
||||
import * as path from "path"
|
||||
import { RLN } from "../src"
|
||||
import { generateMerkleProof, genExternalNullifier, genSignalHash } from "../src/utils"
|
||||
import { RLNPublicSignals } from "../src/types"
|
||||
|
||||
describe("RLN", () => {
|
||||
const zkeyFiles = "./packages/protocols/zkeyFiles"
|
||||
@@ -65,7 +66,15 @@ describe("RLN", () => {
|
||||
const witness = RLN.genWitness(secretHash, merkleProof, epoch, signal, rlnIdentifier)
|
||||
|
||||
const [y, nullifier] = RLN.calculateOutput(secretHash, BigInt(epoch), rlnIdentifier, signalHash)
|
||||
const publicSignals = [y, merkleProof.root, nullifier, signalHash, epoch, rlnIdentifier]
|
||||
|
||||
const publicSignals: RLNPublicSignals = {
|
||||
yShare: y,
|
||||
merkleRoot: merkleProof.root,
|
||||
internalNullifier: nullifier,
|
||||
signalHash,
|
||||
epoch,
|
||||
rlnIdentifier
|
||||
}
|
||||
|
||||
const vkeyPath = path.join(zkeyFiles, "rln", "verification_key.json")
|
||||
const vKey = JSON.parse(fs.readFileSync(vkeyPath, "utf-8"))
|
||||
@@ -77,6 +86,7 @@ describe("RLN", () => {
|
||||
const response = await RLN.verifyProof(vKey, { proof: fullProof.proof, publicSignals })
|
||||
|
||||
expect(response).toBe(true)
|
||||
expect(fullProof.publicSignals).toEqual(publicSignals)
|
||||
}, 30000)
|
||||
|
||||
it("Should retrieve user secret after spaming", () => {
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user