@@ -30,7 +30,7 @@ pragma solidity ^0.8.4;
3030 *
3131 * uintTreaple.getRoot();
3232 *
33- * CartesianMerkleTree.Proof memory proof = uintTreaple.getProof(100);
33+ * CartesianMerkleTree.Proof memory proof = uintTreaple.getProof(100, 0 );
3434 *
3535 * uintTreaple.getNodeByKey(100);
3636 *
@@ -590,6 +590,7 @@ library CartesianMerkleTree {
590590 * @param root The root hash of the Cartesian Merkle tree.
591591 * @param siblings An array of sibling hashes can be used to get the Cartesian Merkle Root.
592592 * @param siblingsLength The number of siblings to be used for evidence.
593+ * @param directionBits A path from the root to the node.
593594 * @param existence Indicates the presence (true) or absence (false) of the node.
594595 * @param key The key associated with the node.
595596 * @param nonExistenceKey The non-existence key of the auxiliary node in case when existence is false.
@@ -598,6 +599,7 @@ library CartesianMerkleTree {
598599 bytes32 root;
599600 bytes32 [] siblings;
600601 uint256 siblingsLength;
602+ uint256 directionBits;
601603 bool existence;
602604 bytes32 key;
603605 bytes32 nonExistenceKey;
@@ -775,6 +777,7 @@ library CartesianMerkleTree {
775777 root: _rootMerkleHash (treaple),
776778 siblings: new bytes32 [](desiredProofSize_),
777779 siblingsLength: 0 ,
780+ directionBits: 0 ,
778781 existence: false ,
779782 key: key_,
780783 nonExistenceKey: ZERO_HASH
@@ -787,20 +790,23 @@ library CartesianMerkleTree {
787790 Node storage node;
788791 uint256 currentSiblingsIndex_;
789792 uint256 nextNodeId_ = treaple.merkleRootId;
793+ uint256 directionBits_;
790794
791795 while (true ) {
792796 node = treaple.nodes[uint64 (nextNodeId_)];
793797
794798 if (node.key == key_) {
795- _addProofSibling (
796- proof_,
797- currentSiblingsIndex_++ ,
798- treaple.nodes[node.childLeft].merkleHash
799- );
800- _addProofSibling (
801- proof_,
802- currentSiblingsIndex_++ ,
803- treaple.nodes[node.childRight].merkleHash
799+ bytes32 leftHash_ = treaple.nodes[node.childLeft].merkleHash;
800+ bytes32 rightHash_ = treaple.nodes[node.childRight].merkleHash;
801+
802+ _addProofSibling (proof_, currentSiblingsIndex_++ , leftHash_);
803+ _addProofSibling (proof_, currentSiblingsIndex_++ , rightHash_);
804+
805+ proof_.directionBits = _calculateDirectionBit (
806+ directionBits_,
807+ currentSiblingsIndex_,
808+ leftHash_,
809+ rightHash_
804810 );
805811
806812 proof_.existence = true ;
@@ -820,15 +826,17 @@ library CartesianMerkleTree {
820826 }
821827
822828 if (nextNodeId_ == 0 ) {
823- _addProofSibling (
824- proof_,
825- currentSiblingsIndex_++ ,
826- treaple.nodes[node.childLeft].merkleHash
827- );
828- _addProofSibling (
829- proof_,
830- currentSiblingsIndex_++ ,
831- treaple.nodes[node.childRight].merkleHash
829+ bytes32 leftHash_ = treaple.nodes[node.childLeft].merkleHash;
830+ bytes32 rightHash_ = treaple.nodes[node.childRight].merkleHash;
831+
832+ _addProofSibling (proof_, currentSiblingsIndex_++ , leftHash_);
833+ _addProofSibling (proof_, currentSiblingsIndex_++ , rightHash_);
834+
835+ proof_.directionBits = _calculateDirectionBit (
836+ directionBits_,
837+ currentSiblingsIndex_,
838+ leftHash_,
839+ rightHash_
832840 );
833841
834842 proof_.nonExistenceKey = node.key;
@@ -843,6 +851,13 @@ library CartesianMerkleTree {
843851 currentSiblingsIndex_++ ,
844852 treaple.nodes[otherNodeId_].merkleHash
845853 );
854+
855+ directionBits_ = _calculateDirectionBit (
856+ directionBits_,
857+ currentSiblingsIndex_,
858+ treaple.nodes[uint64 (nextNodeId_)].merkleHash,
859+ treaple.nodes[otherNodeId_].merkleHash
860+ );
846861 }
847862
848863 return proof_;
@@ -875,6 +890,23 @@ library CartesianMerkleTree {
875890 proof_.siblings[currentSiblingsIndex_] = siblingToAdd_;
876891 }
877892
893+ function _calculateDirectionBit (
894+ uint256 directionBits_ ,
895+ uint256 currentSiblingsIndex_ ,
896+ bytes32 leftHash_ ,
897+ bytes32 rightHash_
898+ ) private pure returns (uint256 ) {
899+ if (currentSiblingsIndex_ != 2 ) {
900+ directionBits_ <<= 1 ;
901+ }
902+
903+ if (leftHash_ > rightHash_) {
904+ directionBits_ |= 1 ;
905+ }
906+
907+ return directionBits_;
908+ }
909+
878910 function _hashNodes (CMT storage treaple , uint256 nodeId_ ) private view returns (bytes32 ) {
879911 Node storage node = treaple.nodes[uint64 (nodeId_)];
880912
0 commit comments