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