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.
- package/contracts/ZKJson.sol +1 -1
- package/contracts/ZKQuery.sol +156 -237
- package/contracts/ZKRollup.sol +3 -23
- package/encoder.js +29 -1
- package/package.json +1 -1
package/contracts/ZKJson.sol
CHANGED
@@ -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[]
|
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");
|
package/contracts/ZKQuery.sol
CHANGED
@@ -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
|
9
|
-
uint
|
10
|
-
|
11
|
-
|
12
|
-
|
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
|
38
|
+
return (_path, i);
|
15
39
|
}
|
16
40
|
|
17
|
-
function
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
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
|
-
|
47
|
-
|
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
|
-
|
61
|
-
|
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
|
-
|
69
|
-
|
70
|
-
|
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 (
|
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
|
99
|
-
uint[] memory
|
100
|
-
|
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(
|
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
|
-
|
91
|
+
require(false, "value not found");
|
209
92
|
}
|
210
93
|
|
211
94
|
function toArr(uint[] memory json) internal pure returns(uint[] memory){
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
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
|
}
|
package/contracts/ZKRollup.sol
CHANGED
@@ -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
|
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[]
|
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
|
-
|
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
|
}
|