@@ -64,6 +64,56 @@ library PartialMerkleTree {
6464 tree.rootEdge = e;
6565 }
6666
67+ function commitBranchOfNonInclusion (
68+ Tree storage tree ,
69+ bytes key ,
70+ bytes32 potentialSiblingLabel ,
71+ bytes32 potentialSiblingValue ,
72+ uint branchMask ,
73+ bytes32 [] siblings
74+ ) internal {
75+ D.Label memory k = D.Label (keccak256 (key), 256 );
76+ D.Edge memory e;
77+ // e.node(0x083d)
78+ for (uint i = 0 ; branchMask != 0 ; i++ ) {
79+ // retrieve edge data with branch mask
80+ uint bitSet = Utils.lowestBitSet (branchMask);
81+ branchMask &= ~ (uint (1 ) << bitSet);
82+ (k, e.label) = Utils.splitAt (k, 255 - bitSet);
83+ uint bit;
84+ (bit, e.label) = Utils.chopFirstBit (e.label);
85+
86+ if (i == 0 ) {
87+ e.label.length = bitSet;
88+ e.label.data = potentialSiblingLabel;
89+ e.node = potentialSiblingValue;
90+ }
91+
92+ // find upper node with retrieved edge & sibling
93+ bytes32 [2 ] memory edgeHashes;
94+ edgeHashes[bit] = edgeHash (e);
95+ edgeHashes[1 - bit] = siblings[siblings.length - i - 1 ];
96+ bytes32 upperNode = keccak256 (abi.encode (edgeHashes[0 ], edgeHashes[1 ]));
97+
98+ // Update sibling information
99+ D.Node storage parentNode = tree.nodes[upperNode];
100+
101+
102+ // Put edge
103+ parentNode.children[bit] = e;
104+ // Put sibling edge if needed
105+ if (parentNode.children[1 - bit].isEmpty ()) {
106+ parentNode.children[1 - bit].header = siblings[siblings.length - i - 1 ];
107+ }
108+ // go to upper edge
109+ e.node = keccak256 (abi.encode (edgeHashes[0 ], edgeHashes[1 ]));
110+ }
111+ e.label = k;
112+ require (tree.root == edgeHash (e));
113+ tree.root = edgeHash (e);
114+ tree.rootEdge = e;
115+ }
116+
67117 function insert (Tree storage tree , bytes key , bytes value ) internal {
68118 D.Label memory k = D.Label (keccak256 (key), 256 );
69119 bytes32 valueHash = keccak256 (value);
@@ -164,6 +214,54 @@ library PartialMerkleTree {
164214 }
165215 }
166216
217+ function getNonInclusionProof (Tree storage tree , bytes key ) internal view returns (
218+ bytes32 potentialSiblingLabel ,
219+ bytes32 potentialSiblingValue ,
220+ uint branchMask ,
221+ bytes32 [] _siblings
222+ ){
223+ uint length;
224+ uint numSiblings;
225+
226+ // Start from root edge
227+ D.Label memory label = D.Label (keccak256 (key), 256 );
228+ D.Edge memory e = tree.rootEdge;
229+ bytes32 [256 ] memory siblings;
230+
231+ while (true ) {
232+ // Find at edge
233+ require (label.length >= e.label.length );
234+ D.Label memory prefix;
235+ D.Label memory suffix;
236+ (prefix, suffix) = Utils.splitCommonPrefix (label, e.label);
237+
238+ // suffix.length == 0 means that the key exists. Thus the length of the suffix should be not zero
239+ require (suffix.length != 0 );
240+
241+ if (prefix.length >= e.label.length ) {
242+ // Partial matched, keep finding
243+ length += prefix.length ;
244+ branchMask |= uint (1 ) << (255 - length);
245+ length += 1 ;
246+ uint head;
247+ (head, label) = Utils.chopFirstBit (suffix);
248+ siblings[numSiblings++ ] = edgeHash (tree.nodes[e.node].children[1 - head]);
249+ e = tree.nodes[e.node].children[head];
250+ } else {
251+ // Found the potential sibling. Set data to return
252+ potentialSiblingLabel = e.label.data;
253+ potentialSiblingValue = e.node;
254+ break ;
255+ }
256+ }
257+ if (numSiblings > 0 )
258+ {
259+ _siblings = new bytes32 [](numSiblings);
260+ for (uint i = 0 ; i < numSiblings; i++ )
261+ _siblings[i] = siblings[i];
262+ }
263+ }
264+
167265 function verifyProof (bytes32 rootHash , bytes key , bytes value , uint branchMask , bytes32 [] siblings ) public pure {
168266 D.Label memory k = D.Label (keccak256 (key), 256 );
169267 D.Edge memory e;
@@ -183,6 +281,29 @@ library PartialMerkleTree {
183281 require (rootHash == edgeHash (e));
184282 }
185283
284+ function verifyNonInclusionProof (bytes32 rootHash , bytes key , bytes32 potentialSiblingLabel , bytes32 potentialSiblingValue , uint branchMask , bytes32 [] siblings ) public pure {
285+ D.Label memory k = D.Label (keccak256 (key), 256 );
286+ D.Edge memory e;
287+ for (uint i = 0 ; branchMask != 0 ; i++ ) {
288+ uint bitSet = Utils.lowestBitSet (branchMask);
289+ branchMask &= ~ (uint (1 ) << bitSet);
290+ (k, e.label) = Utils.splitAt (k, 255 - bitSet);
291+ uint bit;
292+ (bit, e.label) = Utils.chopFirstBit (e.label);
293+ bytes32 [2 ] memory edgeHashes;
294+ if (i == 0 ) {
295+ e.label.length = bitSet;
296+ e.label.data = potentialSiblingLabel;
297+ e.node = potentialSiblingValue;
298+ }
299+ edgeHashes[bit] = edgeHash (e);
300+ edgeHashes[1 - bit] = siblings[siblings.length - i - 1 ];
301+ e.node = keccak256 (abi.encode (edgeHashes[0 ], edgeHashes[1 ]));
302+ }
303+ e.label = k;
304+ require (rootHash == edgeHash (e));
305+ }
306+
186307 function newEdge (bytes32 node , D.Label label ) internal pure returns (D.Edge memory e ){
187308 e.node = node;
188309 e.label = label;
0 commit comments