zkjson 0.1.14 → 0.1.15

Sign up to get free protection for your applications and to get access to all the features.
@@ -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",