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