zkjson 0.1.14 → 0.1.15

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.
@@ -6,7 +6,7 @@ import "./ZKQuery.sol";
6
6
  contract ZKJson is ZKQuery{
7
7
  address public verifierJSON;
8
8
 
9
- function _validateQueryJSON(uint[] memory path, uint[] calldata zkp, uint size_path, uint size_val) internal pure returns(uint[] memory){
9
+ function _validateQueryJSON(uint[] memory path, uint[] memory zkp, uint size_path, uint size_val) internal pure returns(uint[] memory){
10
10
  require(zkp[8] == 1, "value doesn't exist");
11
11
  for(uint i = 10; i < 10 + size_path; i++){
12
12
  require((path.length <= i - 10 && zkp[i] == 0) || path[i - 10] == zkp[i], "wrong path");
@@ -1,260 +1,161 @@
1
1
  // SPDX-License-Identifier: MIT
2
2
 
3
3
  pragma solidity >=0.7.0 <0.9.0;
4
- import "hardhat/console.sol";
5
4
 
6
5
  contract ZKQuery {
7
6
 
8
- function digits (uint x) private pure returns(uint) {
9
- uint p = 0;
10
- while(x > 0){
11
- x /= 10;
12
- p++;
7
+ function getPath(uint i, uint[] memory _json) private pure returns(uint[] memory, uint){
8
+ uint[] memory _path;
9
+ assembly {
10
+ let json := add(_json, 0x20)
11
+ let len := mload(add(json, mul(i, 0x20)))
12
+ i := add(i, 1)
13
+ _path := msize()
14
+ mstore(_path, sub(mload(_json), i))
15
+ let _path0 := add(_path, 0x20)
16
+ mstore(_path0, len)
17
+ let pi := 0x20
18
+ for { let i2 := 0 } lt(i2, len) { i2 := add(i2, 1) } {
19
+ let plen := mload(add(json, mul(i, 0x20)))
20
+ mstore(add(_path0, pi), plen)
21
+ pi := add(pi, 0x20)
22
+ i := add(i, 1)
23
+ let plen2 := 1
24
+ if iszero(plen) {
25
+ if iszero(mload(add(json, mul(i, 0x20)))){
26
+ plen2 := 2
27
+ }
28
+ }
29
+ for { let i3 := 0 } lt(i3, plen2) { i3 := add(i3, 1) } {
30
+ mstore(add(_path0, pi), mload(add(json, mul(i, 0x20))))
31
+ pi := add(pi, 0x20)
32
+ i := add(i, 1)
33
+ }
34
+ }
35
+ mstore(_path, div(pi, 0x20))
36
+ mstore(0x40, add(_path, add(0x20, pi)))
13
37
  }
14
- return p;
38
+ return (_path, i);
15
39
  }
16
40
 
17
- function getValLen(uint[] memory path, uint[] memory _json) private pure returns(uint, uint){
18
- require (_json[0] == 4, "not raw value");
19
- uint i = 1;
20
- uint start;
21
- uint[] memory path2 = toArr(path);
22
- uint vallen;
23
- while(i < _json.length){
24
- start = i;
25
- uint pathlen = getPathLen(i, _json);
26
- uint[] memory _path = new uint[](pathlen);
27
- uint len = _json[i];
28
- i++;
29
- _path[0] = len;
30
- uint pi = 1;
31
- for(uint i2=0;i2 < len; i2++){
32
- uint plen = _json[i];
33
- _path[pi] = plen;
34
- pi++;
35
- i++;
36
- uint plen2 = plen;
37
- if(plen == 0){
38
- plen2 = _json[i] == 0 ? 2 : 1;
39
- }
40
- for(uint i3 = 0; i3 < plen2; i3++){
41
- _path[pi] = _json[i];
42
- pi++;
43
- i++;
44
- }
41
+ function _getVal(uint i, uint[] memory _json) private pure returns(uint[] memory, uint){
42
+ uint[] memory _val;
43
+ assembly {
44
+ let json := add(_json, 0x20)
45
+ _val := msize()
46
+ mstore(_val, sub(mload(_json), i))
47
+ let _val0 := add(_val, 0x20)
48
+ let _type := mload(add(json, mul(i, 0x20)))
49
+ i := add(i, 1)
50
+ let vlen := 0x20
51
+ mstore(_val0, _type)
52
+ let len := 0
53
+ if eq(_type, 1) {
54
+ len := 1
45
55
  }
46
- uint _type = _json[i];
47
- i++;
48
- uint vlen = 1;
49
- if(_type == 1){
50
- vlen++;
51
- i++;
52
- }else if (_type == 2){
53
- vlen += 3;
54
- i += 3;
55
- }else if(_type == 3){
56
- uint slen = _json[i];
57
- vlen += slen + 1;
58
- i += slen + 1;
56
+ if eq(_type, 2) {
57
+ len := 3
59
58
  }
60
- uint path_match = 1;
61
- if(pathlen != path2.length){
62
- path_match = 0;
63
- }else{
64
- for(uint i4 = 0; i4 < path2.length; i4++){
65
- if(_path[i4] != path2[i4]) path_match = 0;
66
- }
59
+ if eq(_type, 3) {
60
+ len := add(mload(add(json, mul(i, 0x20))), 1)
67
61
  }
68
- if(path_match == 1){
69
- vallen = vlen;
70
- break;
62
+ for { let i2 := 0 } lt(i2, len) { i2 := add(i2, 1) } {
63
+ mstore(add(_val0, vlen), mload(add(json, mul(i, 0x20))))
64
+ vlen := add(vlen, 0x20)
65
+ i := add(i, 1)
71
66
  }
67
+ mstore(_val, div(vlen, 0x20))
68
+ mstore(0x40, add(_val, add(0x20, vlen)))
72
69
  }
73
- return (vallen, start);
74
- }
75
-
76
- function getPathLen(uint i, uint[] memory _json) private pure returns(uint){
77
- uint len = _json[i];
78
- i++;
79
- uint pi = 1;
80
- for(uint i2=0;i2 < len; i2++){
81
- uint plen = _json[i];
82
- pi++;
83
- i++;
84
- uint plen2 = plen;
85
- if(plen == 0) plen2 = _json[i] == 0 ? 2 : 1;
86
- pi += plen2;
87
- i += plen2;
88
- }
89
- return pi;
70
+ return (_val, i);
90
71
  }
91
72
 
92
73
  function getVal(uint[] memory path, uint[] memory _json) private pure returns(uint[] memory){
93
74
  require (_json[0] == 4, "not raw value");
94
- (uint vallen, uint i) = getValLen(path, _json);
95
- uint[] memory val = new uint[](vallen);
96
75
  uint[] memory path2 = toArr(path);
76
+ uint i = 1;
97
77
  while(i < _json.length){
98
- uint pathlen = getPathLen(i, _json);
99
- uint[] memory _path = new uint[](pathlen);
100
- uint len = _json[i];
101
- i++;
102
- _path[0] = len;
103
- uint pi = 1;
104
- for(uint i2=0;i2 < len; i2++){
105
- uint plen = _json[i];
106
- _path[pi] = plen;
107
- pi++;
108
- i++;
109
- uint plen2 = plen;
110
- if(plen == 0){
111
- plen2 = _json[i] == 0 ? 2 : 1;
112
- }
113
- for(uint i3 = 0; i3 < plen2; i3++){
114
- _path[pi] = _json[i];
115
- pi++;
116
- i++;
117
- }
118
- }
119
-
120
- uint _type = _json[i];
121
- i++;
122
- uint[] memory _val = new uint[](vallen);
123
- _val[0] = _type;
124
- if(_type == 1){
125
- _val[1] = _json[i];
126
- i++;
127
- }else if (_type == 2){
128
- _val[1] = _json[i];
129
- i++;
130
- _val[2] = _json[i];
131
- i++;
132
- _val[3] = _json[i];
133
- i++;
134
- }else if(_type == 3){
135
- uint slen = _json[i];
136
- _val[1] = slen;
137
- i++;
138
- for(uint i3 = 0;i3 < slen; i3++){
139
- _val[i3 + 2] = _json[i];
140
- i++;
141
- }
142
- }
78
+ (uint[] memory _path, uint i2) = getPath(i, _json);
79
+ (uint[] memory _val2, uint i3) = _getVal(i2, _json);
80
+ i = i3;
143
81
  uint path_match = 1;
144
- if(pathlen != path2.length){
82
+ if(_path.length != path2.length){
145
83
  path_match = 0;
146
84
  }else{
147
85
  for(uint i4 = 0; i4 < path2.length; i4++){
148
86
  if(_path[i4] != path2[i4]) path_match = 0;
149
87
  }
150
88
  }
151
- if(path_match == 1){
152
- val = _val;
153
- break;
154
- }
155
- }
156
- return val;
157
- }
158
-
159
- function getLen(uint[] memory json) private pure returns(uint, uint){
160
- uint ji = 0;
161
- uint prev = 0;
162
- uint jlen = 0;
163
- for(uint j = 0; j < json.length; j++){
164
- if(json[j] > 0){
165
- jlen = j + 1;
166
- uint p = digits(json[j]);
167
- uint x = json[j];
168
- uint on = 0;
169
- uint cur = 0;
170
- uint len = 0;
171
- uint num = 0;
172
- uint is9 = 0;
173
- while(p > 0){
174
- uint n = x / 10 ** (p - 1);
175
- if(on == 0 && n > 0){
176
- on = 1;
177
- if(n == 9){
178
- len = 8;
179
- is9 = 0;
180
- }else{
181
- len = n;
182
- }
183
- cur = 0;
184
- }else if(on == 1){
185
- num += n * 10 ** (len - cur - 1);
186
- cur++;
187
- if(cur == len){
188
- prev *= 10 ** len;
189
- if(is9 == 1){
190
- prev += num;
191
- }else{
192
- num += prev;
193
- prev = 0;
194
- ji++;
195
- }
196
- cur = 0;
197
- on = 0;
198
- len = 0;
199
- num = 0;
200
- is9 = 0;
201
- }
202
- }
203
- x -= 10 ** (p - 1) * n;
204
- p--;
205
- }
206
- }
89
+ if(path_match == 1) return _val2;
207
90
  }
208
- return (ji, jlen);
91
+ require(false, "value not found");
209
92
  }
210
93
 
211
94
  function toArr(uint[] memory json) internal pure returns(uint[] memory){
212
- (uint _len, uint _jlen) = getLen(json);
213
- uint[] memory _json = new uint[](_len);
214
- uint ji = 0;
215
- uint prev = 0;
216
- for(uint j = 0; j < _jlen; j++){
217
- uint p = digits(json[j]);
218
- uint x = json[j];
219
- uint on = 0;
220
- uint cur = 0;
221
- uint len = 0;
222
- uint num = 0;
223
- uint is9 = 0;
224
- while(p > 0){
225
- uint n = x / 10 ** (p - 1);
226
- if(on == 0 && n > 0){
227
- on = 1;
228
- if(n == 9){
229
- len = 8;
230
- is9 = 0;
231
- }else{
232
- len = n;
233
- }
234
- cur = 0;
235
- }else if(on == 1){
236
- num += n * 10 ** (len - cur - 1);
237
- cur++;
238
- if(cur == len){
239
- prev *= 10 ** len;
240
- if(is9 == 1){
241
- prev += num;
242
- }else{
243
- num += prev;
244
- prev = 0;
245
- _json[ji] = num;
246
- ji++;
247
- }
248
- cur = 0;
249
- on = 0;
250
- len = 0;
251
- num = 0;
252
- is9 = 0;
95
+ uint[] memory _json;
96
+ assembly {
97
+ let ji := 0x0
98
+ let prev := 0
99
+ let start := add(json, 0x20)
100
+ _json := msize()
101
+ mstore(_json, mload(json))
102
+ let _json0 := add(_json, 0x20)
103
+ for { let i := 0 } lt(i, mload(json)) { i := add(i, 1) } {
104
+ let v := mload(add(start, mul(i, 0x20)))
105
+ if gt(v,0) {
106
+ let p := 0
107
+ let x := v
108
+ let on := 0
109
+ let cur := 0
110
+ let len := 0
111
+ let num := 0
112
+ let is9 := 0
113
+ for { } gt(v, 0) { } {
114
+ v := div(v, 10)
115
+ p := add(p, 1)
116
+ }
117
+ for { } gt(p, 0) { } {
118
+ let n := div(x, exp(10, sub(p, 1)))
119
+ let _on := on
120
+ if and(iszero(_on), gt(n, 0)) {
121
+ on := 1
122
+ if eq(n, 9) {
123
+ len := 8
124
+ is9 := 0
125
+ }
126
+ if iszero(eq(n, 9)) {
127
+ len := n
128
+ }
129
+ cur := 0
130
+ }
131
+ if eq(_on, 1) {
132
+ num := add(num, mul(n, exp(10, sub(sub(len, cur), 1))))
133
+ cur := add(cur, 1)
134
+ if eq(cur, len) {
135
+ prev := mul(prev, exp(10, len))
136
+ if eq(is9, 1) {
137
+ prev := add(prev, num)
138
+ }
139
+ if iszero(eq(is9, 1)) {
140
+ num := add(num, prev)
141
+ prev := 0
142
+ mstore(add(_json0, ji), num)
143
+ ji := add(ji, 0x20)
144
+ }
145
+ cur := 0
146
+ on := 0
147
+ len := 0
148
+ num := 0
149
+ is9 := 0
150
+ }
151
+ }
152
+ x := sub(x, mul(exp(10, sub(p, 1)), n))
153
+ p := sub(p, 1)
253
154
  }
254
155
  }
255
- x -= 10 ** (p - 1) * n;
256
- p--;
257
156
  }
157
+ mstore(_json, div(ji, 0x20))
158
+ mstore(0x40, add(_json, add(0x20, ji)))
258
159
  }
259
160
  return _json;
260
161
  }
@@ -302,19 +203,6 @@ contract ZKQuery {
302
203
  return true;
303
204
  }
304
205
 
305
- function _parseZKP(uint[] calldata zkp) internal pure returns (uint[2] memory, uint[2][2] memory, uint[2] memory, uint[] memory) {
306
- uint[2] memory _pA;
307
- uint[2][2] memory _pB;
308
- uint[2] memory _pC;
309
- uint[] memory sigs = new uint[](zkp.length - 8);
310
- for(uint i = 0; i < 2; i++) _pA[i] = zkp[i];
311
- for(uint i = 2; i < 4; i++) _pB[0][i - 2] = zkp[i];
312
- for(uint i = 4; i < 6; i++) _pB[1][i - 4] = zkp[i];
313
- for(uint i = 6; i < 8; i++) _pC[i - 6] = zkp[i];
314
- for(uint i = 8; i < zkp.length; i++) sigs[i - 8] = zkp[i];
315
- return (_pA, _pB, _pC, sigs);
316
- }
317
-
318
206
  function getInt (uint[] memory path, uint[] memory raw) internal pure returns (int) {
319
207
  uint[] memory value = getVal(path, raw);
320
208
  return _qInt(value);
@@ -334,5 +222,36 @@ contract ZKQuery {
334
222
  uint[] memory value = getVal(path, raw);
335
223
  _qNull(value);
336
224
  }
337
-
225
+ function verify(uint[] memory zkp, bytes4 selector, address addr) internal view returns (bool) {
226
+ uint size;
227
+ assembly {
228
+ size := extcodesize(addr)
229
+ }
230
+ require(size > 0, "contract doesn't exist");
231
+ bool valid;
232
+ assembly{
233
+ let callData := mload(0x40)
234
+ let zlen := mload(zkp)
235
+ let clen := add(0x4, mul(0x20, zlen))
236
+ mstore(callData, clen)
237
+ mstore(add(callData, 0x20), selector)
238
+ for { let i := 1 } lt(i, add(1, zlen)) { i := add(i, 1) } {
239
+ mstore(add(callData, add(0x4, mul(i, 0x20))), mload(add(zkp, mul(i, 0x20))))
240
+ }
241
+ let success := staticcall(
242
+ gas(),
243
+ addr,
244
+ add(callData, 0x20),
245
+ clen,
246
+ callData,
247
+ 0x20
248
+ )
249
+ if iszero(success) {
250
+ revert(0, 0)
251
+ }
252
+ valid := mload(callData)
253
+ }
254
+ require(valid, "invalid proof");
255
+ return true;
256
+ }
338
257
  }
@@ -1,7 +1,6 @@
1
1
  // SPDX-License-Identifier: MIT
2
2
 
3
3
  pragma solidity >=0.7.0 <0.9.0;
4
- import "hardhat/console.sol";
5
4
  import "./ZKQuery.sol";
6
5
 
7
6
  interface VerifierRU {
@@ -14,21 +13,7 @@ contract ZKRollup is ZKQuery {
14
13
  address public committer;
15
14
  uint public root;
16
15
 
17
- function _verifyRU(uint[] calldata zkp) private view returns (bool) {
18
- uint[2] memory _pA;
19
- uint[2][2] memory _pB;
20
- uint[2] memory _pC;
21
- uint[11] memory sigs;
22
- for(uint i = 0; i < 2; i++) _pA[i] = zkp[i];
23
- for(uint i = 2; i < 4; i++) _pB[0][i - 2] = zkp[i];
24
- for(uint i = 4; i < 6; i++) _pB[1][i - 4] = zkp[i];
25
- for(uint i = 6; i < 8; i++) _pC[i - 6] = zkp[i];
26
- for(uint i = 8; i < 19; i++) sigs[i - 8] = zkp[i];
27
- require(VerifierRU(verifierRU).verifyProof(_pA, _pB, _pC, sigs), "invalid proof");
28
- return true;
29
- }
30
-
31
- function _validateQueryRU(uint[] memory path, uint[] calldata zkp, uint size_path, uint size_val) internal view returns(uint[] memory){
16
+ function _validateQueryRU(uint[] memory path, uint[] memory zkp, uint size_path, uint size_val) internal view returns(uint[] memory){
32
17
  require(zkp[19] == root, "root mismatch");
33
18
  require(zkp[size_path + size_val + 10] == path[0], "wrong collection");
34
19
  require(zkp[size_path + size_val + 11] == path[1], "wrong doc");
@@ -40,16 +25,11 @@ contract ZKRollup is ZKQuery {
40
25
  return toArr(value);
41
26
  }
42
27
 
43
- function commit (uint[] calldata zkp) public returns (uint) {
28
+ function commit (uint[] memory zkp) public returns (uint) {
44
29
  require (zkp[9] == root, "wrong merkle root");
45
30
  require(msg.sender == committer, "sender is not committer");
46
31
  root = zkp[8];
47
- verifyRU(zkp);
32
+ verify(zkp,VerifierRU.verifyProof.selector, verifierRU);
48
33
  return root;
49
34
  }
50
-
51
- function verifyRU(uint[] calldata zkp) private view returns (bool) {
52
- return _verifyRU(zkp);
53
- }
54
-
55
35
  }
package/encoder.js CHANGED
@@ -1,4 +1,17 @@
1
- const { splitEvery, flatten } = require("ramda")
1
+ const { isNil, includes, splitEvery, flatten } = require("ramda")
2
+ const ops = {
3
+ $eq: 10,
4
+ $ne: 11,
5
+ $gt: 12,
6
+ $gte: 13,
7
+ $lt: 14,
8
+ $lte: 15,
9
+ $in: 16,
10
+ $nin: 17,
11
+ }
12
+ const opMap = {}
13
+ for (let k in ops) opMap[ops[k]] = k
14
+
2
15
  const base64Map = {
3
16
  A: "00",
4
17
  B: "01",
@@ -456,6 +469,19 @@ const fromIndex = id2str
456
469
  const path = p => toSignal(encodePath(p))
457
470
  const val = v => toSignal(encodeVal(v))
458
471
 
472
+ function encodeQuery(v) {
473
+ if (!Array.isArray(v)) throw Error("query must be an array")
474
+ const op = v[0]
475
+ if (isNil(ops[op])) throw Error(`query not supported: ${op}`)
476
+ return [ops[op], ...encodeVal(v.slice(1))]
477
+ }
478
+
479
+ function decodeQuery(v) {
480
+ const op = opMap[v[0]]
481
+ if (isNil(op)) throw Error("op doens't exist")
482
+ return [op, ...decodeVal(v.slice(1))]
483
+ }
484
+
459
485
  module.exports = {
460
486
  encode,
461
487
  decode,
@@ -476,4 +502,6 @@ module.exports = {
476
502
  fromIndex,
477
503
  path,
478
504
  val,
505
+ encodeQuery,
506
+ decodeQuery,
479
507
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zkjson",
3
- "version": "0.1.14",
3
+ "version": "0.1.15",
4
4
  "description": "Zero Knowledge Provable JSON",
5
5
  "main": "index.js",
6
6
  "license": "MIT",