zkjson 0.1.10 → 0.1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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.10",
3
+ "version": "0.1.11",
4
4
  "description": "Zero Knowledge Provable JSON",
5
5
  "main": "index.js",
6
6
  "license": "MIT",
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
+ }