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