Skip to content

Commit

Permalink
Merge branch 'master' into tabsed
Browse files Browse the repository at this point in the history
  • Loading branch information
LianaHus authored Nov 18, 2023
2 parents 390bb93 + be8f428 commit 2507a55
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 0 deletions.
2 changes: 2 additions & 0 deletions apps/remix-ide/src/app/plugins/openaigpt.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ export class OpenAIGpt extends Plugin {

if (result && result.choices && result.choices.length) {
this.call('terminal', 'log', { type: 'typewritersuccess', value: result.choices[0].message.content })
} else if (result.error) {
this.call('terminal', 'log', { type: 'typewritersuccess', value: result.error })
} else {
this.call('terminal', 'log', { type: 'typewritersuccess', value: 'No response...' })
}
Expand Down
2 changes: 2 additions & 0 deletions libs/remix-ws-templates/src/templates/rln/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ export default async () => {
// @ts-ignore
'scripts/run_setup.ts': (await import('!!raw-loader!./scripts/run_setup.ts')).default,
// @ts-ignore
'scripts/run_verification.ts': (await import('!!raw-loader!./scripts/run_verification.ts')).default,
// @ts-ignore
'templates/groth16_verifier.sol.ejs': (await import('!!raw-loader!./templates/groth16_verifier.sol.ejs')).default,
// @ts-ignore
'LICENSE-APACHE': (await import('!!raw-loader!./LICENSE-APACHE')).default,
Expand Down
141 changes: 141 additions & 0 deletions libs/remix-ws-templates/src/templates/rln/scripts/run_verification.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
import { ethers, BigNumber } from 'ethers'
import { IncrementalMerkleTree } from "@zk-kit/incremental-merkle-tree"
import { poseidon } from "circomlibjs" // v0.0.8

import { ZqField } from 'ffjavascript'
const SNARK_FIELD_SIZE = BigInt('21888242871839275222246405745257275088548364400416034343698204186575808495617')

// Creates the finite field
const Fq = new ZqField(SNARK_FIELD_SIZE)

// 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),
}

/**
* Recovers secret from two shares
* @param x1 signal hash of first message
* @param x2 signal hash of second message
* @param y1 yshare of first message
* @param y2 yshare of second message
* @returns identity secret
*/
function shamirRecovery(x1: bigint, x2: bigint, y1: bigint, y2: bigint): bigint {
const slope = Fq.div(Fq.sub(y2, y1), Fq.sub(x2, x1))
const privateKey = Fq.sub(y1, Fq.mul(slope, x1))

return Fq.normalize(privateKey)
}

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 hashNullifier(message: any): bigint {
return BigInt(ethers.utils.keccak256(message)) >> BigInt(8)
}

async function prove (signals, wasm, wtns, r1cs, zkey_final, vKey) {
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);
return {
proof,
x: publicSignals[3],
y: publicSignals[0]
}
}

(async () => {
try {
// @ts-ignore
const r1csBuffer = await remix.call('fileManager', 'readFile', 'circuits/.bin/rln.r1cs', true);
// @ts-ignore
const r1cs = new Uint8Array(r1csBuffer);
// @ts-ignore
const wasmBuffer = await remix.call('fileManager', 'readFile', 'circuits/.bin/rln.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'))

// build list of identity commitments
const secrets = []
const identityCommitments = []
const rateCommitments = []
const userMessageLimit = 0x2
for (let k = 0; k < 2; k++) {
const identitySecret = BigInt(ethers.utils.hexlify(ethers.utils.randomBytes(32)))
secrets.push(identitySecret)

const identityCommitment = poseidon([identitySecret])
const rateCommitment = poseidon([identityCommitment, userMessageLimit])
identityCommitments.push(identityCommitment)
rateCommitments.push(rateCommitment)
}

let tree

try {
tree = new IncrementalMerkleTree(poseidon, 20, BigInt(0), 2, rateCommitments) // Binary tree.
} catch (e) {
console.error(e.message)
return
}

const merkleproof1 = tree.createProof(0)

const appId = 0xa
const epoch = 0x1

const signals1 = {
identitySecret: secrets[0],
userMessageLimit,
messageId: 0x0,
pathElements: merkleproof1.siblings,
identityPathIndex: merkleproof1.pathIndices,
x: 0xabcd, // hash(message)
externalNullifier: 0xa // hash(epoch, appId)
}
const proof1 = await prove(signals1, wasm, wtns, r1cs, zkey_final, vKey)

const signals2 = {
identitySecret: secrets[0],
userMessageLimit,
messageId: 0x0,
pathElements: merkleproof1.siblings,
identityPathIndex: merkleproof1.pathIndices,
x: 0xabce, // hash(message)
externalNullifier: 0xa // hash(epoch, appId)
}
const proof2 = await prove(signals2, wasm, wtns, r1cs, zkey_final, vKey)

const secret = shamirRecovery(BigInt(proof1.x), BigInt(proof2.x), BigInt(proof1.y), BigInt(proof2.y))

console.log(secret.toString(10))
console.log(Fq.normalize(secrets[0]))
} catch (e) {
console.error(e.message)
}
})()

0 comments on commit 2507a55

Please sign in to comment.