@@ -6,6 +6,18 @@ pragma solidity ^0.8.28;
66 * Provides functions for processing and verifying Merkle tree proofs
77 */
88library TxMerkleProof {
9+ /**
10+ * @notice Possible directions for hashing:
11+ * - Left: computed hash is on the left, sibling hash is on the right.
12+ * - Right: computed hash is on the right, sibling hash is on the left.
13+ * - Self: node has no sibling and is hashed with itself.
14+ * */
15+ enum HashDirection {
16+ Left,
17+ Right,
18+ Self
19+ }
20+
921 /**
1022 * @notice Emitted when the proof and directions array are of different length.
1123 * This error ensures that only correctly sized proofs are processed
@@ -15,13 +27,13 @@ library TxMerkleProof {
1527 /**
1628 * @notice Returns true if `leaf_` can be proven to be part of a Merkle tree
1729 * defined by `root_`. Requires a `proof_` containing the sibling hashes along
18- * the path from the leaf to the root. Each byte of `directions_` indicates
30+ * the path from the leaf to the root. Each element of `directions_` indicates
1931 * the hashing order for each pair.
2032 * Uses double SHA-256 hashing.
2133 */
2234 function verify (
23- bytes32 [] memory proof_ ,
24- bytes calldata directions_ ,
35+ bytes32 [] calldata proof_ ,
36+ HashDirection[] calldata directions_ ,
2537 bytes32 root_ ,
2638 bytes32 leaf_
2739 ) internal pure returns (bool ) {
@@ -34,31 +46,31 @@ library TxMerkleProof {
3446 * @notice Returns the rebuilt hash obtained by traversing the Merkle tree
3547 * from `leaf_` using `proof_`. A `proof_` is valid if and only if the rebuilt
3648 * hash matches the given tree root. The pre-images are hashed in the order
37- * specified by the `directions_` bytes .
49+ * specified by the `directions_` elements .
3850 * Uses double SHA-256 hashing.
3951 */
4052 function processProof (
41- bytes32 [] memory proof_ ,
42- bytes calldata directions_ ,
53+ bytes32 [] calldata proof_ ,
54+ HashDirection[] calldata directions_ ,
4355 bytes32 leaf_
4456 ) internal pure returns (bytes32 ) {
4557 bytes32 computedHash_ = leaf_;
4658 uint256 proofLength_ = proof_.length ;
4759
4860 for (uint256 i = 0 ; i < proofLength_; ++ i) {
49- if (directions_[i] == hex " 00 " ) {
50- computedHash_ = _sha256 (computedHash_, proof_[i]);
51- } else if (directions_[i] == hex " 01 " ) {
52- computedHash_ = _sha256 (proof_[i], computedHash_);
61+ if (directions_[i] == HashDirection.Left ) {
62+ computedHash_ = _doubleSHA256 (computedHash_, proof_[i]);
63+ } else if (directions_[i] == HashDirection.Right ) {
64+ computedHash_ = _doubleSHA256 (proof_[i], computedHash_);
5365 } else {
54- computedHash_ = _sha256 (computedHash_, computedHash_);
66+ computedHash_ = _doubleSHA256 (computedHash_, computedHash_);
5567 }
5668 }
5769
5870 return computedHash_;
5971 }
6072
61- function _sha256 (bytes32 left_ , bytes32 right_ ) private pure returns (bytes32 ) {
73+ function _doubleSHA256 (bytes32 left_ , bytes32 right_ ) private pure returns (bytes32 ) {
6274 return sha256 (abi.encodePacked (sha256 (abi.encodePacked (left_, right_))));
6375 }
6476}
0 commit comments