Skip to content

Commit 97aba26

Browse files
authored
Added directionBits to CMT proof (#129)
* Added directionBits to CMT proof * review fixes * review fixes in test * U512 lib: switched function from internal to private * updated version and lock file
1 parent 6c2955d commit 97aba26

File tree

5 files changed

+752
-432
lines changed

5 files changed

+752
-432
lines changed

contracts/libs/bn/U512.sol

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1708,7 +1708,7 @@ library U512 {
17081708
* @dev The modulus `m_` must be a prime number.
17091709
* @dev Computes `(a_ * b_^(-1)) % m_` and stores the result in `r_`.
17101710
*/
1711-
function _moddiv(call512 call_, uint512 a_, uint512 b_, uint512 m_, uint512 r_) internal view {
1711+
function _moddiv(call512 call_, uint512 a_, uint512 b_, uint512 m_, uint512 r_) private view {
17121712
unchecked {
17131713
uint512 buffer_ = _buffer(call_);
17141714

@@ -1732,7 +1732,7 @@ library U512 {
17321732
* @notice Performs bitwise AND of two 512-bit unsigned integers.
17331733
* @dev Computes `a_ & b_` and stores the result in `r_`.
17341734
*/
1735-
function _and(uint512 a_, uint512 b_, uint512 r_) internal pure {
1735+
function _and(uint512 a_, uint512 b_, uint512 r_) private pure {
17361736
unchecked {
17371737
assembly {
17381738
mstore(r_, and(mload(a_), mload(b_)))
@@ -1745,7 +1745,7 @@ library U512 {
17451745
* @notice Performs bitwise OR of two 512-bit unsigned integers.
17461746
* @dev Computes `a_ | b_` and stores the result in `r_`.
17471747
*/
1748-
function _or(uint512 a_, uint512 b_, uint512 r_) internal pure {
1748+
function _or(uint512 a_, uint512 b_, uint512 r_) private pure {
17491749
unchecked {
17501750
assembly {
17511751
mstore(r_, or(mload(a_), mload(b_)))
@@ -1758,7 +1758,7 @@ library U512 {
17581758
* @notice Performs bitwise XOR of two 512-bit unsigned integers.
17591759
* @dev Computes `a_ ^ b_` and stores the result in `r_`.
17601760
*/
1761-
function _xor(uint512 a_, uint512 b_, uint512 r_) internal pure {
1761+
function _xor(uint512 a_, uint512 b_, uint512 r_) private pure {
17621762
unchecked {
17631763
assembly {
17641764
mstore(r_, xor(mload(a_), mload(b_)))
@@ -1771,7 +1771,7 @@ library U512 {
17711771
* @notice Performs bitwise NOT of a 512-bit unsigned integer.
17721772
* @dev Computes `~a_` and stores the result in `r_`.
17731773
*/
1774-
function _not(uint512 a_, uint512 r_) internal pure {
1774+
function _not(uint512 a_, uint512 r_) private pure {
17751775
unchecked {
17761776
assembly {
17771777
mstore(r_, not(mload(a_)))
@@ -1784,7 +1784,7 @@ library U512 {
17841784
* @notice Performs left shift of a 512-bit unsigned integer.
17851785
* @dev Computes `a_ << b_` and stores the result in `r_`.
17861786
*/
1787-
function _shl(uint512 a_, uint8 b_, uint512 r_) internal pure {
1787+
function _shl(uint512 a_, uint8 b_, uint512 r_) private pure {
17881788
unchecked {
17891789
assembly {
17901790
mstore(r_, or(shl(b_, mload(a_)), shr(sub(256, b_), mload(add(a_, 0x20)))))
@@ -1797,7 +1797,7 @@ library U512 {
17971797
* @notice Performs right shift of a 512-bit unsigned integer.
17981798
* @dev Computes `a_ >> b_` and stores the result in `r_`.
17991799
*/
1800-
function _shr(uint512 a_, uint8 b_, uint512 r_) internal pure {
1800+
function _shr(uint512 a_, uint8 b_, uint512 r_) private pure {
18011801
unchecked {
18021802
assembly {
18031803
mstore(

contracts/libs/data-structures/CartesianMerkleTree.sol

Lines changed: 51 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)