zkjson 0.1.9 → 0.1.11

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,7 +2,6 @@
2
2
 
3
3
  pragma solidity >=0.7.0 <0.9.0;
4
4
  import "hardhat/console.sol";
5
- import "./ZKJson.sol";
6
5
  import "./ZKQuery.sol";
7
6
 
8
7
  interface VerifierRU {
@@ -12,7 +11,7 @@ interface VerifierRU {
12
11
 
13
12
  contract ZKRollup is ZKQuery {
14
13
  address public verifierRU;
15
- address public comitter;
14
+ address public committer;
16
15
  uint public root;
17
16
 
18
17
  function _verifyRU(uint[] calldata zkp) internal view returns (bool) {
@@ -29,29 +28,27 @@ contract ZKRollup is ZKQuery {
29
28
  return true;
30
29
  }
31
30
 
32
- function _validateQueryRU(uint[] memory path, uint[] calldata zkp, uint size) internal view returns(uint[] memory){
31
+ function _validateQueryRU(uint[] memory path, uint[] calldata zkp, uint size_path, uint size_val) internal view returns(uint[] memory){
33
32
  require(zkp[19] == root, "root mismatch");
34
- require(zkp[size * 2 + 10] == path[0], "wrong collection");
35
- require(zkp[size * 2 + 11] == path[1], "wrong doc");
33
+ require(zkp[size_path + size_val + 10] == path[0], "wrong collection");
34
+ require(zkp[size_path + size_val + 11] == path[1], "wrong doc");
36
35
  require(zkp[8] == 1, "value doesn't exist");
37
- require(path.length <= size + 2, "path too long");
36
+ require(path.length <= size_path + size_val, "path too long");
38
37
  for(uint i = 9; i < 9 + path.length - 2; i++) require(path[i - 7] == zkp[i], "wrong path");
39
- uint[] memory value = new uint[](size);
40
- for(uint i = 9 + size; i < 9 + size * 2; i++) value[i - (9 + size)] = zkp[i];
38
+ uint[] memory value = new uint[](size_val);
39
+ for(uint i = 9 + size_path; i < 9 + size_path + size_val; i++) value[i - (9 + size_path)] = zkp[i];
41
40
  return toArr(value);
42
41
  }
43
42
 
44
43
  function commit (uint[] calldata zkp) public returns (uint) {
45
44
  require (zkp[9] == root, "wrong merkle root");
46
- require(msg.sender == comitter, "sender is not comitter");
45
+ require(msg.sender == committer, "sender is not committer");
47
46
  root = zkp[8];
48
47
  verifyRU(zkp);
49
48
  return root;
50
-
51
49
  }
52
50
 
53
51
  function verifyRU(uint[] calldata zkp) public view returns (bool) {
54
52
  return _verifyRU(zkp);
55
53
  }
56
-
57
54
  }
package/db.js CHANGED
@@ -1,4 +1,5 @@
1
1
  const newMemEmptyTrie = require("./circomlibjs").newMemEmptyTrie
2
+ const snarkjs = require("snarkjs")
2
3
  const { range } = require("ramda")
3
4
  const {
4
5
  pad,
@@ -7,7 +8,7 @@ const {
7
8
  val2str,
8
9
  id2str,
9
10
  encode,
10
- str2id,
11
+ toIndex,
11
12
  } = require("./encoder")
12
13
  const Collection = require("./collection")
13
14
 
@@ -19,7 +20,15 @@ class DB {
19
20
  size_json = 256,
20
21
  size_txs = 10,
21
22
  level_col = 8,
23
+ wasm,
24
+ zkey,
25
+ wasmRU,
26
+ zkeyRU,
22
27
  }) {
28
+ this.wasm = wasm
29
+ this.zkey = zkey
30
+ this.wasmRU = wasmRU
31
+ this.zkeyRU = zkeyRU
23
32
  this.level_col = level_col
24
33
  this.size = size_val
25
34
  this.size_path = size_path
@@ -47,7 +56,63 @@ class DB {
47
56
  siblings = siblings.map(s => s.toString())
48
57
  return { isOld0, oldRoot, oldKey, oldValue, siblings, newRoot }
49
58
  }
59
+ _getVal(j, p) {
60
+ if (p.length === 0) {
61
+ return j
62
+ } else {
63
+ const sp = p[0].split("[")
64
+ for (let v of sp) {
65
+ if (/]$/.test(v)) {
66
+ j = j[v.replace(/]$/, "") * 1]
67
+ } else {
68
+ j = j[v]
69
+ }
70
+ }
71
+ return this._getVal(j, p.slice(1))
72
+ }
73
+ }
74
+ getVal(j, p) {
75
+ if (p === "") return j
76
+ return this._getVal(j, p.split("."))
77
+ }
50
78
 
79
+ async genProof({ json, col_id, path, id }) {
80
+ const inputs = await this.getInputs({
81
+ id,
82
+ col_id,
83
+ json,
84
+ path,
85
+ val: this.getVal(json, path),
86
+ })
87
+ const { proof, publicSignals } = await snarkjs.groth16.fullProve(
88
+ inputs,
89
+ this.wasm,
90
+ this.zkey
91
+ )
92
+ return [
93
+ ...proof.pi_a.slice(0, 2),
94
+ ...proof.pi_b[0].slice(0, 2).reverse(),
95
+ ...proof.pi_b[1].slice(0, 2).reverse(),
96
+ ...proof.pi_c.slice(0, 2),
97
+ ...publicSignals,
98
+ ]
99
+ }
100
+
101
+ async genRollupProof(txs) {
102
+ const inputs = await this.getRollupInputs({ queries: txs })
103
+ const { proof, publicSignals } = await snarkjs.groth16.fullProve(
104
+ inputs,
105
+ this.wasmRU,
106
+ this.zkeyRU
107
+ )
108
+ return [
109
+ ...proof.pi_a.slice(0, 2),
110
+ ...proof.pi_b[0].slice(0, 2).reverse(),
111
+ ...proof.pi_b[1].slice(0, 2).reverse(),
112
+ ...proof.pi_c.slice(0, 2),
113
+ ...publicSignals,
114
+ ]
115
+ }
51
116
  async getRollupInputs({ queries }) {
52
117
  let write, _json
53
118
  let oldRoot = []
@@ -79,6 +144,7 @@ class DB {
79
144
  siblings.push(range(0, this.level).map(() => "0"))
80
145
  isOld0.push("0")
81
146
  oldRoot_db.push(newRoot_db[i - 1])
147
+ newRoot_db.push(newRoot_db[i - 1])
82
148
  oldKey_db.push("0")
83
149
  oldValue_db.push("0")
84
150
  siblings_db.push(range(0, this.level_col).map(() => "0"))
@@ -92,9 +158,9 @@ class DB {
92
158
  const icol = this.parse(res, tree, this.level)
93
159
  const idb = this.parse(res2, this.tree, this.level_col)
94
160
  _res = idb
95
- const _newKey = str2id(v[1])
161
+ const _newKey = toIndex(v[1])
96
162
  json.push(pad(val2str(encode(_json)), this.size_json))
97
- const _newKey_db = v[0]
163
+ const _newKey_db = v[0].toString()
98
164
  fnc.push(update ? [0, 1] : [1, 0])
99
165
  newRoot.push(idb.newRoot)
100
166
  oldRoot.push(icol.oldRoot)
@@ -140,8 +206,8 @@ class DB {
140
206
  } = await this.insert(col_id, id, json)
141
207
  const icol = this.parse(res, tree, this.level)
142
208
  const idb = this.parse(res2, this.tree, this.level_col)
143
- const newKey = str2id(id)
144
- const newKey_db = col_id
209
+ const newKey = toIndex(id)
210
+ const newKey_db = col_id.toString()
145
211
  return {
146
212
  fnc: update ? [0, 1] : [1, 0],
147
213
  oldRoot: icol.oldRoot,
@@ -179,7 +245,7 @@ class DB {
179
245
  json: col_inputs.json,
180
246
  root: col_inputs.root,
181
247
  siblings: col_inputs.siblings,
182
- key: str2id(id),
248
+ key: toIndex(id),
183
249
  col_key,
184
250
  col_siblings,
185
251
  col_root,
@@ -244,7 +310,7 @@ class DB {
244
310
  return await _col.get(_key)
245
311
  }
246
312
  async getCol(_key) {
247
- const id = str2id(_key)
313
+ const id = toIndex(_key)
248
314
  return await this.tree.find(id)
249
315
  }
250
316
  }
package/encoder.js CHANGED
@@ -453,6 +453,9 @@ const fromSignal = str2val
453
453
  const toIndex = str2id
454
454
  const fromIndex = id2str
455
455
 
456
+ const path = p => toSignal(encodePath(p))
457
+ const val = v => toSignal(encodeVal(v))
458
+
456
459
  module.exports = {
457
460
  encode,
458
461
  decode,
@@ -471,4 +474,6 @@ module.exports = {
471
474
  fromSignal,
472
475
  toIndex,
473
476
  fromIndex,
477
+ path,
478
+ val,
474
479
  }
package/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  const encoder = require("./encoder")
2
2
  const DB = require("./db")
3
3
  const Doc = require("./doc")
4
+ const Rollup = require("./rollup")
4
5
  const Collection = require("./collection")
5
6
 
6
- module.exports = { ...encoder, DB, Collection, Doc }
7
+ module.exports = { ...encoder, DB, Collection, Doc, Rollup }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zkjson",
3
- "version": "0.1.9",
3
+ "version": "0.1.11",
4
4
  "description": "Zero Knowledge Provable JSON",
5
5
  "main": "index.js",
6
6
  "license": "MIT",
@@ -9,6 +9,7 @@
9
9
  "blake2b": "^2.1.3",
10
10
  "ethers": "^5.5.1",
11
11
  "ffjavascript": "^0.2.45",
12
- "ramda": "^0.29.1"
12
+ "ramda": "^0.29.1",
13
+ "snarkjs": "^0.7.3"
13
14
  }
14
15
  }
package/rollup.js ADDED
@@ -0,0 +1,224 @@
1
+ const snarkjs = require("snarkjs")
2
+ const { resolve } = require("path")
3
+ const { pad, toSignal, encode, encodePath, encodeVal } = require("./encoder")
4
+ const DB = require("./db")
5
+ const { range } = require("ramda")
6
+
7
+ module.exports = class Rollup {
8
+ constructor({
9
+ size_val = 5,
10
+ size_path = 5,
11
+ size_json = 256,
12
+ level = 100,
13
+ size_txs = 10,
14
+ level_col = 8,
15
+ wasm,
16
+ zkey,
17
+ }) {
18
+ this.size_val = size_val
19
+ this.size_path = size_path
20
+ this.size_json = size_json
21
+ this.size_txs = size_txs
22
+ this.level = level
23
+ this.level_col = level_col
24
+ this.wasm = wasm
25
+ this.zkey = zkey
26
+ }
27
+ async init() {
28
+ this.db = new DB({
29
+ level: this.level,
30
+ size_path: this.size_path,
31
+ size_val: this.size_val,
32
+ size_json: this.size_json,
33
+ size_txs: this.size_txs,
34
+ level_col: this.level_col,
35
+ })
36
+ await this.db.init()
37
+ }
38
+ async getInputs(queries) {
39
+ let write, _json
40
+ let oldRoot = []
41
+ let newRoot = []
42
+ let oldKey = []
43
+ let oldValue = []
44
+ let siblings = []
45
+ let isOld0 = []
46
+ let oldRoot_db = []
47
+ let newRoot_db = []
48
+ let oldKey_db = []
49
+ let oldValue_db = []
50
+ let siblings_db = []
51
+ let isOld0_db = []
52
+ let newKey_db = []
53
+ let newKey = []
54
+ let _res
55
+ let json = []
56
+ let fnc = []
57
+ for (let i = 0; i < this.size_txs; i++) {
58
+ const v = queries[i]
59
+ if (!v) {
60
+ json.push(range(0, this.size_json).map(() => "0"))
61
+ fnc.push([0, 0])
62
+ newRoot.push(newRoot[i - 1])
63
+ oldRoot.push("0")
64
+ oldKey.push("0")
65
+ oldValue.push("0")
66
+ siblings.push(range(0, this.level).map(() => "0"))
67
+ isOld0.push("0")
68
+ oldRoot_db.push(newRoot_db[i - 1])
69
+ oldKey_db.push("0")
70
+ oldValue_db.push("0")
71
+ siblings_db.push(range(0, this.level_col).map(() => "0"))
72
+ isOld0_db.push("0")
73
+ newKey_db.push("0")
74
+ newKey.push("0")
75
+ continue
76
+ }
77
+ _json = v[2]
78
+ const { update, tree, col: res2, doc: res } = await this.insert(...v)
79
+ const icol = this.parse(res, tree, this.level)
80
+ const idb = this.parse(res2, this.tree, this.level_col)
81
+ _res = idb
82
+ const _newKey = str2id(v[1])
83
+ json.push(pad(val2str(encode(_json)), this.size_json))
84
+ const _newKey_db = v[0]
85
+ fnc.push(update ? [0, 1] : [1, 0])
86
+ newRoot.push(idb.newRoot)
87
+ oldRoot.push(icol.oldRoot)
88
+ oldKey.push(icol.oldKey)
89
+ oldValue.push(icol.oldValue)
90
+ siblings.push(icol.siblings)
91
+ isOld0.push(icol.isOld0)
92
+ oldRoot_db.push(idb.oldRoot)
93
+ newRoot_db.push(idb.newRoot)
94
+ oldKey_db.push(idb.oldKey)
95
+ oldValue_db.push(idb.oldValue)
96
+ siblings_db.push(idb.siblings)
97
+ isOld0_db.push(idb.isOld0)
98
+ newKey_db.push(_newKey_db)
99
+ newKey.push(_newKey)
100
+ }
101
+
102
+ return {
103
+ fnc,
104
+ oldRoot,
105
+ newRoot,
106
+ oldKey,
107
+ oldValue,
108
+ siblings,
109
+ isOld0,
110
+ oldRoot_db,
111
+ oldKey_db,
112
+ oldValue_db,
113
+ siblings_db,
114
+ isOld0_db,
115
+ newKey_db,
116
+ newKey,
117
+ json,
118
+ }
119
+ }
120
+ async genProof(queries) {
121
+ const inputs = await this.getInputs(queries)
122
+ console.log(inputs)
123
+ return 3
124
+ }
125
+ async genProof2(col, doc, tar, path) {
126
+ const val = this.getVal(tar, path)
127
+
128
+ const col_root = this.db.tree.F.toObject(this.db.tree.root).toString()
129
+ const col_res = await this.db.getCol(doc)
130
+
131
+ let col_siblings = col_res.siblings
132
+ for (let i = 0; i < col_siblings.length; i++)
133
+ col_siblings[i] = this.db.tree.F.toObject(col_siblings[i])
134
+ while (col_siblings.length < this.level_col) col_siblings.push(0)
135
+ col_siblings = col_siblings.map(s => s.toString())
136
+ const col_key = col
137
+
138
+ const _col = this.db.getColTree(col)
139
+ const root = _col.tree.F.toObject(_col.tree.root).toString()
140
+ const res = await _col.get(doc)
141
+ let _siblings = res.siblings
142
+ for (let i = 0; i < _siblings.length; i++)
143
+ _siblings[i] = _col.tree.F.toObject(_siblings[i])
144
+ while (_siblings.length < this.level) _siblings.push(0)
145
+ _siblings = _siblings.map(s => s.toString())
146
+ const key = toIndex(doc)
147
+
148
+ const _json = pad(toSignal(encode(tar)), this.size_json)
149
+ const _path = pad(toSignal(encodePath(path)), this.size_path)
150
+ const _val = pad(toSignal(encodeVal(val)), this.size)
151
+ const _write = {
152
+ json: _json,
153
+ path: _path,
154
+ val: _val,
155
+ root,
156
+ siblings: _siblings,
157
+ key,
158
+ col_key,
159
+ col_siblings,
160
+ col_root,
161
+ }
162
+ const { proof: proof2, publicSignals: sigs } =
163
+ await snarkjs.groth16.fullProve(
164
+ _write,
165
+ resolve(
166
+ __dirname,
167
+ "../../circom/build/circuits/db/index_js/index.wasm"
168
+ ),
169
+ resolve(__dirname, "../../circom/build/circuits/db/index_0001.zkey")
170
+ )
171
+ return [
172
+ ...proof2.pi_a.slice(0, 2),
173
+ ...proof2.pi_b[0].slice(0, 2).reverse(),
174
+ ...proof2.pi_b[1].slice(0, 2).reverse(),
175
+ ...proof2.pi_c.slice(0, 2),
176
+ ...sigs,
177
+ ]
178
+ }
179
+
180
+ async getInputs2({ json, path }) {
181
+ return {
182
+ json: pad(toSignal(encode(json)), this.size_json),
183
+ path: pad(toSignal(encodePath(path)), this.size_path),
184
+ val: pad(toSignal(encodeVal(this.getVal(json, path))), this.size_val),
185
+ }
186
+ }
187
+
188
+ _getVal(j, p) {
189
+ if (p.length === 0) {
190
+ return j
191
+ } else {
192
+ const sp = p[0].split("[")
193
+ for (let v of sp) {
194
+ if (/]$/.test(v)) {
195
+ j = j[v.replace(/]$/, "") * 1]
196
+ } else {
197
+ j = j[v]
198
+ }
199
+ }
200
+ return this._getVal(j, p.slice(1))
201
+ }
202
+ }
203
+
204
+ getVal(j, p) {
205
+ if (p === "") return j
206
+ return this._getVal(j, p.split("."))
207
+ }
208
+
209
+ async genProof2(json, path) {
210
+ const inputs = await this.getInputs(json, path)
211
+ const { proof, publicSignals } = await snarkjs.groth16.fullProve(
212
+ inputs,
213
+ this.wasm,
214
+ this.zkey
215
+ )
216
+ return [
217
+ ...proof.pi_a.slice(0, 2),
218
+ ...proof.pi_b[0].slice(0, 2).reverse(),
219
+ ...proof.pi_b[1].slice(0, 2).reverse(),
220
+ ...proof.pi_c.slice(0, 2),
221
+ ...publicSignals,
222
+ ]
223
+ }
224
+ }