arnaucube
arnaucube/miksi-corePublic Self-hosted repository
miksi-core/src/miksi.ts
src/miksi.tsRaw
  1const fs = require("fs");
  2const bigInt = require("big-integer");
  3const { groth } = require('snarkjs');
  4const { Fr } = require('ffjavascript').bn128;
  5const { stringifyBigInts, unstringifyBigInts } = require('ffjavascript').utils;
  6const WitnessCalculatorBuilder = require("circom_runtime").WitnessCalculatorBuilder;
  7const circomlib = require("circomlib");
  8const smt = require("circomlib").smt;
  9const Web3 = require("web3");
 10// const buildBn128 = require("wasmsnark").buildBn128;
 11
 12
 13const coinCode = "0"; // refearing to ETH
 14const ethAmount = '1';
 15const amount = Web3.utils.toWei(ethAmount, 'ether');
 16
 17exports.randBigInt = () => {
 18	return Fr.random();
 19};
 20
 21exports.calcCommitment = (key, secret) => {
 22	const poseidon = circomlib.poseidon.createHash(6, 8, 57);
 23    	const nullifier = poseidon([key, secret]).toString();
 24	const commitment = poseidon([coinCode, amount, secret, nullifier]).toString();
 25	return commitment;
 26};
 27
 28exports.calcDepositWitness = async (wasm, nLevels, key, secret, commitments) => {
 29	const poseidon = circomlib.poseidon.createHash(6, 8, 57);
 30    	const nullifier = poseidon([key, secret]).toString();
 31	const commitment = poseidon([coinCode, amount, secret, nullifier]).toString();
 32
 33	console.log("Commitment", commitment.toString());
 34
 35	// rebuild the tree
 36	let tree = await smt.newMemEmptyTrie();
 37	await tree.insert(0, 0);
 38	for (let i=0; i <commitments.length; i++) {
 39		await tree.insert(i+1, commitments[i]);
 40	}
 41
 42	let res = await tree.insert(key, commitment);
 43
 44	// new root
 45	let siblings = res.siblings;
 46	console.log(res);
 47	// while (siblings.length < nLevels) {
 48	//         siblings.push("0");
 49	// };
 50
 51	// calculate witness
 52	const input = unstringifyBigInts({
 53		"coinCode": coinCode,
 54		"amount": amount,
 55		"secret": secret,
 56		"oldKey": res.isOld0 ? 0 : res.oldKey,
 57		"oldValue": res.isOld0 ? 0 : res.oldValue,
 58		"isOld0": res.isOld0 ? 1 : 0,
 59		"siblings": siblings,
 60		"rootOld": res.oldRoot,
 61		"rootNew": res.newRoot,
 62		"commitment": commitment,
 63		"key": key
 64	});
 65	console.log("input", input);
 66	// const options = {};
 67	// const wc = await WitnessCalculatorBuilder(wasm, options);
 68
 69	const wc = await WitnessCalculatorBuilder(wasm);
 70
 71	const witness = await wc.calculateWitness(input, {sanityCheck: true});
 72
 73	const wBuff = Buffer.allocUnsafe(witness.length*32);
 74
 75	for (let i=0; i <witness.length; i++) {
 76		for (let j=0; j <8; j++) {
 77			const bi = witness[i];
 78			const v = bigInt(bi).shiftRight(j*32).and(0xFFFFFFFF).toJSNumber();
 79			// wBuff.writeUInt32LE(v, i*32 + j*4, 4)
 80			wBuff.writeUInt32LE(v, i*32 + j*4)
 81		}
 82	}
 83
 84
 85	// const witness = unstringifyBigInts(stringifyBigInts(w));
 86	// return wBuff;
 87	return {
 88		witness: wBuff,
 89		publicInputs: {
 90			commitment:commitment,
 91			root:res.newRoot
 92		}
 93	};
 94}
 95
 96exports.calcWithdrawWitness = async (wasm, nLevels, key, secret, commitments, addr) => {
 97	const poseidon = circomlib.poseidon.createHash(6, 8, 57);
 98    	const nullifier = poseidon([key, secret]).toString();
 99	const commitment = poseidon([coinCode, amount, secret, nullifier]).toString();
100
101	// rebuild the tree
102	let tree = await smt.newMemEmptyTrie();
103	await tree.insert(0, 0);
104	for (let i=0; i <commitments.length; i++) {
105		await tree.insert(i+1, commitments[i]);
106	}
107	// await tree.insert(commitment, 0);
108
109	// root
110	const root = tree.root;
111	const res = await tree.find(key);
112	if (!res.found) {
113		console.error("leaf expect to exist but not exists, key:", key);
114	}
115	let siblings = res.siblings;
116	while (siblings.length < nLevels) {
117		siblings.push("0");
118	};
119
120	// calculate witness
121	const input = unstringifyBigInts({
122		"coinCode": coinCode,
123		"amount": amount,
124		"secret": secret,
125		"nullifier": nullifier,
126		"siblings": siblings,
127		"root": root,
128		"address": addr,
129		"key": key
130	});
131	console.log("input", input);
132	// const options = {};
133	// const wc = await WitnessCalculatorBuilder(wasm, options);
134
135	const wc = await WitnessCalculatorBuilder(wasm);
136
137	const witness = await wc.calculateWitness(input, {sanityCheck: true});
138
139	const wBuff = Buffer.allocUnsafe(witness.length*32);
140
141	for (let i=0; i <witness.length; i++) {
142		for (let j=0; j <8; j++) {
143			const bi = witness[i];
144			const v = bigInt(bi).shiftRight(j*32).and(0xFFFFFFFF).toJSNumber();
145			// wBuff.writeUInt32LE(v, i*32 + j*4, 4)
146			wBuff.writeUInt32LE(v, i*32 + j*4)
147		}
148	}
149
150
151	// const witness = unstringifyBigInts(stringifyBigInts(w));
152	return {
153		witness: wBuff,
154		publicInputs: {
155			address:addr,
156			nullifier:nullifier
157		}
158	};
159}