zkjson 0.1.24 → 0.1.26

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,96 @@
1
+ // SPDX-License-Identifier: MIT
2
+
3
+ pragma solidity >=0.7.0 <0.9.0;
4
+ import "./ZKQuery.sol";
5
+ import "hardhat/console.sol";
6
+
7
+ interface VerifierIPFS {
8
+ function verifyProof(uint[2] calldata _pA, uint[2][2] calldata _pB, uint[2] calldata _pC, uint[43] calldata _pubSignals) external view returns (bool);
9
+ }
10
+
11
+ contract ZKIPFS is ZKQuery{
12
+ uint constant SIZE_PATH = 5;
13
+ uint constant SIZE_VAL = 5;
14
+ address public verifierIPFS;
15
+ bytes constant ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
16
+
17
+ function charArrayToString(bytes1[46] memory charArray) public pure returns (string memory) {
18
+ bytes memory byteArray = new bytes(charArray.length);
19
+ for(uint i = 0; i < charArray.length; i++) {
20
+ byteArray[i] = charArray[i];
21
+ }
22
+ return string(byteArray);
23
+ }
24
+
25
+ function concat(string memory a, string memory b) public pure returns (string memory) {
26
+ return string(abi.encodePacked(a, b));
27
+ }
28
+
29
+ function uriEqual(string memory a, string memory b) public pure returns (bool) {
30
+ return keccak256(abi.encodePacked(a)) == keccak256(abi.encodePacked(b));
31
+ }
32
+
33
+ function toCID(uint[34] memory source) public pure returns (string memory) {
34
+ uint zeroes = 0;
35
+ uint length = 0;
36
+ uint pbegin = 0;
37
+ uint pend = source.length;
38
+ while (pbegin != pend && source[pbegin] == 0) {
39
+ pbegin++;
40
+ zeroes++;
41
+ }
42
+ uint size = 46;
43
+ uint[46] memory b58;
44
+ while (pbegin != pend) {
45
+ uint carry = source[pbegin];
46
+ uint i = 0;
47
+ for ( uint it1 = size - 1; (carry != 0 || i < length); it1-- ) {
48
+ carry += (256 * b58[it1]);
49
+ b58[it1] = carry % 58;
50
+ carry = (carry / 58);
51
+ i++;
52
+ if(it1 == 0) break;
53
+ }
54
+ length = i;
55
+ pbegin++;
56
+ }
57
+ uint it2 = size - length;
58
+ while (it2 != size && b58[it2] == 0) it2++;
59
+ bytes1[46] memory str;
60
+ uint i = 0;
61
+ for (; it2 < size; ++it2){
62
+ str[i] = ALPHABET[b58[it2]];
63
+ i++;
64
+ }
65
+ return charArrayToString(str);
66
+ }
67
+
68
+ function ipfsURI(uint[34] memory source) public pure returns (string memory) {
69
+ return concat("ipfs://", toCID(source));
70
+ }
71
+
72
+ function _validateQueryIPFS(uint[] memory path, uint[] memory zkp, uint size_path, uint size_val) internal pure returns(uint[] memory){
73
+ require(zkp[8] == 1, "value doesn't exist");
74
+ uint len = 41;
75
+ for(uint i = len; i < len + size_path; i++){
76
+ require((path.length <= i - len && zkp[i] == 0) || path[i - len] == zkp[i], "wrong path");
77
+ }
78
+ uint[] memory value = new uint[](size_val);
79
+ for(uint i = len + size_path; i < len + size_path + size_val; i++){
80
+ value[i - (len + size_val)] = zkp[i];
81
+ }
82
+ return toArr(value);
83
+ }
84
+
85
+ function validateQuery(string memory URI, uint[] memory path, uint[] memory zkp) internal pure returns(uint[] memory){
86
+ uint[34] memory hash;
87
+ hash[0] = 18;
88
+ hash[1] = 32;
89
+ for(uint i = 9; i < 41; i++) hash[i - 7] = zkp[i];
90
+ string memory CID = ipfsURI(hash);
91
+ require(uriEqual(CID,URI), "wrong CID");
92
+ verify(zkp, VerifierIPFS.verifyProof.selector, verifierIPFS);
93
+ return _validateQueryIPFS(path, zkp, SIZE_PATH, SIZE_VAL);
94
+ }
95
+
96
+ }
package/nft.js ADDED
@@ -0,0 +1,131 @@
1
+ const crypto = require("crypto")
2
+ const snarkjs = require("snarkjs")
3
+ const { query, pad, path, val } = require("./encoder")
4
+ const { push, arr } = require("./uint")
5
+ const { parse } = require("./parse")
6
+
7
+ function coerce(o) {
8
+ if (o instanceof Uint8Array && o.constructor.name === "Uint8Array") return o
9
+ if (o instanceof ArrayBuffer) return new Uint8Array(o)
10
+ if (ArrayBuffer.isView(o)) {
11
+ return new Uint8Array(o.buffer, o.byteOffset, o.byteLength)
12
+ }
13
+ throw new Error("Unknown type, must be binary type")
14
+ }
15
+
16
+ const ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
17
+ const BASE = ALPHABET.length
18
+ const LEADER = ALPHABET.charAt(0)
19
+ const FACTOR = Math.log(BASE) / Math.log(256)
20
+ const iFACTOR = Math.log(256) / Math.log(BASE)
21
+
22
+ function toCID(source) {
23
+ if (source instanceof Uint8Array);
24
+ else if (ArrayBuffer.isView(source)) {
25
+ source = new Uint8Array(source.buffer, source.byteOffset, source.byteLength)
26
+ } else if (Array.isArray(source)) {
27
+ source = Uint8Array.from(source)
28
+ }
29
+ if (!(source instanceof Uint8Array)) {
30
+ throw new TypeError("Expected Uint8Array")
31
+ }
32
+ if (source.length === 0) return ""
33
+
34
+ var zeroes = 0
35
+ var length = 0
36
+ var pbegin = 0
37
+ var pend = source.length
38
+ while (pbegin !== pend && source[pbegin] === 0) {
39
+ pbegin++
40
+ zeroes++
41
+ }
42
+
43
+ var size = ((pend - pbegin) * iFACTOR + 1) >>> 0
44
+ var b58 = new Uint8Array(size)
45
+ while (pbegin !== pend) {
46
+ var carry = source[pbegin]
47
+ var i = 0
48
+ for (
49
+ var it1 = size - 1;
50
+ (carry !== 0 || i < length) && it1 !== -1;
51
+ it1--, i++
52
+ ) {
53
+ carry += (256 * b58[it1]) >>> 0
54
+ b58[it1] = carry % BASE >>> 0
55
+ carry = (carry / BASE) >>> 0
56
+ }
57
+ if (carry !== 0) {
58
+ throw new Error("Non-zero carry")
59
+ }
60
+ length = i
61
+ pbegin++
62
+ }
63
+ var it2 = size - length
64
+ while (it2 !== size && b58[it2] === 0) {
65
+ it2++
66
+ }
67
+ var str = LEADER.repeat(zeroes)
68
+ for (; it2 < size; ++it2) {
69
+ str += ALPHABET.charAt(b58[it2])
70
+ }
71
+ return str
72
+ }
73
+
74
+ class NFT {
75
+ constructor({
76
+ size_val = 5,
77
+ size_path = 5,
78
+ size_json = 256,
79
+ nBlocks = 10,
80
+ wasm,
81
+ zkey,
82
+ json,
83
+ }) {
84
+ this.json = json
85
+ this.wasm = wasm
86
+ this.zkey = zkey
87
+ this.nBlocks = nBlocks
88
+ this.size_val = size_val
89
+ this.size_path = size_path
90
+ this.size_json = size_json
91
+ }
92
+ path(pth) {
93
+ return pad(path(pth), this.size_path)
94
+ }
95
+ val(pth) {
96
+ return pad(val(this.json[pth]), this.size_val)
97
+ }
98
+ query(pth, cond) {
99
+ return pad(query(cond), this.size_val)
100
+ }
101
+
102
+ async zkp(pth, cond) {
103
+ const str = new TextEncoder().encode(JSON.stringify(this.json))
104
+ let encoded = arr(256)
105
+ for (let v of Array.from(str))
106
+ encoded = push(encoded, this.size_json, 76, v)
107
+ const enc = parse(encoded, 256)
108
+ const _path = this.path(pth)
109
+ const _val = Array.isArray(cond) ? this.query(pth, cond) : this.val(pth)
110
+ const inputs = { path: _path, val: _val, encoded }
111
+ const { proof, publicSignals } = await snarkjs.groth16.fullProve(
112
+ inputs,
113
+ this.wasm,
114
+ this.zkey,
115
+ )
116
+ return [
117
+ ...proof.pi_a.slice(0, 2),
118
+ ...proof.pi_b[0].slice(0, 2).reverse(),
119
+ ...proof.pi_b[1].slice(0, 2).reverse(),
120
+ ...proof.pi_c.slice(0, 2),
121
+ ...publicSignals,
122
+ ]
123
+ }
124
+ cid() {
125
+ const str = new TextEncoder().encode(JSON.stringify(this.json))
126
+ const hash = coerce(crypto.createHash("sha256").update(str).digest())
127
+ return toCID(new Uint8Array([18, hash.length, ...Array.from(hash)]))
128
+ }
129
+ }
130
+
131
+ module.exports = NFT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zkjson",
3
- "version": "0.1.24",
3
+ "version": "0.1.26",
4
4
  "description": "Zero Knowledge Provable JSON",
5
5
  "main": "index.js",
6
6
  "license": "MIT",
package/uint.js CHANGED
@@ -591,4 +591,5 @@ module.exports = {
591
591
  concat,
592
592
  bn,
593
593
  digits,
594
+ str,
594
595
  }