zkjson 0.1.24 → 0.1.26

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.
@@ -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
  }