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