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