UniRep circuits package
Client library for circuit related functions which are used in UniRep protocol.
💡 About UniRep
UniRep is a private and non-repudiable data system. Users can receive attestations from attesters, and voluntarily prove facts about their data without revealing the data itself. Moreover, users cannot refuse to receive attestations from an attester.
📘 Documentation
Read the medium article to know more about the concept of UniRep protocol.
For more information, refer to the documentation
🛠 Install
npm or yarn
Install the @unirep/circuits
package with npm:
npm i @unirep/circuits
or yarn:
yarn add @unirep/circuits
📔 Usage
Prover
Build a prover for UniRep protocol
import * as snarkjs from 'snarkjs'
import { Circuit, Prover } from '@unirep/circuits'
import { SnarkProof, SnarkPublicSignals } from '@unirep/utils'
const buildPath = 'PATH/TO/CIRCUIT/FOLDER/'
const prover: Prover = {
genProofAndPublicSignals: async (
proofType: string | Circuit,
inputs: any
): Promise<{
proof: any,
publicSignals: any
}> => {
const circuitWasmPath = buildPath + `${proofType}.wasm`
const zkeyPath = buildPath + `${proofType}.zkey`
const { proof, publicSignals } = await snarkjs.groth16.fullProve(
inputs,
circuitWasmPath,
zkeyPath
)
return { proof, publicSignals }
},
verifyProof: async (
name: string | Circuit,
publicSignals: SnarkPublicSignals,
proof: SnarkProof
): Promise<boolean> => {
const vkey = require(buildPath + `${name}.vkey.json`)
return snarkjs.groth16.verify(vkey, publicSignals, proof)
},
}
Generate proof and verify it with the above prover
import { Circuit } from '@unirep/circuits'
const circuitInputs = {
state_tree_elements: ...,
state_tree_indexes: ...,
...
}
const { proof, publicSignals } = await prover.genProofAndPublicSignals(
Circuit.epochKey,
circuitInputs
)
const isValid = await prover.verifyProof(
Circuit.epochKey,
publicSignals,
proof
)
Circom
Use the unirep circom circuits like so:
pragma circom 2.0.0;
include "PATH/TO/node_modules/@unirep/circuits/circuits/epochKey.circom";
template DataProof(STATE_TREE_DEPTH, EPOCH_KEY_NONCE_PER_EPOCH, FIELD_COUNT) {
signal input state_tree_indexes[STATE_TREE_DEPTH];
signal input state_tree_elements[STATE_TREE_DEPTH];
signal input identity_secret;
signal input data[FIELD_COUNT];
signal input sig_data;
signal input reveal_nonce;
signal input attester_id;
signal input epoch;
signal input nonce;
signal output epoch_key;
signal output state_tree_root;
component epoch_key_template = EpochKey(STATE_TREE_DEPTH, EPOCH_KEY_NONCE_PER_EPOCH, FIELD_COUNT);
for (var x = 0; x < STATE_TREE_DEPTH; x++) {
epoch_key_template.state_tree_indexes[x] <== state_tree_indexes[x];
epoch_key_template.state_tree_elements[x] <== state_tree_elements[x];
}
epoch_key_template.identity_secret <== identity_secret;
epoch_key_template.reveal_nonce <== reveal_nonce;
epoch_key_template.attester_id <== attester_id;
epoch_key_template.epoch <== epoch;
epoch_key_template.nonce <== nonce;
epoch_key_template.sig_data <== sig_data;
control <== epoch_key_template.control;
epoch_key <== epoch_key_template.epoch_key;
// add your customized circuits
...
}
Proof helpers
Proof helpers can help users query the public signals in each proof.
EpochKeyProof
import { EpochKeyProof } from '@unirep/circuits'
const { proof, publicSignals } = await prover.genProofAndPublicSignals(
Circuit.epochKey,
circuitInputs
)
const data = new EpochKeyProof(publicSignals, proof)
const epk = data.epochKey
SignupProof
import { SignupProof } from '@unirep/circuits'
const { proof, publicSignals } = await prover.genProofAndPublicSignals(
Circuit.signup,
circuitInputs
)
const data = new SignupProof(publicSignals, proof)
const idCommitment = data.identityCommitment
- Discord server:
- Twitter account:
- Telegram group:
Privacy & Scaling Explorations
This project is supported by Privacy & Scaling Explorations in Ethereum Foundation.
See more projects on: https://appliedzkp.org/.