Modify script

pull/4430/head^2
ioedeveloper 11 months ago committed by Aniket
parent 8b7853b97a
commit a2c70d632a
  1. 4
      apps/remix-ide/src/app/editor/editor.js
  2. 20
      libs/remix-ws-templates/src/templates/ecdsa/scripts/run_setup.ts
  3. 136
      libs/remix-ws-templates/src/templates/ecdsa/scripts/run_verification.ts

@ -208,8 +208,8 @@ class Editor extends Plugin {
const paths = path.split('/')
paths.pop()
const fromPath = paths.join('/') // get current execution context path
for (const match of content.matchAll(/import\s+.*\s+from\s+(?:"(.*?)"|'(.*?)')/g)) {
let pathDep = match[2]
for (const match of content.matchAll(/import\s+(?:(?:\{[^{}]*\}|[^'";]+)\s+from\s+)?['"](@[\w-]+\/[\w-]+)['"];?/g)) {
let pathDep = match[1]
if (pathDep.startsWith('./') || pathDep.startsWith('../')) pathDep = resolve(fromPath, pathDep)
if (pathDep.startsWith('/')) pathDep = pathDep.substring(1)
if (!pathDep.endsWith('.ts')) pathDep = pathDep + '.ts'

@ -3,30 +3,14 @@ import { ethers, BigNumber } from 'ethers'
// 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)
};
/**
* Creates a keccak256 hash of a message compatible with the SNARK scalar modulus.
* @param message The message to be hashed.
* @returns The message digest.
*/
function hash(message: any): bigint {
message = BigNumber.from(message).toTwos(256).toHexString()
message = ethers.utils.zeroPad(message, 32)
return BigInt(ethers.utils.keccak256(message)) >> BigInt(8)
}
(async () => {
try {
// @ts-ignore
await remix.call('circuit-compiler', 'generateR1cs', 'circuits/semaphore.circom');
await remix.call('circuit-compiler', 'generateR1cs', 'circuits/instances/pubkey_membership.circom');
const ptau_final = "https://ipfs-cluster.ethdevops.io/ipfs/QmTiT4eiYz5KF7gQrDsgfCSTRv3wBPYJ4bRN1MmTRshpnW";
// @ts-ignore
const r1csBuffer = await remix.call('fileManager', 'readFile', 'circuits/.bin/semaphore.r1cs', true);
const r1csBuffer = await remix.call('fileManager', 'readFile', 'circuits/instances/.bin/pubkey_membership.r1cs', true);
// @ts-ignore
const r1cs = new Uint8Array(r1csBuffer);
const zkey_0 = { type: "mem" };

@ -1,6 +1,7 @@
import { ethers, BigNumber } from 'ethers'
import { IncrementalMerkleTree } from "@zk-kit/incremental-merkle-tree"
import { poseidon } from "circomlibjs" // v0.0.8
// @ts-ignore
import { Poseidon, Tree, computeEffEcdsaPubInput } from "@personaelabs/spartan-ecdsa"
// @ts-ignore
import { privateToPublic, hashPersonalMessage, ecsign, utf8ToBytes, bytesToHex } from "@ethereumjs/util"
// eslint-disable-next-line @typescript-eslint/no-var-requires
const snarkjs = require('snarkjs');
@ -11,88 +12,107 @@ const logger = {
error: (...args) => console.error(...args),
}
/**
* Creates a keccak256 hash of a message compatible with the SNARK scalar modulus.
* @param message The message to be hashed.
* @returns The message digest.
*/
function hash(message: any): bigint {
message = BigNumber.from(message).toTwos(256).toHexString()
message = ethers.utils.zeroPad(message, 32)
return BigInt(ethers.utils.keccak256(message)) >> BigInt(8)
function getEffEcdsaCircuitInput (privKey, msg) {
const msgHash = hashPersonalMessage(msg)
const { v, r: _r, s } = ecsign(msgHash, privKey)
const r = BigInt('0x' + _r.map(byte => byte.toString(16).padStart(2, '0')).join(''))
const circuitPubInput = computeEffEcdsaPubInput(r, v, msgHash)
const input = {
s: BigInt('0x' + s.map(byte => byte.toString(16).padStart(2, '0')).join('')),
Tx: circuitPubInput.Tx,
Ty: circuitPubInput.Ty,
Ux: circuitPubInput.Ux,
Uy: circuitPubInput.Uy
}
return input
}
(async () => {
try {
// @ts-ignore
const r1csBuffer = await remix.call('fileManager', 'readFile', 'circuits/.bin/semaphore.r1cs', true);
const r1csBuffer = await remix.call('fileManager', 'readFile', 'circuits/instances/.bin/pubkey_membership.r1cs', true)
// @ts-ignore
const r1cs = new Uint8Array(r1csBuffer);
const r1cs = new Uint8Array(r1csBuffer)
// @ts-ignore
const wasmBuffer = await remix.call('fileManager', 'readFile', 'circuits/.bin/semaphore.wasm', true);
const wasmBuffer = await remix.call('fileManager', 'readFile', 'circuits/instances/.bin/pubkey_membership.wasm', true)
// @ts-ignore
const wasm = new Uint8Array(wasmBuffer);
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 wtns = { type: "mem" }
const vKey = JSON.parse(await remix.call('fileManager', 'readFile', './zk/build/verification_key.json'))
// build list of identity commitments
const secrets = []
const identityCommitments = []
for (let k = 0; k < 2; k++) {
const identityTrapdoor = BigInt(ethers.utils.hexlify(ethers.utils.randomBytes(32)))
const identityNullifier = BigInt(ethers.utils.hexlify(ethers.utils.randomBytes(32)))
secrets.push({identityTrapdoor, identityNullifier})
const secret = poseidon([identityNullifier, identityTrapdoor])
const identityCommitment = poseidon([secret])
identityCommitments.push(identityCommitment)
}
//console.log('incremental tree', identityCommitments.map((x) => x.toString()))
// Construct the tree
const poseidon = new Poseidon()
await poseidon.initWasm()
let tree
try {
tree = new IncrementalMerkleTree(poseidon, 20, BigInt(0), 2, identityCommitments) // Binary tree.
} catch (e) {
console.error(e.message)
return
const nLevels = 10
const tree = new Tree(nLevels, poseidon)
console.log('done')
const privKeys = [
utf8ToBytes("".padStart(16, "🧙")),
utf8ToBytes("".padStart(16, "🪄")),
utf8ToBytes("".padStart(16, "🔮"))
]
// Store public key hashes
const pubKeyHashes: bigint[] = []
// Compute public key hashes
for (const privKey of privKeys) {
const pubKey = privateToPublic(privKey)
const pubKeyHex = bytesToHex(pubKey)
const hexWithoutPrefix = pubKeyHex.startsWith('0x') ? pubKeyHex.slice(2) : pubKeyHex;
const pubKeyHash = poseidon.hashPubKey(hexWithoutPrefix)
pubKeyHashes.push(pubKeyHash)
}
// Insert the pubkey hashes into the tree
for (const pubKeyHash of pubKeyHashes) {
tree.insert(pubKeyHash)
}
const index = tree.indexOf(identityCommitments[0])
console.log(index.toString())
const proof1 = tree.createProof(0)
// Sign
const index = 0; // Use privKeys[0] for proving
const privKey = privKeys[index]
const msg = utf8ToBytes("hello world".padStart(16, " "))
// Prepare signature proof input
const effEcdsaInput = getEffEcdsaCircuitInput(privKey, msg)
const merkleProof = tree.createProof(index)
console.log('prepare signals for id ', identityCommitments[0].toString(), tree.indexOf(identityCommitments[0]), proof1.siblings.map((x)=> x.toString()))
const signals = {
identityTrapdoor: secrets[0].identityTrapdoor,
identityNullifier: secrets[0].identityNullifier,
treePathIndices: proof1.pathIndices,
treeSiblings: proof1.siblings,
externalNullifier: hash(42),
signalHash: hash(ethers.utils.formatBytes32String("Hello World"))
...effEcdsaInput,
siblings: merkleProof.siblings,
pathIndices: merkleProof.pathIndices,
root: tree.root()
}
console.log('signals: ', signals)
console.log('calculate')
await snarkjs.wtns.calculate(signals, wasm, wtns);
await snarkjs.wtns.calculate(signals, wasm, wtns)
console.log('check')
await snarkjs.wtns.check(r1cs, wtns, logger);
// console.log('check')
// await snarkjs.wtns.check(r1cs, wtns, logger)
console.log('prove')
const { proof, publicSignals } = await snarkjs.groth16.prove(zkey_final, wtns);
// 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);
proof1.root.toString() === publicSignals[0] ? console.log('merkle proof valid') : console.log('merkle proof invalid')
// const verified = await snarkjs.groth16.verify(vKey, publicSignals, proof, logger);
// console.log('zk proof validity', verified);
// proof1.root.toString() === publicSignals[0] ? console.log('merkle proof valid') : console.log('merkle proof invalid')

Loading…
Cancel
Save