mirror of
https://github.com/semaphore-protocol/semaphore.git
synced 2026-01-11 07:38:14 -05:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
88c3facbb7 | ||
|
|
2fc40bf710 | ||
|
|
78dcb705c5 | ||
|
|
3c75453e69 |
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@semaphore-protocol/cli-template-contracts-hardhat",
|
||||
"version": "3.13.0",
|
||||
"version": "3.15.0",
|
||||
"description": "Semaphore Hardhat template.",
|
||||
"license": "Unlicense",
|
||||
"files": [
|
||||
@@ -36,10 +36,10 @@
|
||||
"@nomicfoundation/hardhat-toolbox": "^2.0.0",
|
||||
"@nomiclabs/hardhat-ethers": "^2.0.0",
|
||||
"@nomiclabs/hardhat-etherscan": "^3.0.0",
|
||||
"@semaphore-protocol/group": "3.13.0",
|
||||
"@semaphore-protocol/hardhat": "3.13.0",
|
||||
"@semaphore-protocol/identity": "3.13.0",
|
||||
"@semaphore-protocol/proof": "3.13.0",
|
||||
"@semaphore-protocol/group": "3.15.0",
|
||||
"@semaphore-protocol/hardhat": "3.15.0",
|
||||
"@semaphore-protocol/identity": "3.15.0",
|
||||
"@semaphore-protocol/proof": "3.15.0",
|
||||
"@typechain/ethers-v5": "^10.1.0",
|
||||
"@typechain/hardhat": "^6.1.2",
|
||||
"@types/chai": "^4.2.0",
|
||||
@@ -58,7 +58,7 @@
|
||||
"typescript": ">=4.5.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@semaphore-protocol/contracts": "3.13.0"
|
||||
"@semaphore-protocol/contracts": "3.15.0"
|
||||
},
|
||||
"config": {
|
||||
"solidity": {
|
||||
|
||||
@@ -18,10 +18,10 @@
|
||||
"@nomicfoundation/hardhat-chai-matchers": "^1.0.5",
|
||||
"@nomiclabs/hardhat-ethers": "^2.0.0",
|
||||
"@nomiclabs/hardhat-etherscan": "^3.1.7",
|
||||
"@semaphore-protocol/group": "3.13.0",
|
||||
"@semaphore-protocol/hardhat": "3.13.0",
|
||||
"@semaphore-protocol/identity": "3.13.0",
|
||||
"@semaphore-protocol/proof": "3.13.0",
|
||||
"@semaphore-protocol/group": "3.15.0",
|
||||
"@semaphore-protocol/hardhat": "3.15.0",
|
||||
"@semaphore-protocol/identity": "3.15.0",
|
||||
"@semaphore-protocol/proof": "3.15.0",
|
||||
"@typechain/ethers-v5": "^10.0.0",
|
||||
"@typechain/hardhat": "^6.0.0",
|
||||
"@types/chai": "^4.3.1",
|
||||
@@ -40,7 +40,7 @@
|
||||
"typechain": "^8.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@semaphore-protocol/contracts": "3.13.0"
|
||||
"@semaphore-protocol/contracts": "3.15.0"
|
||||
},
|
||||
"config": {
|
||||
"solidity": {
|
||||
|
||||
@@ -10,10 +10,10 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@next/font": "13.0.3",
|
||||
"@semaphore-protocol/data": "3.13.0",
|
||||
"@semaphore-protocol/group": "3.13.0",
|
||||
"@semaphore-protocol/identity": "3.13.0",
|
||||
"@semaphore-protocol/proof": "3.13.0",
|
||||
"@semaphore-protocol/data": "3.15.0",
|
||||
"@semaphore-protocol/group": "3.15.0",
|
||||
"@semaphore-protocol/identity": "3.15.0",
|
||||
"@semaphore-protocol/proof": "3.15.0",
|
||||
"@types/react": "18.0.25",
|
||||
"@types/react-dom": "18.0.8",
|
||||
"dotenv": "^16.0.3",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@semaphore-protocol/cli-template-monorepo-ethers",
|
||||
"version": "3.13.0",
|
||||
"version": "3.15.0",
|
||||
"description": "Semaphore Hardhat + Next.js + SemaphoreEthers template.",
|
||||
"license": "Unlicense",
|
||||
"files": [
|
||||
|
||||
@@ -18,10 +18,10 @@
|
||||
"@nomicfoundation/hardhat-chai-matchers": "^1.0.5",
|
||||
"@nomiclabs/hardhat-ethers": "^2.0.0",
|
||||
"@nomiclabs/hardhat-etherscan": "^3.1.7",
|
||||
"@semaphore-protocol/group": "3.13.0",
|
||||
"@semaphore-protocol/hardhat": "3.13.0",
|
||||
"@semaphore-protocol/identity": "3.13.0",
|
||||
"@semaphore-protocol/proof": "3.13.0",
|
||||
"@semaphore-protocol/group": "3.15.0",
|
||||
"@semaphore-protocol/hardhat": "3.15.0",
|
||||
"@semaphore-protocol/identity": "3.15.0",
|
||||
"@semaphore-protocol/proof": "3.15.0",
|
||||
"@typechain/ethers-v5": "^10.0.0",
|
||||
"@typechain/hardhat": "^6.0.0",
|
||||
"@types/chai": "^4.3.1",
|
||||
@@ -40,7 +40,7 @@
|
||||
"typechain": "^8.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@semaphore-protocol/contracts": "3.13.0"
|
||||
"@semaphore-protocol/contracts": "3.15.0"
|
||||
},
|
||||
"config": {
|
||||
"solidity": {
|
||||
|
||||
@@ -10,10 +10,10 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@next/font": "13.0.3",
|
||||
"@semaphore-protocol/data": "3.13.0",
|
||||
"@semaphore-protocol/group": "3.13.0",
|
||||
"@semaphore-protocol/identity": "3.13.0",
|
||||
"@semaphore-protocol/proof": "3.13.0",
|
||||
"@semaphore-protocol/data": "3.15.0",
|
||||
"@semaphore-protocol/group": "3.15.0",
|
||||
"@semaphore-protocol/identity": "3.15.0",
|
||||
"@semaphore-protocol/proof": "3.15.0",
|
||||
"@types/react": "18.0.25",
|
||||
"@types/react-dom": "18.0.8",
|
||||
"dotenv": "^16.0.3",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@semaphore-protocol/cli-template-monorepo-subgraph",
|
||||
"version": "3.13.0",
|
||||
"version": "3.15.0",
|
||||
"description": "Semaphore Hardhat + Next.js + SemaphoreSubgraph template.",
|
||||
"license": "Unlicense",
|
||||
"files": [
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@semaphore-protocol/cli",
|
||||
"type": "module",
|
||||
"version": "3.13.0",
|
||||
"version": "3.15.0",
|
||||
"description": "A command line tool to set up your Semaphore project and get group data.",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
@@ -42,7 +42,7 @@
|
||||
"ts-node": "^10.9.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@semaphore-protocol/data": "3.13.0",
|
||||
"@semaphore-protocol/data": "3.15.0",
|
||||
"axios": "^1.3.2",
|
||||
"boxen": "^7.0.1",
|
||||
"chalk": "^5.1.2",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@semaphore-protocol/contracts",
|
||||
"version": "3.13.0",
|
||||
"version": "3.15.0",
|
||||
"description": "Semaphore contracts to manage groups and broadcast anonymous signals.",
|
||||
"license": "MIT",
|
||||
"files": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@semaphore-protocol/data",
|
||||
"version": "3.13.0",
|
||||
"version": "3.15.0",
|
||||
"description": "A library to query Semaphore contracts.",
|
||||
"license": "MIT",
|
||||
"main": "dist/index.node.js",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@semaphore-protocol/group",
|
||||
"version": "3.13.0",
|
||||
"version": "3.15.0",
|
||||
"description": "A library to create and manage Semaphore groups.",
|
||||
"license": "MIT",
|
||||
"main": "dist/index.node.js",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@semaphore-protocol/hardhat",
|
||||
"version": "3.13.0",
|
||||
"version": "3.15.0",
|
||||
"description": "A Semaphore Hardhat plugin to deploy verifiers and Semaphore contract.",
|
||||
"license": "MIT",
|
||||
"main": "dist/index.node.js",
|
||||
@@ -38,7 +38,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@nomiclabs/hardhat-ethers": "^2.1.1",
|
||||
"@semaphore-protocol/contracts": "3.13.0",
|
||||
"@semaphore-protocol/contracts": "3.15.0",
|
||||
"circomlibjs": "^0.1.7",
|
||||
"ethers": "^5.7.1",
|
||||
"hardhat-dependency-compiler": "^1.1.3"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@semaphore-protocol/heyauthn",
|
||||
"version": "3.13.0",
|
||||
"version": "3.15.0",
|
||||
"description": "A library to allow developers to create and manage Semaphore identities using WebAuthn",
|
||||
"license": "MIT",
|
||||
"main": "dist/index.node.js",
|
||||
@@ -33,7 +33,7 @@
|
||||
"rollup-plugin-typescript2": "^0.31.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@semaphore-protocol/identity": "3.13.0",
|
||||
"@semaphore-protocol/identity": "3.15.0",
|
||||
"@simplewebauthn/browser": "7.2.0",
|
||||
"@simplewebauthn/server": "7.2.0"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@semaphore-protocol/identity",
|
||||
"version": "3.13.0",
|
||||
"version": "3.15.0",
|
||||
"description": "A library to create Semaphore identities.",
|
||||
"license": "MIT",
|
||||
"main": "dist/index.node.js",
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
{
|
||||
"name": "@semaphore-protocol/proof",
|
||||
"version": "3.13.0",
|
||||
"version": "3.15.0",
|
||||
"description": "A library to generate and verify Semaphore proofs.",
|
||||
"license": "MIT",
|
||||
"main": "dist/index.node.js",
|
||||
"exports": {
|
||||
"node": {
|
||||
"import": "./dist/index.node.mjs",
|
||||
"require": "./dist/index.node.js"
|
||||
},
|
||||
"browser": "./dist/index.browser.mjs",
|
||||
"default": "./dist/index.browser.mjs"
|
||||
"import": "./dist/index.node.mjs",
|
||||
"require": "./dist/index.node.js"
|
||||
},
|
||||
"types": "dist/types/index.d.ts",
|
||||
"files": [
|
||||
@@ -26,21 +22,16 @@
|
||||
},
|
||||
"scripts": {
|
||||
"build:watch": "rollup -c rollup.config.ts -w --configPlugin typescript",
|
||||
"build": "rimraf dist && yarn build:browser && yarn build:node",
|
||||
"build:browser": "rollup -c rollup.browser.config.ts --configPlugin typescript",
|
||||
"build:node": "rollup -c rollup.node.config.ts --configPlugin typescript",
|
||||
"build": "rimraf dist && rollup -c rollup.config.ts --configPlugin typescript",
|
||||
"prepublishOnly": "yarn build"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@iden3/binfileutils": "0.0.11",
|
||||
"@rollup/plugin-commonjs": "^24.1.0",
|
||||
"@rollup/plugin-json": "^5.0.1",
|
||||
"@rollup/plugin-node-resolve": "^15.0.2",
|
||||
"@rollup/plugin-virtual": "^3.0.2",
|
||||
"fastfile": "0.0.20",
|
||||
"poseidon-lite": "^0.2.0",
|
||||
"rimraf": "^5.0.5",
|
||||
"rollup": "^4.0.2",
|
||||
@@ -48,16 +39,15 @@
|
||||
"rollup-plugin-typescript2": "^0.31.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@semaphore-protocol/group": "3.13.0",
|
||||
"@semaphore-protocol/identity": "3.13.0"
|
||||
"@semaphore-protocol/group": "3.15.0",
|
||||
"@semaphore-protocol/identity": "3.15.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ethersproject/bignumber": "^5.5.0",
|
||||
"@ethersproject/bytes": "^5.7.0",
|
||||
"@ethersproject/keccak256": "^5.7.0",
|
||||
"@ethersproject/strings": "^5.5.0",
|
||||
"@zk-kit/incremental-merkle-tree": "0.4.3",
|
||||
"circom_runtime": "0.1.24",
|
||||
"ffjavascript": "0.2.60"
|
||||
"@zk-kit/groth16": "0.1.0",
|
||||
"@zk-kit/incremental-merkle-tree": "0.4.3"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
import commonjs from "@rollup/plugin-commonjs"
|
||||
import json from "@rollup/plugin-json"
|
||||
import { nodeResolve } from "@rollup/plugin-node-resolve"
|
||||
import virtual from "@rollup/plugin-virtual"
|
||||
import * as fs from "fs"
|
||||
import cleanup from "rollup-plugin-cleanup"
|
||||
import typescript from "rollup-plugin-typescript2"
|
||||
|
||||
// Needed by fastfile.
|
||||
import { O_CREAT, O_EXCL, O_RDONLY, O_RDWR, O_TRUNC } from "constants"
|
||||
|
||||
const constants = `
|
||||
export const O_TRUNC = ${O_TRUNC};
|
||||
export const O_CREAT = ${O_CREAT};
|
||||
export const O_RDWR = ${O_RDWR};
|
||||
export const O_EXCL = ${O_EXCL};
|
||||
export const O_RDONLY = ${O_RDONLY}
|
||||
`
|
||||
|
||||
const empty = "export default {}"
|
||||
|
||||
const pkg = JSON.parse(fs.readFileSync("./package.json", "utf-8"))
|
||||
const banner = `/**
|
||||
* @module ${pkg.name}
|
||||
* @version ${pkg.version}
|
||||
* @file ${pkg.description}
|
||||
* @copyright Ethereum Foundation 2022
|
||||
* @license ${pkg.license}
|
||||
* @see [Github]{@link ${pkg.homepage}}
|
||||
*/`
|
||||
|
||||
export default {
|
||||
input: "src/index.ts",
|
||||
output: [
|
||||
{
|
||||
file: pkg.exports.browser,
|
||||
format: "es",
|
||||
banner
|
||||
}
|
||||
],
|
||||
external: Object.keys(pkg.dependencies),
|
||||
plugins: [
|
||||
typescript({
|
||||
tsconfig: "./build.tsconfig.json",
|
||||
useTsconfigDeclarationDir: true
|
||||
}),
|
||||
virtual({
|
||||
fs: empty,
|
||||
constants
|
||||
}),
|
||||
nodeResolve(),
|
||||
commonjs({
|
||||
esmExternals: true
|
||||
}),
|
||||
cleanup({ comments: "jsdoc" }),
|
||||
json()
|
||||
]
|
||||
}
|
||||
@@ -19,13 +19,13 @@ export default {
|
||||
input: "src/index.ts",
|
||||
output: [
|
||||
{
|
||||
file: pkg.exports.node.require,
|
||||
file: pkg.exports.require,
|
||||
format: "cjs",
|
||||
banner,
|
||||
exports: "auto"
|
||||
},
|
||||
{
|
||||
file: pkg.exports.node.import,
|
||||
file: pkg.exports.import,
|
||||
format: "es",
|
||||
banner
|
||||
}
|
||||
@@ -2,12 +2,12 @@ import { BigNumber } from "@ethersproject/bignumber"
|
||||
import { BytesLike, Hexable } from "@ethersproject/bytes"
|
||||
import { Group } from "@semaphore-protocol/group"
|
||||
import type { Identity } from "@semaphore-protocol/identity"
|
||||
import { prove } from "@zk-kit/groth16"
|
||||
import { MerkleProof } from "@zk-kit/incremental-merkle-tree"
|
||||
import type { NumericString } from "snarkjs"
|
||||
import hash from "./hash"
|
||||
import packProof from "./packProof"
|
||||
import { SemaphoreProof, SnarkArtifacts } from "./types"
|
||||
import groth16Prove from "./groth16/prove"
|
||||
|
||||
/**
|
||||
* Generates a Semaphore proof.
|
||||
@@ -46,7 +46,7 @@ export default async function generateProof(
|
||||
}
|
||||
}
|
||||
|
||||
const { proof, publicSignals } = await groth16Prove(
|
||||
const { proof, publicSignals } = await prove(
|
||||
{
|
||||
identityTrapdoor: trapdoor,
|
||||
identityNullifier: nullifier,
|
||||
|
||||
@@ -1,226 +0,0 @@
|
||||
/* eslint-disable no-plusplus */
|
||||
/* eslint-disable eqeqeq */
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
/* istanbul ignore file */
|
||||
|
||||
// @ts-ignore
|
||||
import * as binFileUtils from "@iden3/binfileutils"
|
||||
import { BigBuffer, Scalar, utils } from "ffjavascript"
|
||||
import { log2 } from "./utils"
|
||||
import * as zkeyUtils from "./zkey-utils"
|
||||
import * as wtnsUtils from "./wtns-utils"
|
||||
import wtnsCalculate from "./wtns-calculate"
|
||||
|
||||
const { stringifyBigInts, unstringifyBigInts } = utils
|
||||
|
||||
async function buildABC1(curve: any, zkey: any, witness: any, coeffs: any) {
|
||||
const { n8 } = curve.Fr
|
||||
const sCoef = 4 * 3 + zkey.n8r
|
||||
const nCoef = (coeffs.byteLength - 4) / sCoef
|
||||
|
||||
const outBuffA = new BigBuffer(zkey.domainSize * n8)
|
||||
const outBuffB = new BigBuffer(zkey.domainSize * n8)
|
||||
const outBuffC = new BigBuffer(zkey.domainSize * n8)
|
||||
|
||||
const outBuf = [outBuffA, outBuffB]
|
||||
for (let i = 0; i < nCoef; i++) {
|
||||
const buffCoef = coeffs.slice(4 + i * sCoef, 4 + i * sCoef + sCoef)
|
||||
const buffCoefV = new DataView(buffCoef.buffer)
|
||||
const m = buffCoefV.getUint32(0, true)
|
||||
const c = buffCoefV.getUint32(4, true)
|
||||
const s = buffCoefV.getUint32(8, true)
|
||||
const coef = buffCoef.slice(12, 12 + n8)
|
||||
outBuf[m].set(
|
||||
curve.Fr.add(outBuf[m].slice(c * n8, c * n8 + n8), curve.Fr.mul(coef, witness.slice(s * n8, s * n8 + n8))),
|
||||
c * n8
|
||||
)
|
||||
}
|
||||
|
||||
for (let i = 0; i < zkey.domainSize; i++) {
|
||||
outBuffC.set(curve.Fr.mul(outBuffA.slice(i * n8, i * n8 + n8), outBuffB.slice(i * n8, i * n8 + n8)), i * n8)
|
||||
}
|
||||
|
||||
return [outBuffA, outBuffB, outBuffC]
|
||||
}
|
||||
|
||||
async function joinABC(curve: any, _zkey: any, a: any, b: any, c: any) {
|
||||
const MAX_CHUNK_SIZE = 1 << 22
|
||||
|
||||
const { n8 } = curve.Fr
|
||||
const nElements = Math.floor(a.byteLength / curve.Fr.n8)
|
||||
|
||||
const promises = []
|
||||
|
||||
for (let i = 0; i < nElements; i += MAX_CHUNK_SIZE) {
|
||||
const n = Math.min(nElements - i, MAX_CHUNK_SIZE)
|
||||
|
||||
const task = []
|
||||
|
||||
const aChunk = a.slice(i * n8, (i + n) * n8)
|
||||
const bChunk = b.slice(i * n8, (i + n) * n8)
|
||||
const cChunk = c.slice(i * n8, (i + n) * n8)
|
||||
|
||||
task.push({ cmd: "ALLOCSET", var: 0, buff: aChunk })
|
||||
task.push({ cmd: "ALLOCSET", var: 1, buff: bChunk })
|
||||
task.push({ cmd: "ALLOCSET", var: 2, buff: cChunk })
|
||||
task.push({ cmd: "ALLOC", var: 3, len: n * n8 })
|
||||
task.push({
|
||||
cmd: "CALL",
|
||||
fnName: "qap_joinABC",
|
||||
params: [{ var: 0 }, { var: 1 }, { var: 2 }, { val: n }, { var: 3 }]
|
||||
})
|
||||
task.push({ cmd: "CALL", fnName: "frm_batchFromMontgomery", params: [{ var: 3 }, { val: n }, { var: 3 }] })
|
||||
task.push({ cmd: "GET", out: 0, var: 3, len: n * n8 })
|
||||
promises.push(curve.tm.queueAction(task))
|
||||
}
|
||||
|
||||
const result = await Promise.all(promises)
|
||||
|
||||
let outBuff
|
||||
if (a instanceof BigBuffer) {
|
||||
// @ts-ignore
|
||||
outBuff = new BigBuffer(a.byteLength)
|
||||
} else {
|
||||
outBuff = new Uint8Array(a.byteLength)
|
||||
}
|
||||
|
||||
let p = 0
|
||||
for (let i = 0; i < result.length; i++) {
|
||||
outBuff.set(result[i][0], p)
|
||||
p += result[i][0].byteLength
|
||||
}
|
||||
|
||||
return outBuff
|
||||
}
|
||||
|
||||
export default async function groth16Prove(_input: any, wasmFile: any, zkeyFileName: any) {
|
||||
const input = unstringifyBigInts(_input)
|
||||
|
||||
const witnessFileName = {
|
||||
type: "mem"
|
||||
}
|
||||
|
||||
await wtnsCalculate(input, wasmFile, witnessFileName)
|
||||
|
||||
const { fd: fdWtns, sections: sectionsWtns } = await binFileUtils.readBinFile(
|
||||
witnessFileName,
|
||||
"wtns",
|
||||
2,
|
||||
1 << 25,
|
||||
1 << 23
|
||||
)
|
||||
|
||||
const wtns = await wtnsUtils.readHeader(fdWtns, sectionsWtns)
|
||||
|
||||
const { fd: fdZKey, sections: sectionsZKey } = await binFileUtils.readBinFile(
|
||||
zkeyFileName,
|
||||
"zkey",
|
||||
2,
|
||||
1 << 25,
|
||||
1 << 23
|
||||
)
|
||||
|
||||
const zkey = await zkeyUtils.readHeader(fdZKey, sectionsZKey, undefined)
|
||||
|
||||
if (zkey.protocol !== "groth16") {
|
||||
throw new Error("zkey file is not groth16")
|
||||
}
|
||||
|
||||
if (!Scalar.eq(zkey.r, wtns.q)) {
|
||||
throw new Error("Curve of the witness does not match the curve of the proving key")
|
||||
}
|
||||
|
||||
if (wtns.nWitness !== zkey.nVars) {
|
||||
throw new Error(`Invalid witness length. Circuit: ${zkey.nVars}, witness: ${wtns.nWitness}`)
|
||||
}
|
||||
|
||||
const { curve } = zkey
|
||||
const { Fr } = curve
|
||||
const { G1 } = curve
|
||||
const { G2 } = curve
|
||||
|
||||
const power = log2(zkey.domainSize)
|
||||
|
||||
const buffWitness = await binFileUtils.readSection(fdWtns, sectionsWtns, 2)
|
||||
const buffCoeffs = await binFileUtils.readSection(fdZKey, sectionsZKey, 4)
|
||||
|
||||
const [buffA_T, buffB_T, buffC_T] = await buildABC1(curve, zkey, buffWitness, buffCoeffs)
|
||||
|
||||
const inc = power == Fr.s ? curve.Fr.shift : curve.Fr.w[power + 1]
|
||||
|
||||
const buffA = await Fr.ifft(buffA_T, "", "", undefined, "IFFT_A")
|
||||
const buffAodd = await Fr.batchApplyKey(buffA, Fr.e(1), inc)
|
||||
const buffAodd_T = await Fr.fft(buffAodd, "", "", undefined, "FFT_A")
|
||||
|
||||
const buffB = await Fr.ifft(buffB_T, "", "", undefined, "IFFT_B")
|
||||
const buffBodd = await Fr.batchApplyKey(buffB, Fr.e(1), inc)
|
||||
const buffBodd_T = await Fr.fft(buffBodd, "", "", undefined, "FFT_B")
|
||||
|
||||
const buffC = await Fr.ifft(buffC_T, "", "", undefined, "IFFT_C")
|
||||
const buffCodd = await Fr.batchApplyKey(buffC, Fr.e(1), inc)
|
||||
const buffCodd_T = await Fr.fft(buffCodd, "", "", undefined, "FFT_C")
|
||||
|
||||
const buffPodd_T = await joinABC(curve, zkey, buffAodd_T, buffBodd_T, buffCodd_T)
|
||||
|
||||
let proof: any = {}
|
||||
|
||||
const buffBasesA = await binFileUtils.readSection(fdZKey, sectionsZKey, 5)
|
||||
proof.pi_a = await curve.G1.multiExpAffine(buffBasesA, buffWitness, undefined, "multiexp A")
|
||||
|
||||
const buffBasesB1 = await binFileUtils.readSection(fdZKey, sectionsZKey, 6)
|
||||
let pib1 = await curve.G1.multiExpAffine(buffBasesB1, buffWitness, undefined, "multiexp B1")
|
||||
|
||||
const buffBasesB2 = await binFileUtils.readSection(fdZKey, sectionsZKey, 7)
|
||||
proof.pi_b = await curve.G2.multiExpAffine(buffBasesB2, buffWitness, undefined, "multiexp B2")
|
||||
|
||||
const buffBasesC = await binFileUtils.readSection(fdZKey, sectionsZKey, 8)
|
||||
proof.pi_c = await curve.G1.multiExpAffine(
|
||||
buffBasesC,
|
||||
buffWitness.slice((zkey.nPublic + 1) * curve.Fr.n8),
|
||||
undefined,
|
||||
"multiexp C"
|
||||
)
|
||||
|
||||
const buffBasesH = await binFileUtils.readSection(fdZKey, sectionsZKey, 9)
|
||||
const resH = await curve.G1.multiExpAffine(buffBasesH, buffPodd_T, undefined, "multiexp H")
|
||||
|
||||
const r = curve.Fr.random()
|
||||
const s = curve.Fr.random()
|
||||
|
||||
proof.pi_a = G1.add(proof.pi_a, zkey.vk_alpha_1)
|
||||
proof.pi_a = G1.add(proof.pi_a, G1.timesFr(zkey.vk_delta_1, r))
|
||||
|
||||
proof.pi_b = G2.add(proof.pi_b, zkey.vk_beta_2)
|
||||
proof.pi_b = G2.add(proof.pi_b, G2.timesFr(zkey.vk_delta_2, s))
|
||||
|
||||
pib1 = G1.add(pib1, zkey.vk_beta_1)
|
||||
pib1 = G1.add(pib1, G1.timesFr(zkey.vk_delta_1, s))
|
||||
|
||||
proof.pi_c = G1.add(proof.pi_c, resH)
|
||||
|
||||
proof.pi_c = G1.add(proof.pi_c, G1.timesFr(proof.pi_a, s))
|
||||
proof.pi_c = G1.add(proof.pi_c, G1.timesFr(pib1, r))
|
||||
proof.pi_c = G1.add(proof.pi_c, G1.timesFr(zkey.vk_delta_1, Fr.neg(Fr.mul(r, s))))
|
||||
|
||||
let publicSignals = []
|
||||
|
||||
for (let i = 1; i <= zkey.nPublic; i++) {
|
||||
const b = buffWitness.slice(i * Fr.n8, i * Fr.n8 + Fr.n8)
|
||||
publicSignals.push(Scalar.fromRprLE(b, undefined, undefined))
|
||||
}
|
||||
|
||||
proof.pi_a = G1.toObject(G1.toAffine(proof.pi_a))
|
||||
proof.pi_b = G2.toObject(G2.toAffine(proof.pi_b))
|
||||
proof.pi_c = G1.toObject(G1.toAffine(proof.pi_c))
|
||||
|
||||
proof.protocol = "groth16"
|
||||
proof.curve = curve.name
|
||||
|
||||
await fdZKey.close()
|
||||
await fdWtns.close()
|
||||
|
||||
proof = stringifyBigInts(proof)
|
||||
publicSignals = stringifyBigInts(publicSignals)
|
||||
|
||||
return { proof, publicSignals }
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
/* eslint-disable import/prefer-default-export */
|
||||
/* eslint-disable no-return-assign */
|
||||
/* istanbul ignore file */
|
||||
|
||||
export function log2(V: any) {
|
||||
return (
|
||||
((V & 0xffff0000) !== 0 ? ((V &= 0xffff0000), 16) : 0) |
|
||||
((V & 0xff00ff00) !== 0 ? ((V &= 0xff00ff00), 8) : 0) |
|
||||
((V & 0xf0f0f0f0) !== 0 ? ((V &= 0xf0f0f0f0), 4) : 0) |
|
||||
((V & 0xcccccccc) !== 0 ? ((V &= 0xcccccccc), 2) : 0) |
|
||||
// @ts-ignore
|
||||
((V & 0xaaaaaaaa) !== 0)
|
||||
)
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
/* eslint-disable no-plusplus */
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
/* istanbul ignore file */
|
||||
|
||||
import { Scalar, utils, buildBn128 } from "ffjavascript"
|
||||
|
||||
const { unstringifyBigInts } = utils
|
||||
|
||||
function isWellConstructed(curve: any, proof: any) {
|
||||
const { G1 } = curve
|
||||
const { G2 } = curve
|
||||
|
||||
return G1.isValid(proof.pi_a) && G2.isValid(proof.pi_b) && G1.isValid(proof.pi_c)
|
||||
}
|
||||
|
||||
function publicInputsAreValid(curve: any, publicInputs: any) {
|
||||
for (let i = 0; i < publicInputs.length; i++) {
|
||||
if (!Scalar.lt(publicInputs[i], curve.r)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
export default async function groth16Verify(_vk_verifier: any, _publicSignals: any, _proof: any) {
|
||||
const vk_verifier = unstringifyBigInts(_vk_verifier)
|
||||
const proof = unstringifyBigInts(_proof)
|
||||
const publicSignals = unstringifyBigInts(_publicSignals)
|
||||
|
||||
const curve = await buildBn128(undefined, undefined)
|
||||
|
||||
const IC0 = curve.G1.fromObject(vk_verifier.IC[0])
|
||||
const IC = new Uint8Array(curve.G1.F.n8 * 2 * publicSignals.length)
|
||||
const w = new Uint8Array(curve.Fr.n8 * publicSignals.length)
|
||||
|
||||
if (!publicInputsAreValid(curve, publicSignals)) {
|
||||
return false
|
||||
}
|
||||
|
||||
for (let i = 0; i < publicSignals.length; i++) {
|
||||
const buffP = curve.G1.fromObject(vk_verifier.IC[i + 1])
|
||||
IC.set(buffP, i * curve.G1.F.n8 * 2)
|
||||
Scalar.toRprLE(w, curve.Fr.n8 * i, publicSignals[i], curve.Fr.n8)
|
||||
}
|
||||
|
||||
let cpub = await curve.G1.multiExpAffine(IC, w)
|
||||
cpub = curve.G1.add(cpub, IC0)
|
||||
|
||||
const pi_a = curve.G1.fromObject(proof.pi_a)
|
||||
const pi_b = curve.G2.fromObject(proof.pi_b)
|
||||
const pi_c = curve.G1.fromObject(proof.pi_c)
|
||||
|
||||
if (!isWellConstructed(curve, { pi_a, pi_b, pi_c })) {
|
||||
return false
|
||||
}
|
||||
|
||||
const vk_gamma_2 = curve.G2.fromObject(vk_verifier.vk_gamma_2)
|
||||
const vk_delta_2 = curve.G2.fromObject(vk_verifier.vk_delta_2)
|
||||
const vk_alpha_1 = curve.G1.fromObject(vk_verifier.vk_alpha_1)
|
||||
const vk_beta_2 = curve.G2.fromObject(vk_verifier.vk_beta_2)
|
||||
|
||||
return curve.pairingEq(
|
||||
curve.G1.neg(pi_a),
|
||||
pi_b,
|
||||
cpub,
|
||||
vk_gamma_2,
|
||||
pi_c,
|
||||
vk_delta_2,
|
||||
|
||||
vk_alpha_1,
|
||||
vk_beta_2
|
||||
)
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
/* eslint-disable eqeqeq */
|
||||
/* istanbul ignore file */
|
||||
|
||||
// @ts-ignore
|
||||
import * as binFileUtils from "@iden3/binfileutils"
|
||||
// @ts-ignore
|
||||
import { WitnessCalculatorBuilder } from "circom_runtime"
|
||||
// @ts-ignore
|
||||
import * as fastFile from "fastfile"
|
||||
import { utils } from "ffjavascript"
|
||||
import * as wtnsUtils from "./wtns-utils"
|
||||
|
||||
const { unstringifyBigInts } = utils
|
||||
|
||||
export default async function wtnsCalculate(_input: any, wasmFileName: any, wtnsFileName: any) {
|
||||
const input = unstringifyBigInts(_input)
|
||||
|
||||
const fdWasm = await fastFile.readExisting(wasmFileName)
|
||||
const wasm = await fdWasm.read(fdWasm.totalSize)
|
||||
await fdWasm.close()
|
||||
|
||||
const wc = await WitnessCalculatorBuilder(wasm)
|
||||
|
||||
if (wc.circom_version() == 1) {
|
||||
const w = await wc.calculateBinWitness(input)
|
||||
|
||||
const fdWtns = await binFileUtils.createBinFile(wtnsFileName, "wtns", 2, 2)
|
||||
|
||||
await wtnsUtils.writeBin(fdWtns, w, wc.prime)
|
||||
await fdWtns.close()
|
||||
} else {
|
||||
const fdWtns = await fastFile.createOverride(wtnsFileName)
|
||||
|
||||
const w = await wc.calculateWTNSBin(input)
|
||||
|
||||
await fdWtns.write(w)
|
||||
await fdWtns.close()
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
/* eslint-disable eqeqeq */
|
||||
/* istanbul ignore file */
|
||||
|
||||
// @ts-ignore
|
||||
import * as binFileUtils from "@iden3/binfileutils"
|
||||
import { Scalar } from "ffjavascript"
|
||||
|
||||
export async function writeBin(fd: any, witnessBin: any, prime: any) {
|
||||
await binFileUtils.startWriteSection(fd, 1)
|
||||
const n8 = (Math.floor((Scalar.bitLength(prime) - 1) / 64) + 1) * 8
|
||||
await fd.writeULE32(n8)
|
||||
await binFileUtils.writeBigInt(fd, prime, n8)
|
||||
if (witnessBin.byteLength % n8 != 0) {
|
||||
throw new Error("Invalid witness length")
|
||||
}
|
||||
await fd.writeULE32(witnessBin.byteLength / n8)
|
||||
await binFileUtils.endWriteSection(fd)
|
||||
|
||||
await binFileUtils.startWriteSection(fd, 2)
|
||||
await fd.write(witnessBin)
|
||||
await binFileUtils.endWriteSection(fd)
|
||||
}
|
||||
|
||||
export async function readHeader(fd: any, sections: any) {
|
||||
await binFileUtils.startReadUniqueSection(fd, sections, 1)
|
||||
const n8 = await fd.readULE32()
|
||||
const q = await binFileUtils.readBigInt(fd, n8)
|
||||
const nWitness = await fd.readULE32()
|
||||
await binFileUtils.endReadSection(fd)
|
||||
|
||||
return { n8, q, nWitness }
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
/* eslint-disable import/prefer-default-export */
|
||||
/* istanbul ignore file */
|
||||
|
||||
// @ts-ignore
|
||||
import * as binFileUtils from "@iden3/binfileutils"
|
||||
import { buildBn128 } from "ffjavascript"
|
||||
import { log2 } from "./utils"
|
||||
|
||||
async function readG1(fd: any, curve: any, toObject: any) {
|
||||
const buff = await fd.read(curve.G1.F.n8 * 2)
|
||||
const res = curve.G1.fromRprLEM(buff, 0)
|
||||
return toObject ? curve.G1.toObject(res) : res
|
||||
}
|
||||
|
||||
async function readG2(fd: any, curve: any, toObject: any) {
|
||||
const buff = await fd.read(curve.G2.F.n8 * 2)
|
||||
const res = curve.G2.fromRprLEM(buff, 0)
|
||||
return toObject ? curve.G2.toObject(res) : res
|
||||
}
|
||||
|
||||
async function readHeaderGroth16(fd: any, sections: any, toObject: any) {
|
||||
const zkey: any = {}
|
||||
|
||||
zkey.protocol = "groth16"
|
||||
|
||||
await binFileUtils.startReadUniqueSection(fd, sections, 2)
|
||||
const n8q = await fd.readULE32()
|
||||
zkey.n8q = n8q
|
||||
zkey.q = await binFileUtils.readBigInt(fd, n8q)
|
||||
|
||||
const n8r = await fd.readULE32()
|
||||
zkey.n8r = n8r
|
||||
zkey.r = await binFileUtils.readBigInt(fd, n8r)
|
||||
zkey.curve = await buildBn128(undefined, undefined)
|
||||
zkey.nVars = await fd.readULE32()
|
||||
zkey.nPublic = await fd.readULE32()
|
||||
zkey.domainSize = await fd.readULE32()
|
||||
zkey.power = log2(zkey.domainSize)
|
||||
zkey.vk_alpha_1 = await readG1(fd, zkey.curve, toObject)
|
||||
zkey.vk_beta_1 = await readG1(fd, zkey.curve, toObject)
|
||||
zkey.vk_beta_2 = await readG2(fd, zkey.curve, toObject)
|
||||
zkey.vk_gamma_2 = await readG2(fd, zkey.curve, toObject)
|
||||
zkey.vk_delta_1 = await readG1(fd, zkey.curve, toObject)
|
||||
zkey.vk_delta_2 = await readG2(fd, zkey.curve, toObject)
|
||||
await binFileUtils.endReadSection(fd)
|
||||
|
||||
return zkey
|
||||
}
|
||||
|
||||
export async function readHeader(fd: any, sections: any, toObject: any) {
|
||||
await binFileUtils.startReadUniqueSection(fd, sections, 1)
|
||||
const protocolId = await fd.readULE32()
|
||||
await binFileUtils.endReadSection(fd)
|
||||
|
||||
if (protocolId === 1) {
|
||||
return readHeaderGroth16(fd, sections, toObject)
|
||||
}
|
||||
|
||||
throw new Error("Protocol not supported: ")
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
import { verify } from "@zk-kit/groth16"
|
||||
import hash from "./hash"
|
||||
import { SemaphoreProof } from "./types"
|
||||
import unpackProof from "./unpackProof"
|
||||
import verificationKeys from "./verificationKeys.json"
|
||||
import groth16Verify from "./groth16/verify"
|
||||
|
||||
/**
|
||||
* Verifies a Semaphore proof.
|
||||
@@ -24,9 +24,8 @@ export default function verifyProof(
|
||||
IC: verificationKeys.IC[treeDepth - 16]
|
||||
}
|
||||
|
||||
return groth16Verify(
|
||||
verificationKey,
|
||||
[merkleTreeRoot, nullifierHash, hash(signal), hash(externalNullifier)],
|
||||
unpackProof(proof)
|
||||
)
|
||||
return verify(verificationKey, {
|
||||
publicSignals: [merkleTreeRoot, nullifierHash, hash(signal), hash(externalNullifier)],
|
||||
proof: unpackProof(proof)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"allowJs": true
|
||||
},
|
||||
"include": ["src", "rollup.config.ts"]
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
dc2f95a0a229d9a66a7b3900e3f2c2eeb3c4cd81
|
||||
56f1eae9f45dc17131882a1e18bd4d2997714e07
|
||||
Reference in New Issue
Block a user