Skip to content

Commit

Permalink
feat(verification): added actions helper to extract artifacts from a …
Browse files Browse the repository at this point in the history
…zKey

Added helper functions to extract the solidity verifier and the verification key from a zkey
  • Loading branch information
ctrlc03 committed Feb 28, 2023
1 parent 89adcc0 commit 1aed70e
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 2 deletions.
67 changes: 66 additions & 1 deletion packages/actions/src/helpers/verification.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { DocumentData, Firestore } from "firebase/firestore"
import { FirebaseDocumentInfo } from "../types"
import { zKey } from "snarkjs"
import fs from "fs"
import path from "path"
import { cwd } from "process"
import { getCurrentContributorContribution } from "./database"
import { FirebaseDocumentInfo } from "../types"

/**
* Return an array of true of false based on contribution verification result per each circuit.
Expand Down Expand Up @@ -121,3 +125,64 @@ export const getValidContributionAttestation = async (

return attestation
}

/**
* Helper method to extract the Solidity verifier
* from a final zKey file and save it to a local file.
* @param solidityVersion <string> The solidity version to include in the verifier pragma definition.
* @param finalZkeyPath <string> The path to the zKey file.
* @param verifierLocalPath <string> The path to the local file where the verifier will be saved.
*/
export const exportVerifierContract = async (
solidityVersion: string,
finalZkeyPath: string,
verifierLocalPath: string
) => {
// Extract verifier.

let verifierCode = await zKey.exportSolidityVerifier(
finalZkeyPath,
{
groth16: fs
.readFileSync(path.join(cwd(), "node_modules/snarkjs/templates/verifier_groth16.sol.ejs"))
.toString()
},
console
)

// Update solidity version.
verifierCode = verifierCode.replace(
/pragma solidity \^\d+\.\d+\.\d+/,
`pragma solidity ^${solidityVersion || "0.8.0"}`
)

fs.writeFileSync(verifierLocalPath, verifierCode)
}

/**
* Helpers method to extract the vKey from a final zKey file
* @param finalZkeyPath <string> The path to the zKey file.
* @param vKeyLocalPath <string> The path to the local file where the vKey will be saved.
*/
export const exportVkey = async (finalZkeyPath: string, vKeyLocalPath: string) => {
const verificationKeyJSONData = await zKey.exportVerificationKey(finalZkeyPath)
fs.writeFileSync(vKeyLocalPath, JSON.stringify(verificationKeyJSONData))
}

/**
* Helper method to extract the Solidity verifier and the Verification key
* from a final zKey file and save them to local files.
* @param solidityVersion <string> The solidity version to include in the verifier pragma definition.
* @param finalZkeyPath <string> The path to the zKey file.
* @param verifierLocalPath <string> The path to the local file where the verifier will be saved.
* @param vKeyLocalPath <string> The path to the local file where the vKey will be saved.
*/
export const exportVerifierAndVKey = async (
solidityVersion: string,
finalZkeyPath: string,
verifierLocalPath: string,
vKeyLocalPath: string
) => {
await exportVerifierContract(solidityVersion, finalZkeyPath, verifierLocalPath)
await exportVkey(finalZkeyPath, vKeyLocalPath)
}
8 changes: 7 additions & 1 deletion packages/actions/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,13 @@ export {
getContributionsCollectionPath,
getTimeoutsCollectionPath
} from "./helpers/database"
export { getContributorContributionsVerificationResults, getValidContributionAttestation } from "./helpers/verification"
export {
getContributorContributionsVerificationResults,
getValidContributionAttestation,
exportVerifierAndVKey,
exportVerifierContract,
exportVkey
} from "./helpers/verification"
export { initializeFirebaseCoreServices } from "./helpers/services"
export { signInToFirebaseWithCredentials, getCurrentFirebaseAuthUser, isCoordinator } from "./helpers/authentication"
export {
Expand Down
Binary file not shown.
65 changes: 65 additions & 0 deletions packages/actions/test/unit/verification.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import chai, { expect } from "chai"
import chaiAsPromised from "chai-as-promised"
import dotenv from "dotenv"
import { cwd } from "process"
import fs from "fs"
import { exportVerifierAndVKey, exportVerifierContract, exportVkey } from "../../src"
import { envType } from "../utils"
import { TestingEnvironment } from "../../src/types/enums"

chai.use(chaiAsPromised)
dotenv.config()

/**
* Unit test for Verification utilities.
*/

describe("Verification utilities", () => {
const finalZkeyPath = `${cwd()}/packages/actions/test/data/circuit-small_00001.zkey`
const verifierExportPath = `${cwd()}/packages/actions/test/data/verifier.sol`
const vKeyExportPath = `${cwd()}/packages/actions/test/data/vkey.json`
const solidityVersion = "0.8.10"
describe("exportVerifierContract", () => {
if (envType === TestingEnvironment.PRODUCTION) {
it("should export the verifier contract", async () => {
await exportVerifierContract(solidityVersion, finalZkeyPath, verifierExportPath)
expect(fs.existsSync(verifierExportPath)).to.be.true
})
}
it("should fail when the zkey is not found", async () => {
await expect(exportVerifierContract("0.8.0", "invalid-path", verifierExportPath)).to.be.rejected
})
})
describe("exportVkey", () => {
if (envType === TestingEnvironment.PRODUCTION) {
it("should export the vkey", async () => {
await exportVkey(finalZkeyPath, vKeyExportPath)
expect(fs.existsSync(vKeyExportPath)).to.be.true
})
}
it("should fail when the zkey is not found", async () => {
await expect(exportVkey("invalid-path", vKeyExportPath)).to.be.rejected
})
})
describe("exportVerifierAndVKey", () => {
if (envType === TestingEnvironment.PRODUCTION) {
it("should export the verifier contract and the vkey", async () => {
await exportVerifierAndVKey("0.8.0", finalZkeyPath, verifierExportPath, vKeyExportPath)
expect(fs.existsSync(verifierExportPath)).to.be.true
expect(fs.existsSync(vKeyExportPath)).to.be.true
})
}
it("should fail when the zkey is not found", async () => {
await expect(exportVerifierAndVKey("0.8.0", "invalid-path", verifierExportPath, vKeyExportPath)).to.be
.rejected
})
})
afterAll(() => {
if (fs.existsSync(verifierExportPath)) {
fs.unlinkSync(verifierExportPath)
}
if (fs.existsSync(vKeyExportPath)) {
fs.unlinkSync(vKeyExportPath)
}
})
})

0 comments on commit 1aed70e

Please sign in to comment.