@freedomofpress/ics23 0.1.0
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/Readme.md +3 -0
- package/dist/.gitkeep +0 -0
- package/dist/compress.d.ts +3 -0
- package/dist/compress.js +96 -0
- package/dist/compress.js.map +1 -0
- package/dist/ics23.d.ts +18 -0
- package/dist/ics23.js +118 -0
- package/dist/ics23.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/ops.d.ts +4 -0
- package/dist/ops.js +111 -0
- package/dist/ops.js.map +1 -0
- package/dist/proofs.d.ts +11 -0
- package/dist/proofs.js +235 -0
- package/dist/proofs.js.map +1 -0
- package/dist/proto/cosmos/ics23/v1/proofs.d.ts +264 -0
- package/dist/proto/cosmos/ics23/v1/proofs.js +1411 -0
- package/dist/proto/cosmos/ics23/v1/proofs.js.map +1 -0
- package/dist/specs.d.ts +7 -0
- package/dist/specs.js +105 -0
- package/dist/specs.js.map +1 -0
- package/dist/tests/ops.test.d.ts +1 -0
- package/dist/tests/ops.test.js +143 -0
- package/dist/tests/ops.test.js.map +1 -0
- package/dist/tests/proofs.test.d.ts +1 -0
- package/dist/tests/proofs.test.js +194 -0
- package/dist/tests/proofs.test.js.map +1 -0
- package/dist/tests/testhelpers.d.ts +3 -0
- package/dist/tests/testhelpers.js +35 -0
- package/dist/tests/testhelpers.js.map +1 -0
- package/dist/tests/testvectors.test.d.ts +1 -0
- package/dist/tests/testvectors.test.js +229 -0
- package/dist/tests/testvectors.test.js.map +1 -0
- package/dist/tests/webcat.test.d.ts +1 -0
- package/dist/tests/webcat.test.js +45 -0
- package/dist/tests/webcat.test.js.map +1 -0
- package/dist/webcat.d.ts +15 -0
- package/dist/webcat.js +77 -0
- package/dist/webcat.js.map +1 -0
- package/package.json +46 -0
package/Readme.md
ADDED
package/dist/.gitkeep
ADDED
|
File without changes
|
package/dist/compress.js
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { InnerOp, } from "./proto/cosmos/ics23/v1/proofs";
|
|
2
|
+
export function compress(proof) {
|
|
3
|
+
if (!proof.batch) {
|
|
4
|
+
return proof;
|
|
5
|
+
}
|
|
6
|
+
return { compressed: compressBatch(proof.batch) };
|
|
7
|
+
}
|
|
8
|
+
export function decompress(proof) {
|
|
9
|
+
if (!proof.compressed) {
|
|
10
|
+
return proof;
|
|
11
|
+
}
|
|
12
|
+
return { batch: decompressBatch(proof.compressed) };
|
|
13
|
+
}
|
|
14
|
+
function compressBatch(proof) {
|
|
15
|
+
const centries = [];
|
|
16
|
+
const lookup = [];
|
|
17
|
+
const registry = new Map();
|
|
18
|
+
for (const entry of proof.entries) {
|
|
19
|
+
if (entry.exist) {
|
|
20
|
+
const centry = { exist: compressExist(entry.exist, lookup, registry) };
|
|
21
|
+
centries.push(centry);
|
|
22
|
+
}
|
|
23
|
+
else if (entry.nonexist) {
|
|
24
|
+
const non = entry.nonexist;
|
|
25
|
+
const centry = {
|
|
26
|
+
nonexist: {
|
|
27
|
+
key: non.key,
|
|
28
|
+
left: compressExist(non.left, lookup, registry),
|
|
29
|
+
right: compressExist(non.right, lookup, registry),
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
centries.push(centry);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
throw new Error("Unexpected batch entry during compress");
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
entries: centries,
|
|
40
|
+
lookupInners: lookup,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
function compressExist(exist, lookup, registry) {
|
|
44
|
+
if (!exist) {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
const path = exist.path.map((inner) => {
|
|
48
|
+
const sig = InnerOp.encode(inner).finish();
|
|
49
|
+
let idx = registry.get(sig);
|
|
50
|
+
if (idx === undefined) {
|
|
51
|
+
idx = lookup.length;
|
|
52
|
+
lookup.push(inner);
|
|
53
|
+
registry.set(sig, idx);
|
|
54
|
+
}
|
|
55
|
+
return idx;
|
|
56
|
+
});
|
|
57
|
+
return {
|
|
58
|
+
key: exist.key,
|
|
59
|
+
value: exist.value,
|
|
60
|
+
leaf: exist.leaf,
|
|
61
|
+
path,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function decompressBatch(proof) {
|
|
65
|
+
const lookup = proof.lookupInners;
|
|
66
|
+
const entries = proof.entries.map((comp) => {
|
|
67
|
+
if (comp.exist) {
|
|
68
|
+
return { exist: decompressExist(comp.exist, lookup) };
|
|
69
|
+
}
|
|
70
|
+
else if (comp.nonexist) {
|
|
71
|
+
const non = comp.nonexist;
|
|
72
|
+
return {
|
|
73
|
+
nonexist: {
|
|
74
|
+
key: non.key,
|
|
75
|
+
left: decompressExist(non.left, lookup),
|
|
76
|
+
right: decompressExist(non.right, lookup),
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
throw new Error("Unexpected batch entry during compress");
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
return {
|
|
85
|
+
entries,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
function decompressExist(exist, lookup) {
|
|
89
|
+
if (!exist) {
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
const { key, value, leaf, path } = exist;
|
|
93
|
+
const newPath = (path || []).map((idx) => lookup[idx]);
|
|
94
|
+
return { key, value, leaf, path: newPath };
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=compress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compress.js","sourceRoot":"","sources":["../src/compress.ts"],"names":[],"mappings":"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"}
|
package/dist/ics23.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { CommitmentRoot } from "./proofs";
|
|
2
|
+
import { CommitmentProof, ProofSpec } from "./proto/cosmos/ics23/v1/proofs";
|
|
3
|
+
/**
|
|
4
|
+
* verifyMembership ensures proof is (contains) a valid existence proof for the given
|
|
5
|
+
*/
|
|
6
|
+
export declare function verifyMembership(proof: CommitmentProof, spec: ProofSpec, root: CommitmentRoot, key: Uint8Array, value: Uint8Array): Promise<boolean>;
|
|
7
|
+
/**
|
|
8
|
+
* verifyNonMembership ensures proof is (contains) a valid non-existence proof for the given key
|
|
9
|
+
*/
|
|
10
|
+
export declare function verifyNonMembership(proof: CommitmentProof, spec: ProofSpec, root: CommitmentRoot, key: Uint8Array): Promise<boolean>;
|
|
11
|
+
/**
|
|
12
|
+
* batchVerifyMembership ensures proof is (contains) a valid existence proof for the given
|
|
13
|
+
*/
|
|
14
|
+
export declare function batchVerifyMembership(proof: CommitmentProof, spec: ProofSpec, root: CommitmentRoot, items: Map<Uint8Array, Uint8Array>): Promise<boolean>;
|
|
15
|
+
/**
|
|
16
|
+
* batchVerifyNonMembership ensures proof is (contains) a valid existence proof for the given
|
|
17
|
+
*/
|
|
18
|
+
export declare function batchVerifyNonMembership(proof: CommitmentProof, spec: ProofSpec, root: CommitmentRoot, keys: readonly Uint8Array[]): Promise<boolean>;
|
package/dist/ics23.js
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { decompress } from "./compress";
|
|
2
|
+
import { verifyExistence, verifyNonExistence } from "./proofs";
|
|
3
|
+
import { keyForComparison } from "./proofs";
|
|
4
|
+
import { bytesBefore, bytesEqual } from "./specs";
|
|
5
|
+
/*
|
|
6
|
+
This implements the client side functions as specified in
|
|
7
|
+
https://github.com/cosmos/ics/tree/master/spec/ics-023-vector-commitments
|
|
8
|
+
|
|
9
|
+
In particular:
|
|
10
|
+
|
|
11
|
+
// Assumes ExistenceProof
|
|
12
|
+
type verifyMembership = (root: CommitmentRoot, proof: CommitmentProof, key: Key, value: Value) => boolean
|
|
13
|
+
|
|
14
|
+
// Assumes NonExistenceProof
|
|
15
|
+
type verifyNonMembership = (root: CommitmentRoot, proof: CommitmentProof, key: Key) => boolean
|
|
16
|
+
|
|
17
|
+
// Assumes BatchProof - required ExistenceProofs may be a subset of all items proven
|
|
18
|
+
type batchVerifyMembership = (root: CommitmentRoot, proof: CommitmentProof, items: Map<Key, Value>) => boolean
|
|
19
|
+
|
|
20
|
+
// Assumes BatchProof - required NonExistenceProofs may be a subset of all items proven
|
|
21
|
+
type batchVerifyNonMembership = (root: CommitmentRoot, proof: CommitmentProof, keys: Set<Key>) => boolean
|
|
22
|
+
|
|
23
|
+
We make an adjustment to accept a Spec to ensure the provided proof is in the format of the expected merkle store.
|
|
24
|
+
This can avoid an range of attacks on fake preimages, as we need to be careful on how to map key, value -> leaf
|
|
25
|
+
and determine neighbors
|
|
26
|
+
*/
|
|
27
|
+
/**
|
|
28
|
+
* verifyMembership ensures proof is (contains) a valid existence proof for the given
|
|
29
|
+
*/
|
|
30
|
+
export async function verifyMembership(proof, spec, root, key, value) {
|
|
31
|
+
const norm = decompress(proof);
|
|
32
|
+
const exist = getExistForKey(norm, key);
|
|
33
|
+
if (!exist) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
await verifyExistence(exist, spec, root, key, value);
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* verifyNonMembership ensures proof is (contains) a valid non-existence proof for the given key
|
|
46
|
+
*/
|
|
47
|
+
export async function verifyNonMembership(proof, spec, root, key) {
|
|
48
|
+
const norm = decompress(proof);
|
|
49
|
+
const nonexist = await getNonExistForKey(spec, norm, key);
|
|
50
|
+
if (!nonexist) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
try {
|
|
54
|
+
await verifyNonExistence(nonexist, spec, root, key);
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* batchVerifyMembership ensures proof is (contains) a valid existence proof for the given
|
|
63
|
+
*/
|
|
64
|
+
export async function batchVerifyMembership(proof, spec, root, items) {
|
|
65
|
+
const norm = decompress(proof);
|
|
66
|
+
for (const [key, value] of items.entries()) {
|
|
67
|
+
if (!(await verifyMembership(norm, spec, root, key, value))) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* batchVerifyNonMembership ensures proof is (contains) a valid existence proof for the given
|
|
75
|
+
*/
|
|
76
|
+
export async function batchVerifyNonMembership(proof, spec, root, keys) {
|
|
77
|
+
const norm = decompress(proof);
|
|
78
|
+
for (const key of keys) {
|
|
79
|
+
if (!(await verifyNonMembership(norm, spec, root, key))) {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
function getExistForKey(proof, key) {
|
|
86
|
+
const match = (p) => !!p && bytesEqual(key, p.key);
|
|
87
|
+
if (match(proof.exist)) {
|
|
88
|
+
return proof.exist;
|
|
89
|
+
}
|
|
90
|
+
else if (proof.batch) {
|
|
91
|
+
return proof.batch
|
|
92
|
+
.entries.map((x) => x.exist || null)
|
|
93
|
+
.find(match);
|
|
94
|
+
}
|
|
95
|
+
return undefined;
|
|
96
|
+
}
|
|
97
|
+
async function getNonExistForKey(spec, proof, key) {
|
|
98
|
+
const match = async (p) => {
|
|
99
|
+
return (!!p &&
|
|
100
|
+
(!p.left ||
|
|
101
|
+
bytesBefore(await keyForComparison(spec, p.left.key), await keyForComparison(spec, key))) &&
|
|
102
|
+
(!p.right ||
|
|
103
|
+
bytesBefore(await keyForComparison(spec, key), await keyForComparison(spec, p.right.key))));
|
|
104
|
+
};
|
|
105
|
+
if (await match(proof.nonexist)) {
|
|
106
|
+
return proof.nonexist;
|
|
107
|
+
}
|
|
108
|
+
else if (proof.batch) {
|
|
109
|
+
for (const entry of proof.batch.entries || []) {
|
|
110
|
+
const candidate = entry.nonexist || null;
|
|
111
|
+
if (await match(candidate)) {
|
|
112
|
+
return candidate;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return undefined;
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=ics23.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ics23.js","sourceRoot":"","sources":["../src/ics23.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { verifyMembership, verifyNonMembership } from "./ics23";
|
|
2
|
+
export { calculateExistenceRoot, iavlSpec, tendermintSpec, verifyExistence, verifyNonExistence, } from "./proofs";
|
|
3
|
+
export { verifyWebcatProof, webcatSpec } from "./webcat";
|
|
4
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EACL,sBAAsB,EAEtB,QAAQ,EACR,cAAc,EACd,eAAe,EACf,kBAAkB,GACnB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC"}
|
package/dist/ops.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { HashOp, InnerOp, LeafOp } from "./proto/cosmos/ics23/v1/proofs";
|
|
2
|
+
export declare function applyLeaf(leaf: LeafOp, key: Uint8Array, value: Uint8Array): Promise<Uint8Array>;
|
|
3
|
+
export declare function applyInner(inner: InnerOp, child: Uint8Array): Promise<Uint8Array>;
|
|
4
|
+
export declare function doHash(hashOp: HashOp, preimage: Uint8Array): Promise<Uint8Array>;
|
package/dist/ops.js
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { HashOp, LengthOp, } from "./proto/cosmos/ics23/v1/proofs";
|
|
2
|
+
const subtle = globalThis.crypto?.subtle;
|
|
3
|
+
async function sha256(preimage) {
|
|
4
|
+
if (!subtle) {
|
|
5
|
+
throw new Error("Web Crypto API is not available");
|
|
6
|
+
}
|
|
7
|
+
const digest = await subtle.digest("SHA-256", preimage);
|
|
8
|
+
return new Uint8Array(digest);
|
|
9
|
+
}
|
|
10
|
+
export async function applyLeaf(leaf, key, value) {
|
|
11
|
+
if (key.length === 0) {
|
|
12
|
+
throw new Error("Missing key");
|
|
13
|
+
}
|
|
14
|
+
if (value.length === 0) {
|
|
15
|
+
throw new Error("Missing value");
|
|
16
|
+
}
|
|
17
|
+
const pkey = await prepareLeafData(ensureHash(leaf.prehashKey), ensureLength(leaf.length), key);
|
|
18
|
+
const pvalue = await prepareLeafData(ensureHash(leaf.prehashValue), ensureLength(leaf.length), value);
|
|
19
|
+
const data = new Uint8Array([
|
|
20
|
+
...ensureBytes(leaf.prefix),
|
|
21
|
+
...pkey,
|
|
22
|
+
...pvalue,
|
|
23
|
+
]);
|
|
24
|
+
return doHash(ensureHash(leaf.hash), data);
|
|
25
|
+
}
|
|
26
|
+
export async function applyInner(inner, child) {
|
|
27
|
+
if (child.length === 0) {
|
|
28
|
+
throw new Error("Inner op needs child value");
|
|
29
|
+
}
|
|
30
|
+
const preimage = new Uint8Array([
|
|
31
|
+
...ensureBytes(inner.prefix),
|
|
32
|
+
...child,
|
|
33
|
+
...ensureBytes(inner.suffix),
|
|
34
|
+
]);
|
|
35
|
+
return doHash(ensureHash(inner.hash), preimage);
|
|
36
|
+
}
|
|
37
|
+
function ensure(maybe, value) {
|
|
38
|
+
return maybe === undefined || maybe === null ? value : maybe;
|
|
39
|
+
}
|
|
40
|
+
const ensureHash = (h) => ensure(h, HashOp.NO_HASH);
|
|
41
|
+
const ensureLength = (l) => ensure(l, LengthOp.NO_PREFIX);
|
|
42
|
+
const ensureBytes = (b) => ensure(b, new Uint8Array([]));
|
|
43
|
+
async function prepareLeafData(hashOp, lengthOp, data) {
|
|
44
|
+
const h = await doHashOrNoop(hashOp, data);
|
|
45
|
+
return doLengthOp(lengthOp, h);
|
|
46
|
+
}
|
|
47
|
+
// doHashOrNoop will return the preimage untouched if hashOp == NONE,
|
|
48
|
+
// otherwise, perform doHash
|
|
49
|
+
async function doHashOrNoop(hashOp, preimage) {
|
|
50
|
+
if (hashOp === HashOp.NO_HASH) {
|
|
51
|
+
return preimage;
|
|
52
|
+
}
|
|
53
|
+
return doHash(hashOp, preimage);
|
|
54
|
+
}
|
|
55
|
+
// doHash will perform the specified hash on the preimage.
|
|
56
|
+
// if hashOp == NONE, it will return an error (use doHashOrNoop if you want different behavior)
|
|
57
|
+
export async function doHash(hashOp, preimage) {
|
|
58
|
+
if (hashOp === HashOp.SHA256) {
|
|
59
|
+
return sha256(preimage);
|
|
60
|
+
}
|
|
61
|
+
throw new Error(`Unsupported hashop: ${hashOp}`);
|
|
62
|
+
}
|
|
63
|
+
// doLengthOp will calculate the proper prefix and return it prepended
|
|
64
|
+
// doLengthOp(op, data) -> length(data) || data
|
|
65
|
+
function doLengthOp(lengthOp, data) {
|
|
66
|
+
switch (lengthOp) {
|
|
67
|
+
case LengthOp.NO_PREFIX:
|
|
68
|
+
return data;
|
|
69
|
+
case LengthOp.VAR_PROTO:
|
|
70
|
+
return new Uint8Array([...encodeVarintProto(data.length), ...data]);
|
|
71
|
+
case LengthOp.REQUIRE_32_BYTES:
|
|
72
|
+
if (data.length !== 32) {
|
|
73
|
+
throw new Error(`Length is ${data.length}, not 32 bytes`);
|
|
74
|
+
}
|
|
75
|
+
return data;
|
|
76
|
+
case LengthOp.REQUIRE_64_BYTES:
|
|
77
|
+
if (data.length !== 64) {
|
|
78
|
+
throw new Error(`Length is ${data.length}, not 64 bytes`);
|
|
79
|
+
}
|
|
80
|
+
return data;
|
|
81
|
+
case LengthOp.FIXED32_LITTLE:
|
|
82
|
+
return new Uint8Array([...encodeFixed32Le(data.length), ...data]);
|
|
83
|
+
// TODO
|
|
84
|
+
// case LengthOp_VAR_RLP:
|
|
85
|
+
// case LengthOp_FIXED32_BIG:
|
|
86
|
+
// case LengthOp_FIXED64_BIG:
|
|
87
|
+
// case LengthOp_FIXED64_LITTLE:
|
|
88
|
+
}
|
|
89
|
+
throw new Error(`Unsupported lengthop: ${lengthOp}`);
|
|
90
|
+
}
|
|
91
|
+
function encodeVarintProto(n) {
|
|
92
|
+
let enc = [];
|
|
93
|
+
let l = n;
|
|
94
|
+
while (l >= 128) {
|
|
95
|
+
const b = (l % 128) + 128;
|
|
96
|
+
enc = [...enc, b];
|
|
97
|
+
l = l / 128;
|
|
98
|
+
}
|
|
99
|
+
enc = [...enc, l];
|
|
100
|
+
return new Uint8Array(enc);
|
|
101
|
+
}
|
|
102
|
+
function encodeFixed32Le(n) {
|
|
103
|
+
const enc = new Uint8Array(4);
|
|
104
|
+
let l = n;
|
|
105
|
+
for (let i = enc.length; i > 0; i--) {
|
|
106
|
+
enc[Math.abs(i - enc.length)] = l % 256;
|
|
107
|
+
l = Math.floor(l / 256);
|
|
108
|
+
}
|
|
109
|
+
return enc;
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=ops.js.map
|
package/dist/ops.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ops.js","sourceRoot":"","sources":["../src/ops.ts"],"names":[],"mappings":"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"}
|
package/dist/proofs.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ExistenceProof, InnerOp, InnerSpec, NonExistenceProof, ProofSpec } from "./proto/cosmos/ics23/v1/proofs";
|
|
2
|
+
export declare const iavlSpec: ProofSpec;
|
|
3
|
+
export declare const tendermintSpec: ProofSpec;
|
|
4
|
+
export declare const smtSpec: ProofSpec;
|
|
5
|
+
export type CommitmentRoot = Uint8Array;
|
|
6
|
+
export declare function keyForComparison(spec: ProofSpec, key: Uint8Array): Promise<Uint8Array>;
|
|
7
|
+
export declare function verifyExistence(proof: ExistenceProof, spec: ProofSpec, root: CommitmentRoot, key: Uint8Array, value: Uint8Array): Promise<void>;
|
|
8
|
+
export declare function verifyNonExistence(proof: NonExistenceProof, spec: ProofSpec, root: CommitmentRoot, key: Uint8Array): Promise<void>;
|
|
9
|
+
export declare function calculateExistenceRoot(proof: ExistenceProof): Promise<CommitmentRoot>;
|
|
10
|
+
export declare function ensureSpec(proof: ExistenceProof, spec: ProofSpec): void;
|
|
11
|
+
export declare function ensureLeftNeighbor(spec: InnerSpec, left: readonly InnerOp[], right: readonly InnerOp[]): void;
|
package/dist/proofs.js
ADDED
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import { applyInner, applyLeaf, doHash } from "./ops";
|
|
2
|
+
import { HashOp, LengthOp, } from "./proto/cosmos/ics23/v1/proofs";
|
|
3
|
+
import { bytesEqual, ensureBytesBefore, ensureBytesEqual, ensureInner, ensureLeaf, } from "./specs";
|
|
4
|
+
export const iavlSpec = {
|
|
5
|
+
leafSpec: {
|
|
6
|
+
prefix: Uint8Array.from([0]),
|
|
7
|
+
hash: HashOp.SHA256,
|
|
8
|
+
prehashValue: HashOp.SHA256,
|
|
9
|
+
prehashKey: HashOp.NO_HASH,
|
|
10
|
+
length: LengthOp.VAR_PROTO,
|
|
11
|
+
},
|
|
12
|
+
innerSpec: {
|
|
13
|
+
childOrder: [0, 1],
|
|
14
|
+
minPrefixLength: 4,
|
|
15
|
+
maxPrefixLength: 12,
|
|
16
|
+
childSize: 33,
|
|
17
|
+
hash: HashOp.SHA256,
|
|
18
|
+
emptyChild: new Uint8Array(),
|
|
19
|
+
},
|
|
20
|
+
minDepth: 0,
|
|
21
|
+
maxDepth: 255,
|
|
22
|
+
prehashKeyBeforeComparison: false,
|
|
23
|
+
};
|
|
24
|
+
export const tendermintSpec = {
|
|
25
|
+
leafSpec: {
|
|
26
|
+
prefix: Uint8Array.from([0]),
|
|
27
|
+
hash: HashOp.SHA256,
|
|
28
|
+
prehashValue: HashOp.SHA256,
|
|
29
|
+
prehashKey: HashOp.NO_HASH,
|
|
30
|
+
length: LengthOp.VAR_PROTO,
|
|
31
|
+
},
|
|
32
|
+
innerSpec: {
|
|
33
|
+
childOrder: [0, 1],
|
|
34
|
+
minPrefixLength: 1,
|
|
35
|
+
maxPrefixLength: 1,
|
|
36
|
+
childSize: 32,
|
|
37
|
+
hash: HashOp.SHA256,
|
|
38
|
+
emptyChild: new Uint8Array(),
|
|
39
|
+
},
|
|
40
|
+
minDepth: 0,
|
|
41
|
+
maxDepth: 255,
|
|
42
|
+
prehashKeyBeforeComparison: false,
|
|
43
|
+
};
|
|
44
|
+
export const smtSpec = {
|
|
45
|
+
leafSpec: {
|
|
46
|
+
hash: HashOp.SHA256,
|
|
47
|
+
prehashKey: HashOp.SHA256,
|
|
48
|
+
prehashValue: HashOp.SHA256,
|
|
49
|
+
length: LengthOp.NO_PREFIX,
|
|
50
|
+
prefix: Uint8Array.from([0]),
|
|
51
|
+
},
|
|
52
|
+
innerSpec: {
|
|
53
|
+
childOrder: [0, 1],
|
|
54
|
+
childSize: 32,
|
|
55
|
+
minPrefixLength: 1,
|
|
56
|
+
maxPrefixLength: 1,
|
|
57
|
+
emptyChild: new Uint8Array(32),
|
|
58
|
+
hash: HashOp.SHA256,
|
|
59
|
+
},
|
|
60
|
+
maxDepth: 256,
|
|
61
|
+
minDepth: 0,
|
|
62
|
+
prehashKeyBeforeComparison: true,
|
|
63
|
+
};
|
|
64
|
+
export async function keyForComparison(spec, key) {
|
|
65
|
+
if (!spec.prehashKeyBeforeComparison) {
|
|
66
|
+
return key;
|
|
67
|
+
}
|
|
68
|
+
return doHash(spec.leafSpec.prehashKey, key);
|
|
69
|
+
}
|
|
70
|
+
// verifyExistence will throw an error if the proof doesn't link key, value -> root
|
|
71
|
+
// or if it doesn't fulfill the spec
|
|
72
|
+
export async function verifyExistence(proof, spec, root, key, value) {
|
|
73
|
+
ensureSpec(proof, spec);
|
|
74
|
+
const calc = await calculateExistenceRoot(proof);
|
|
75
|
+
ensureBytesEqual(calc, root);
|
|
76
|
+
ensureBytesEqual(key, proof.key);
|
|
77
|
+
ensureBytesEqual(value, proof.value);
|
|
78
|
+
}
|
|
79
|
+
// Verify does all checks to ensure the proof has valid non-existence proofs,
|
|
80
|
+
// and they ensure the given key is not in the CommitmentState,
|
|
81
|
+
// throwing an error if there is an issue
|
|
82
|
+
export async function verifyNonExistence(proof, spec, root, key) {
|
|
83
|
+
let leftKey;
|
|
84
|
+
let rightKey;
|
|
85
|
+
if (proof.left) {
|
|
86
|
+
await verifyExistence(proof.left, spec, root, proof.left.key, proof.left.value);
|
|
87
|
+
leftKey = proof.left.key;
|
|
88
|
+
}
|
|
89
|
+
if (proof.right) {
|
|
90
|
+
await verifyExistence(proof.right, spec, root, proof.right.key, proof.right.value);
|
|
91
|
+
rightKey = proof.right.key;
|
|
92
|
+
}
|
|
93
|
+
if (!leftKey && !rightKey) {
|
|
94
|
+
throw new Error("neither left nor right proof defined");
|
|
95
|
+
}
|
|
96
|
+
if (leftKey) {
|
|
97
|
+
ensureBytesBefore(await keyForComparison(spec, leftKey), await keyForComparison(spec, key));
|
|
98
|
+
}
|
|
99
|
+
if (rightKey) {
|
|
100
|
+
ensureBytesBefore(await keyForComparison(spec, key), await keyForComparison(spec, rightKey));
|
|
101
|
+
}
|
|
102
|
+
if (!spec.innerSpec) {
|
|
103
|
+
throw new Error("no inner spec");
|
|
104
|
+
}
|
|
105
|
+
if (!leftKey) {
|
|
106
|
+
ensureLeftMost(spec.innerSpec, proof.right.path);
|
|
107
|
+
}
|
|
108
|
+
else if (!rightKey) {
|
|
109
|
+
ensureRightMost(spec.innerSpec, proof.left.path);
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
ensureLeftNeighbor(spec.innerSpec, proof.left.path, proof.right.path);
|
|
113
|
+
}
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
// Calculate determines the root hash that matches the given proof.
|
|
117
|
+
// You must validate the result is what you have in a header.
|
|
118
|
+
// Returns error if the calculations cannot be performed.
|
|
119
|
+
export async function calculateExistenceRoot(proof) {
|
|
120
|
+
if (!proof.key || !proof.value) {
|
|
121
|
+
throw new Error("Existence proof needs key and value set");
|
|
122
|
+
}
|
|
123
|
+
if (!proof.leaf) {
|
|
124
|
+
throw new Error("Existence proof must start with a leaf operation");
|
|
125
|
+
}
|
|
126
|
+
const path = proof.path || [];
|
|
127
|
+
let res = await applyLeaf(proof.leaf, proof.key, proof.value);
|
|
128
|
+
for (const inner of path) {
|
|
129
|
+
res = await applyInner(inner, res);
|
|
130
|
+
}
|
|
131
|
+
return res;
|
|
132
|
+
}
|
|
133
|
+
// ensureSpec throws an Error if proof doesn't fulfill spec
|
|
134
|
+
export function ensureSpec(proof, spec) {
|
|
135
|
+
if (!proof.leaf) {
|
|
136
|
+
throw new Error("Existence proof must start with a leaf operation");
|
|
137
|
+
}
|
|
138
|
+
if (!spec.leafSpec) {
|
|
139
|
+
throw new Error("Spec must include leafSpec");
|
|
140
|
+
}
|
|
141
|
+
if (!spec.innerSpec) {
|
|
142
|
+
throw new Error("Spec must include innerSpec");
|
|
143
|
+
}
|
|
144
|
+
ensureLeaf(proof.leaf, spec.leafSpec);
|
|
145
|
+
const path = proof.path || [];
|
|
146
|
+
if (spec.minDepth && path.length < spec.minDepth) {
|
|
147
|
+
throw new Error(`Too few inner nodes ${path.length}`);
|
|
148
|
+
}
|
|
149
|
+
if (spec.maxDepth && path.length > spec.maxDepth) {
|
|
150
|
+
throw new Error(`Too many inner nodes ${path.length}`);
|
|
151
|
+
}
|
|
152
|
+
for (const inner of path) {
|
|
153
|
+
ensureInner(inner, spec.leafSpec.prefix, spec.innerSpec);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
function ensureLeftMost(spec, path) {
|
|
157
|
+
const { minPrefix, maxPrefix, suffix } = getPadding(spec, 0);
|
|
158
|
+
// ensure every step has a prefix and suffix defined to be leftmost
|
|
159
|
+
for (const step of path) {
|
|
160
|
+
if (!hasPadding(step, minPrefix, maxPrefix, suffix)) {
|
|
161
|
+
throw new Error("Step not leftmost");
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
function ensureRightMost(spec, path) {
|
|
166
|
+
const len = spec.childOrder.length - 1;
|
|
167
|
+
const { minPrefix, maxPrefix, suffix } = getPadding(spec, len);
|
|
168
|
+
// ensure every step has a prefix and suffix defined to be leftmost
|
|
169
|
+
for (const step of path) {
|
|
170
|
+
if (!hasPadding(step, minPrefix, maxPrefix, suffix)) {
|
|
171
|
+
throw new Error("Step not leftmost");
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
export function ensureLeftNeighbor(spec, left, right) {
|
|
176
|
+
const mutleft = [...left];
|
|
177
|
+
const mutright = [...right];
|
|
178
|
+
let topleft = mutleft.pop();
|
|
179
|
+
let topright = mutright.pop();
|
|
180
|
+
while (bytesEqual(topleft.prefix, topright.prefix) &&
|
|
181
|
+
bytesEqual(topleft.suffix, topright.suffix)) {
|
|
182
|
+
topleft = mutleft.pop();
|
|
183
|
+
topright = mutright.pop();
|
|
184
|
+
}
|
|
185
|
+
// now topleft and topright are the first divergent nodes
|
|
186
|
+
// make sure they are left and right of each other
|
|
187
|
+
if (!isLeftStep(spec, topleft, topright)) {
|
|
188
|
+
throw new Error(`Not left neightbor at first divergent step`);
|
|
189
|
+
}
|
|
190
|
+
// make sure the paths are left and right most possibilities respectively
|
|
191
|
+
ensureRightMost(spec, mutleft);
|
|
192
|
+
ensureLeftMost(spec, mutright);
|
|
193
|
+
}
|
|
194
|
+
// isLeftStep assumes left and right have common parents
|
|
195
|
+
// checks if left is exactly one slot to the left of right
|
|
196
|
+
function isLeftStep(spec, left, right) {
|
|
197
|
+
const leftidx = orderFromPadding(spec, left);
|
|
198
|
+
const rightidx = orderFromPadding(spec, right);
|
|
199
|
+
return rightidx === leftidx + 1;
|
|
200
|
+
}
|
|
201
|
+
function orderFromPadding(spec, inner) {
|
|
202
|
+
for (let branch = 0; branch < spec.childOrder.length; branch++) {
|
|
203
|
+
const { minPrefix, maxPrefix, suffix } = getPadding(spec, branch);
|
|
204
|
+
if (hasPadding(inner, minPrefix, maxPrefix, suffix)) {
|
|
205
|
+
return branch;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
throw new Error(`Cannot find any valid spacing for this node`);
|
|
209
|
+
}
|
|
210
|
+
function hasPadding(op, minPrefix, maxPrefix, suffix) {
|
|
211
|
+
if ((op.prefix || []).length < minPrefix) {
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
214
|
+
if ((op.prefix || []).length > maxPrefix) {
|
|
215
|
+
return false;
|
|
216
|
+
}
|
|
217
|
+
return (op.suffix || []).length === suffix;
|
|
218
|
+
}
|
|
219
|
+
function getPadding(spec, branch) {
|
|
220
|
+
const idx = getPosition(spec.childOrder, branch);
|
|
221
|
+
// count how many children are in the prefix
|
|
222
|
+
const prefix = idx * spec.childSize;
|
|
223
|
+
const minPrefix = prefix + spec.minPrefixLength;
|
|
224
|
+
const maxPrefix = prefix + spec.maxPrefixLength;
|
|
225
|
+
// count how many children are in the suffix
|
|
226
|
+
const suffix = (spec.childOrder.length - 1 - idx) * spec.childSize;
|
|
227
|
+
return { minPrefix, maxPrefix, suffix };
|
|
228
|
+
}
|
|
229
|
+
function getPosition(order, branch) {
|
|
230
|
+
if (branch < 0 || branch >= order.length) {
|
|
231
|
+
throw new Error(`Invalid branch: ${branch}`);
|
|
232
|
+
}
|
|
233
|
+
return order.findIndex((val) => val === branch);
|
|
234
|
+
}
|
|
235
|
+
//# sourceMappingURL=proofs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proofs.js","sourceRoot":"","sources":["../src/proofs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AACtD,OAAO,EAEL,MAAM,EAGN,QAAQ,GAGT,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,gBAAgB,EAChB,WAAW,EACX,UAAU,GACX,MAAM,SAAS,CAAC;AAEjB,MAAM,CAAC,MAAM,QAAQ,GAAc;IACjC,QAAQ,EAAE;QACR,MAAM,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5B,IAAI,EAAE,MAAM,CAAC,MAAM;QACnB,YAAY,EAAE,MAAM,CAAC,MAAM;QAC3B,UAAU,EAAE,MAAM,CAAC,OAAO;QAC1B,MAAM,EAAE,QAAQ,CAAC,SAAS;KAC3B;IACD,SAAS,EAAE;QACT,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;QAClB,eAAe,EAAE,CAAC;QAClB,eAAe,EAAE,EAAE;QACnB,SAAS,EAAE,EAAE;QACb,IAAI,EAAE,MAAM,CAAC,MAAM;QACnB,UAAU,EAAE,IAAI,UAAU,EAAE;KAC7B;IACD,QAAQ,EAAE,CAAC;IACX,QAAQ,EAAE,GAAG;IACb,0BAA0B,EAAE,KAAK;CAClC,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAc;IACvC,QAAQ,EAAE;QACR,MAAM,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5B,IAAI,EAAE,MAAM,CAAC,MAAM;QACnB,YAAY,EAAE,MAAM,CAAC,MAAM;QAC3B,UAAU,EAAE,MAAM,CAAC,OAAO;QAC1B,MAAM,EAAE,QAAQ,CAAC,SAAS;KAC3B;IACD,SAAS,EAAE;QACT,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;QAClB,eAAe,EAAE,CAAC;QAClB,eAAe,EAAE,CAAC;QAClB,SAAS,EAAE,EAAE;QACb,IAAI,EAAE,MAAM,CAAC,MAAM;QACnB,UAAU,EAAE,IAAI,UAAU,EAAE;KAC7B;IACD,QAAQ,EAAE,CAAC;IACX,QAAQ,EAAE,GAAG;IACb,0BAA0B,EAAE,KAAK;CAClC,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAAc;IAChC,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAC,MAAM;QACnB,UAAU,EAAE,MAAM,CAAC,MAAM;QACzB,YAAY,EAAE,MAAM,CAAC,MAAM;QAC3B,MAAM,EAAE,QAAQ,CAAC,SAAS;QAC1B,MAAM,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;KAC7B;IACD,SAAS,EAAE;QACT,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;QAClB,SAAS,EAAE,EAAE;QACb,eAAe,EAAE,CAAC;QAClB,eAAe,EAAE,CAAC;QAClB,UAAU,EAAE,IAAI,UAAU,CAAC,EAAE,CAAC;QAC9B,IAAI,EAAE,MAAM,CAAC,MAAM;KACpB;IACD,QAAQ,EAAE,GAAG;IACb,QAAQ,EAAE,CAAC;IACX,0BAA0B,EAAE,IAAI;CACjC,CAAC;AAIF,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,IAAe,EACf,GAAe;IAEf,IAAI,CAAC,IAAI,CAAC,0BAA0B,EAAE,CAAC;QACrC,OAAO,GAAG,CAAC;IACb,CAAC;IAED,OAAO,MAAM,CAAC,IAAI,CAAC,QAAS,CAAC,UAAW,EAAE,GAAG,CAAC,CAAC;AACjD,CAAC;AAED,mFAAmF;AACnF,oCAAoC;AACpC,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,KAAqB,EACrB,IAAe,EACf,IAAoB,EACpB,GAAe,EACf,KAAiB;IAEjB,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IACxB,MAAM,IAAI,GAAG,MAAM,sBAAsB,CAAC,KAAK,CAAC,CAAC;IACjD,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC7B,gBAAgB,CAAC,GAAG,EAAE,KAAK,CAAC,GAAI,CAAC,CAAC;IAClC,gBAAgB,CAAC,KAAK,EAAE,KAAK,CAAC,KAAM,CAAC,CAAC;AACxC,CAAC;AAED,6EAA6E;AAC7E,+DAA+D;AAC/D,yCAAyC;AACzC,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,KAAwB,EACxB,IAAe,EACf,IAAoB,EACpB,GAAe;IAEf,IAAI,OAA+B,CAAC;IACpC,IAAI,QAAgC,CAAC;IAErC,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;QACf,MAAM,eAAe,CACnB,KAAK,CAAC,IAAI,EACV,IAAI,EACJ,IAAI,EACJ,KAAK,CAAC,IAAI,CAAC,GAAI,EACf,KAAK,CAAC,IAAI,CAAC,KAAM,CAClB,CAAC;QACF,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,GAAI,CAAC;IAC5B,CAAC;IACD,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,MAAM,eAAe,CACnB,KAAK,CAAC,KAAK,EACX,IAAI,EACJ,IAAI,EACJ,KAAK,CAAC,KAAK,CAAC,GAAI,EAChB,KAAK,CAAC,KAAK,CAAC,KAAM,CACnB,CAAC;QACF,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,GAAI,CAAC;IAC9B,CAAC;IAED,IAAI,CAAC,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;IAC1D,CAAC;IAED,IAAI,OAAO,EAAE,CAAC;QACZ,iBAAiB,CACf,MAAM,gBAAgB,CAAC,IAAI,EAAE,OAAO,CAAC,EACrC,MAAM,gBAAgB,CAAC,IAAI,EAAE,GAAG,CAAC,CAClC,CAAC;IACJ,CAAC;IACD,IAAI,QAAQ,EAAE,CAAC;QACb,iBAAiB,CACf,MAAM,gBAAgB,CAAC,IAAI,EAAE,GAAG,CAAC,EACjC,MAAM,gBAAgB,CAAC,IAAI,EAAE,QAAQ,CAAC,CACvC,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;IACnC,CAAC;IACD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,cAAc,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,KAAM,CAAC,IAAK,CAAC,CAAC;IACrD,CAAC;SAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;QACrB,eAAe,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,IAAK,CAAC,IAAK,CAAC,CAAC;IACrD,CAAC;SAAM,CAAC;QACN,kBAAkB,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,IAAK,CAAC,IAAK,EAAE,KAAK,CAAC,KAAM,CAAC,IAAK,CAAC,CAAC;IAC5E,CAAC;IACD,OAAO;AACT,CAAC;AAED,mEAAmE;AACnE,6DAA6D;AAC7D,yDAAyD;AACzD,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,KAAqB;IAErB,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC7D,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACtE,CAAC;IACD,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC;IAE9B,IAAI,GAAG,GAAG,MAAM,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;IAC9D,KAAK,MAAM,KAAK,IAAI,IAAI,EAAE,CAAC;QACzB,GAAG,GAAG,MAAM,UAAU,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACrC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,UAAU,CAAC,KAAqB,EAAE,IAAe;IAC/D,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACtE,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAChD,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IACjD,CAAC;IACD,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;IAEtC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC;IAC9B,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QACjD,MAAM,IAAI,KAAK,CAAC,uBAAuB,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IACxD,CAAC;IACD,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QACjD,MAAM,IAAI,KAAK,CAAC,wBAAwB,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IACzD,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,IAAI,EAAE,CAAC;QACzB,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IAC3D,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,IAAe,EAAE,IAAwB;IAC/D,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAE7D,mEAAmE;IACnE,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;QACxB,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,CAAC;YACpD,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,IAAe,EAAE,IAAwB;IAChE,MAAM,GAAG,GAAG,IAAI,CAAC,UAAW,CAAC,MAAM,GAAG,CAAC,CAAC;IACxC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAE/D,mEAAmE;IACnE,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;QACxB,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,CAAC;YACpD,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,IAAe,EACf,IAAwB,EACxB,KAAyB;IAEzB,MAAM,OAAO,GAAc,CAAC,GAAG,IAAI,CAAC,CAAC;IACrC,MAAM,QAAQ,GAAc,CAAC,GAAG,KAAK,CAAC,CAAC;IAEvC,IAAI,OAAO,GAAG,OAAO,CAAC,GAAG,EAAG,CAAC;IAC7B,IAAI,QAAQ,GAAG,QAAQ,CAAC,GAAG,EAAG,CAAC;IAC/B,OACE,UAAU,CAAC,OAAO,CAAC,MAAO,EAAE,QAAQ,CAAC,MAAO,CAAC;QAC7C,UAAU,CAAC,OAAO,CAAC,MAAO,EAAE,QAAQ,CAAC,MAAO,CAAC,EAC7C,CAAC;QACD,OAAO,GAAG,OAAO,CAAC,GAAG,EAAG,CAAC;QACzB,QAAQ,GAAG,QAAQ,CAAC,GAAG,EAAG,CAAC;IAC7B,CAAC;IAED,yDAAyD;IACzD,kDAAkD;IAClD,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,CAAC;QACzC,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAChE,CAAC;IAED,yEAAyE;IACzE,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC/B,cAAc,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AACjC,CAAC;AAED,wDAAwD;AACxD,0DAA0D;AAC1D,SAAS,UAAU,CAAC,IAAe,EAAE,IAAa,EAAE,KAAc;IAChE,MAAM,OAAO,GAAG,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC7C,MAAM,QAAQ,GAAG,gBAAgB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC/C,OAAO,QAAQ,KAAK,OAAO,GAAG,CAAC,CAAC;AAClC,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAe,EAAE,KAAc;IACvD,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC,UAAW,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC;QAChE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAClE,IAAI,UAAU,CAAC,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,CAAC;YACpD,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;AACjE,CAAC;AAED,SAAS,UAAU,CACjB,EAAW,EACX,SAAiB,EACjB,SAAiB,EACjB,MAAc;IAEd,IAAI,CAAC,EAAE,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,MAAM,GAAG,SAAS,EAAE,CAAC;QACzC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,CAAC,EAAE,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,MAAM,GAAG,SAAS,EAAE,CAAC;QACzC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,CAAC,EAAE,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC;AAC7C,CAAC;AAOD,SAAS,UAAU,CAAC,IAAe,EAAE,MAAc;IACjD,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,UAAW,EAAE,MAAM,CAAC,CAAC;IAElD,4CAA4C;IAC5C,MAAM,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,SAAU,CAAC;IACrC,MAAM,SAAS,GAAG,MAAM,GAAG,IAAI,CAAC,eAAgB,CAAC;IACjD,MAAM,SAAS,GAAG,MAAM,GAAG,IAAI,CAAC,eAAgB,CAAC;IAEjD,4CAA4C;IAC5C,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,UAAW,CAAC,MAAM,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,SAAU,CAAC;IACrE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;AAC1C,CAAC;AAED,SAAS,WAAW,CAAC,KAAwB,EAAE,MAAc;IAC3D,IAAI,MAAM,GAAG,CAAC,IAAI,MAAM,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QACzC,MAAM,IAAI,KAAK,CAAC,mBAAmB,MAAM,EAAE,CAAC,CAAC;IAC/C,CAAC;IACD,OAAO,KAAK,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,MAAM,CAAC,CAAC;AAClD,CAAC"}
|