Skip to content

Instantly share code, notes, and snippets.

@yann300
Created February 19, 2024 12:57
Show Gist options
  • Save yann300/0deac54cd1bd1fc545b85aa6895ae8eb to your computer and use it in GitHub Desktop.
Save yann300/0deac54cd1bd1fc545b85aa6895ae8eb to your computer and use it in GitHub Desktop.
Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=soljson-v0.8.24+commit.e11b9ed9.js&optimize=false&runs=200&gist=
// eslint-disable-next-line @typescript-eslint/no-var-requires
const snarkjs = require('snarkjs');
const logger = {
info: (...args) => console.log(...args),
debug: (...args) => console.log(...args)
};
(async () => {
try {
// @ts-ignore
await remix.call('circuit-compiler', 'generateR1cs', 'circuits/calculate_hash.circom');
const ptau_final = "https://ipfs-cluster.ethdevops.io/ipfs/QmTiT4eiYz5KF7gQrDsgfCSTRv3wBPYJ4bRN1MmTRshpnW";
// @ts-ignore
const r1csBuffer = await remix.call('fileManager', 'readFile', 'circuits/.bin/calculate_hash.r1cs', true);
// @ts-ignore
const r1cs = new Uint8Array(r1csBuffer);
const zkey_0 = { type: "mem" };
const zkey_1 = { type: "mem" };
const zkey_final = { type: "mem" };
console.log('newZkey')
await snarkjs.zKey.newZKey(r1cs, ptau_final, zkey_0);
console.log('contribute')
await snarkjs.zKey.contribute(zkey_0, zkey_1, "p2_C1", "pa_Entropy1");
console.log('beacon')
await snarkjs.zKey.beacon(zkey_1, zkey_final, "B3", "0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20", 10);
console.log('verifyFromR1cs')
const verifyFromR1csResult = await snarkjs.zKey.verifyFromR1cs(r1cs, ptau_final, zkey_final);
console.assert(verifyFromR1csResult);
console.log('verifyFromInit')
const verifyFromInit = await snarkjs.zKey.verifyFromInit(zkey_0, ptau_final, zkey_final);
console.assert(verifyFromInit);
console.log('exportVerificationKey')
const vKey = await snarkjs.zKey.exportVerificationKey(zkey_final)
await remix.call('fileManager', 'writeFile', './zk/build/verification_key.json', JSON.stringify(vKey))
const templates = {
groth16: await remix.call('fileManager', 'readFile', 'templates/groth16_verifier.sol.ejs')
}
const solidityContract = await snarkjs.zKey.exportSolidityVerifier(zkey_final, templates)
await remix.call('fileManager', 'writeFile', './zk/build/zk_verifier.sol', solidityContract)
console.log('buffer', (zkey_final as any).data.length)
await remix.call('fileManager', 'writeFile', './zk/build/zk_setup.txt', JSON.stringify(Array.from(((zkey_final as any).data))))
console.log('setup done.')
} catch (e) {
console.error(e.message)
}
})()
import client from 'sindri'
const run = async () => {
try {
console.log('setting up circuit...')
client.authorize({ apiKey: 'sindri-crT1D0Hr4ORryTl3yMV9eH2tEdLNIF25-R8nS' })
console.log(client.apiKey)
const gistPrefix = 'gist-904e280efde30ae45e988addf81542dc'
const poseidonConstant = await remix.call('fileManager', 'readFile', `./${gistPrefix}/.deps/https/raw.githubusercontent.com/iden3/circomlib/master/circuits/poseidon.circom`)
const poseidon = await remix.call('fileManager', 'readFile', `./${gistPrefix}/.deps/https/raw.githubusercontent.com/iden3/circomlib/master/circuits/poseidon.circom`)
const circuit = await remix.call('fileManager', 'readFile', `./${gistPrefix}/circuits/calculate_hash.circom`)
const sindriConf = await remix.call('fileManager', 'readFile', `./${gistPrefix}/sindri.json`)
const files = [
new File([circuit], 'circuit.circom'),
new File([sindriConf], 'sindri.json'),
new File([poseidon], 'node_modules/circomlib/circuits/poseidon.circom'),
new File([poseidonConstant], 'node_modules/circomlib/circuits/poseidon_constants.circom')
]
const circuitProject = await client.createCircuit(files)
console.log(circuitProject)
if (circuitProject.error) {
console.error(circuitProject.error)
}
} catch (e) {
console.error(e.message)
}
}
run()
import { poseidon } from "circomlibjs" // v0.0.8
// eslint-disable-next-line @typescript-eslint/no-var-requires
const snarkjs = require('snarkjs');
const logger = {
info: (...args) => console.log(...args),
debug: (...args) => console.log(...args),
error: (...args) => console.error(...args),
};
(async () => {
try {
// @ts-ignore
const r1csBuffer = await remix.call('fileManager', 'readFile', 'circuits/.bin/calculate_hash.r1cs', true);
// @ts-ignore
const r1cs = new Uint8Array(r1csBuffer);
// @ts-ignore
const wasmBuffer = await remix.call('fileManager', 'readFile', 'circuits/.bin/calculate_hash.wasm', true);
// @ts-ignore
const wasm = new Uint8Array(wasmBuffer);
const zkey_final = {
type: "mem",
data: new Uint8Array(JSON.parse(await remix.call('fileManager', 'readFile', './zk/build/zk_setup.txt')))
}
const wtns = { type: "mem" };
const vKey = JSON.parse(await remix.call('fileManager', 'readFile', './zk/build/verification_key.json'))
const value1 = '1234'
const value2 = '2'
const value3 = '3'
const value4 = '4'
const wrongValue = '5' // put this in the poseidon hash calculation to simulate a non matching hash.
const signals = {
value1,
value2,
value3,
value4,
hash: poseidon([value1, value2, value3, value4])
}
console.log('calculate')
await snarkjs.wtns.calculate(signals, wasm, wtns);
console.log('check')
await snarkjs.wtns.check(r1cs, wtns, logger);
console.log('prove')
const { proof, publicSignals } = await snarkjs.groth16.prove(zkey_final, wtns);
const verified = await snarkjs.groth16.verify(vKey, publicSignals, proof, logger);
console.log('zk proof validity', verified);
} catch (e) {
console.error(e.message)
}
})()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment