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