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}