Skip to content

Commit

Permalink
build(merkle): replace const-hex with hex-literal
Browse files Browse the repository at this point in the history
  • Loading branch information
alexfertel committed May 1, 2024
1 parent c5a9b7f commit ab37411
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 132 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions lib/crypto/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ repository.workspace = true
version = "0.1.0"

[dependencies]
tiny-keccak = { version = "2.0.2", features = ["keccak"] }
mini-alloc.workspace = true
tiny-keccak = { version = "2.0.2", features = ["keccak"] }

[dev-dependencies]
const-hex = { version = "1.11.1", default-features = false }
hex-literal = "0.4.1"
rand = "0.8.5"

[features]
Expand Down
229 changes: 100 additions & 129 deletions lib/crypto/src/merkle/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,17 +66,12 @@ impl Verifier<KeccakBuilder> {
/// # Examples
///
/// ```
/// # use const_hex::FromHex;
/// # use crypto::merkle::Verifier;
/// type Bytes32 = [u8; 32];
/// use crypto::merkle::Verifier;
/// use hex_literal::hex;
///
/// const ROOT: &str = "0x0000000000000000000000000000000000000000000000000000000000000000";
/// const LEAF: &str = "0x0000000000000000000000000000000000000000000000000000000000000000";
/// const PROOF: &str = "0x0000000000000000000000000000000000000000000000000000000000000000";
///
/// let root = Bytes32::from_hex(ROOT).unwrap();
/// let leaf = Bytes32::from_hex(LEAF).unwrap();
/// let proof = Bytes32::from_hex(PROOF).unwrap();
/// let root = hex!("0000000000000000000000000000000000000000000000000000000000000000");
/// let leaf = hex!("0000000000000000000000000000000000000000000000000000000000000000");
/// let proof = hex!("0000000000000000000000000000000000000000000000000000000000000000");
///
/// let verification = Verifier::verify(&[proof], root, leaf);
/// assert!(!verification);
Expand Down Expand Up @@ -135,27 +130,17 @@ impl Verifier<KeccakBuilder> {
///
/// # Examples
///
/// ```
/// # use const_hex::FromHex;
/// # use crypto::merkle::Verifier;
/// type Bytes32 = [u8; 32];
///
/// const ROOT: &str = "0x6deb52b5da8fd108f79fab00341f38d2587896634c646ee52e49f845680a70c8";
/// const LEAVES: &str = "0x19ba6c6333e0e9a15bf67523e0676e2f23eb8e574092552d5e888c64a4bb3681
/// 0xc62a8cfa41edc0ef6f6ae27a2985b7d39c7fea770787d7e104696c6e81f64848
/// 0xeba909cf4bb90c6922771d7f126ad0fd11dfde93f3937a196274e1ac20fd2f5b";
/// const PROOF: &str = "0x9a4f64e953595df82d1b4f570d34c4f4f0cfaf729a61e9d60e83e579e1aa283e
/// 0x8076923e76cf01a7c048400a2304c9a9c23bbbdac3a98ea3946340fdafbba34f";
///
/// let root = Bytes32::from_hex(ROOT).unwrap();
/// let leaves: Vec<_> = LEAVES
/// .lines()
/// .map(|h| Bytes32::from_hex(h.trim()).unwrap())
/// .collect();
/// let proof: Vec<_> = PROOF
/// .lines()
/// .map(|h| Bytes32::from_hex(h.trim()).unwrap())
/// .collect();
/// ```rust
/// use crypto::merkle::Verifier;
/// use hex_literal::hex;
///
/// let root = hex!("6deb52b5da8fd108f79fab00341f38d2587896634c646ee52e49f845680a70c8");
/// let leaves = [hex!("19ba6c6333e0e9a15bf67523e0676e2f23eb8e574092552d5e888c64a4bb3681"),
/// hex!("c62a8cfa41edc0ef6f6ae27a2985b7d39c7fea770787d7e104696c6e81f64848"),
/// hex!("eba909cf4bb90c6922771d7f126ad0fd11dfde93f3937a196274e1ac20fd2f5b")];
/// let proof = [hex!("9a4f64e953595df82d1b4f570d34c4f4f0cfaf729a61e9d60e83e579e1aa283e"),
/// hex!("8076923e76cf01a7c048400a2304c9a9c23bbbdac3a98ea3946340fdafbba34f")];
///
/// let proof_flags = [false, true, false, true];
///
/// let verification =
Expand Down Expand Up @@ -203,17 +188,12 @@ where
/// # Examples
///
/// ```
/// # use const_hex::FromHex;
/// # use crypto::merkle::{KeccakBuilder, Verifier};
/// type Bytes32 = [u8; 32];
/// use crypto::merkle::{KeccakBuilder, Verifier};
/// use hex_literal::hex;
///
/// const ROOT: &str = "0x0000000000000000000000000000000000000000000000000000000000000000";
/// const LEAF: &str = "0x0000000000000000000000000000000000000000000000000000000000000000";
/// const PROOF: &str = "0x0000000000000000000000000000000000000000000000000000000000000000";
///
/// let root = Bytes32::from_hex(ROOT).unwrap();
/// let leaf = Bytes32::from_hex(LEAF).unwrap();
/// let proof = Bytes32::from_hex(PROOF).unwrap();
/// let root = hex!("0000000000000000000000000000000000000000000000000000000000000000");
/// let leaf = hex!("0000000000000000000000000000000000000000000000000000000000000000");
/// let proof = hex!("0000000000000000000000000000000000000000000000000000000000000000");
///
/// let verification = Verifier::verify_with_builder(&[proof], root, leaf, &KeccakBuilder);
/// assert!(!verification);
Expand Down Expand Up @@ -282,27 +262,16 @@ where
///
/// # Examples
///
/// ```
/// # use const_hex::FromHex;
/// # use crypto::merkle::{KeccakBuilder, Verifier};
/// type Bytes32 = [u8; 32];
///
/// const ROOT: &str = "0x6deb52b5da8fd108f79fab00341f38d2587896634c646ee52e49f845680a70c8";
/// const LEAVES: &str = "0x19ba6c6333e0e9a15bf67523e0676e2f23eb8e574092552d5e888c64a4bb3681
/// 0xc62a8cfa41edc0ef6f6ae27a2985b7d39c7fea770787d7e104696c6e81f64848
/// 0xeba909cf4bb90c6922771d7f126ad0fd11dfde93f3937a196274e1ac20fd2f5b";
/// const PROOF: &str = "0x9a4f64e953595df82d1b4f570d34c4f4f0cfaf729a61e9d60e83e579e1aa283e
/// 0x8076923e76cf01a7c048400a2304c9a9c23bbbdac3a98ea3946340fdafbba34f";
///
/// let root = Bytes32::from_hex(ROOT).unwrap();
/// let leaves: Vec<_> = LEAVES
/// .lines()
/// .map(|h| Bytes32::from_hex(h.trim()).unwrap())
/// .collect();
/// let proof: Vec<_> = PROOF
/// .lines()
/// .map(|h| Bytes32::from_hex(h.trim()).unwrap())
/// .collect();
/// ```rust
/// use crypto::merkle::{KeccakBuilder, Verifier};
/// use hex_literal::hex;
///
/// let root = hex!("6deb52b5da8fd108f79fab00341f38d2587896634c646ee52e49f845680a70c8");
/// let leaves = [hex!("19ba6c6333e0e9a15bf67523e0676e2f23eb8e574092552d5e888c64a4bb3681"),
/// hex!("c62a8cfa41edc0ef6f6ae27a2985b7d39c7fea770787d7e104696c6e81f64848"),
/// hex!("eba909cf4bb90c6922771d7f126ad0fd11dfde93f3937a196274e1ac20fd2f5b")];
/// let proof = [hex!("9a4f64e953595df82d1b4f570d34c4f4f0cfaf729a61e9d60e83e579e1aa283e"),
/// hex!("8076923e76cf01a7c048400a2304c9a9c23bbbdac3a98ea3946340fdafbba34f")];
/// let proof_flags = [false, true, false, true];
///
/// let verification =
Expand Down Expand Up @@ -416,27 +385,29 @@ impl Hash for [u8; 64] {
mod tests {
//! NOTE: The values used as input for these tests were all generated using
//! https://github.com/OpenZeppelin/merkle-tree.
use const_hex::FromHex;
use hex_literal::hex;
use rand::{thread_rng, RngCore};

use super::{hash_sorted_pair, Bytes32, KeccakBuilder, Verifier};
use crate::merkle::hash::BuildHasher;

/// Shorthand for converting from a hex str to a fixed 32-bytes array.
macro_rules! hex_to_bytes_32 {
($($var:ident = $bytes:expr);* $(;)?) => {
$(let $var = Bytes32::from_hex($bytes).unwrap();)*
macro_rules! bytes {
($($var:ident = $hex:literal);* $(;)?) => {
$(
#[allow(non_upper_case_globals)]
const $var: Bytes32 = hex!($hex);
)*
};
}

/// Shorthand for converting from a string containing several address to
/// Shorthand for converting from a string containing several addresses to
/// a fixed 32-bytes collection.
macro_rules! str_to_bytes_32 {
($bytes:expr) => {
$bytes
.lines()
.map(|l| Bytes32::from_hex(l.trim()).unwrap())
.collect()
macro_rules! bytes_array {
($($s:literal),* $(,)?) => {
[
$(hex!($s),)*
]
};
}

Expand All @@ -452,18 +423,18 @@ mod tests {
// const hash = merkleTree.leafHash(['A']);
// const proof = merkleTree.getProof(['A']);
// ```
hex_to_bytes_32! {
root = "0xb89eb120147840e813a77109b44063488a346b4ca15686185cf314320560d3f3";
leaf_a = "0x6efbf77e320741a027b50f02224545461f97cd83762d5fbfeb894b9eb3287c16";
leaf_b = "0x7051e21dd45e25ed8c605a53da6f77de151dcbf47b0e3ced3c5d8b61f4a13dbc";
bytes! {
root = "b89eb120147840e813a77109b44063488a346b4ca15686185cf314320560d3f3";
leaf_a = "6efbf77e320741a027b50f02224545461f97cd83762d5fbfeb894b9eb3287c16";
leaf_b = "7051e21dd45e25ed8c605a53da6f77de151dcbf47b0e3ced3c5d8b61f4a13dbc";
};
let proof: Vec<_> = str_to_bytes_32! {
"0x7051e21dd45e25ed8c605a53da6f77de151dcbf47b0e3ced3c5d8b61f4a13dbc
0x1629d3b5b09b30449d258e35bbd09dd5e8a3abb91425ef810dc27eef995f7490
0x633d21baee4bbe5ed5c51ac0c68f7946b8f28d2937f0ca7ef5e1ea9dbda52e7a
0x8a65d3006581737a3bab46d9e4775dbc1821b1ea813d350a13fcd4f15a8942ec
0xd6c3f3e36cd23ba32443f6a687ecea44ebfe2b8759a62cccf7759ec1fb563c76
0x276141cd72b9b81c67f7182ff8a550b76eb96de9248a3ec027ac048c79649115"
let proof = bytes_array! {
"7051e21dd45e25ed8c605a53da6f77de151dcbf47b0e3ced3c5d8b61f4a13dbc",
"1629d3b5b09b30449d258e35bbd09dd5e8a3abb91425ef810dc27eef995f7490",
"633d21baee4bbe5ed5c51ac0c68f7946b8f28d2937f0ca7ef5e1ea9dbda52e7a",
"8a65d3006581737a3bab46d9e4775dbc1821b1ea813d350a13fcd4f15a8942ec",
"d6c3f3e36cd23ba32443f6a687ecea44ebfe2b8759a62cccf7759ec1fb563c76",
"276141cd72b9b81c67f7182ff8a550b76eb96de9248a3ec027ac048c79649115",
};

let verification = Verifier::verify(&proof, root, leaf_a);
Expand All @@ -486,10 +457,10 @@ mod tests {
// const leaf = correctMerkleTree.leafHash(['a']);
// const proof = otherMerkleTree.getProof(['d']);
// ```
hex_to_bytes_32! {
root = "0xf2129b5a697531ef818f644564a6552b35c549722385bc52aa7fe46c0b5f46b1";
leaf = "0x9c15a6a0eaeed500fd9eed4cbeab71f797cefcc67bfd46683e4d2e6ff7f06d1c";
proof = "0x7b0c6cd04b82bfc0e250030a5d2690c52585e0cc6a4f3bc7909d7723b0236ece";
bytes! {
root = "f2129b5a697531ef818f644564a6552b35c549722385bc52aa7fe46c0b5f46b1";
leaf = "9c15a6a0eaeed500fd9eed4cbeab71f797cefcc67bfd46683e4d2e6ff7f06d1c";
proof = "7b0c6cd04b82bfc0e250030a5d2690c52585e0cc6a4f3bc7909d7723b0236ece";
};

let verification = Verifier::verify(&[proof], root, leaf);
Expand All @@ -505,13 +476,13 @@ mod tests {
// const leaf = merkleTree.leafHash(['a']);
// const proof = merkleTree.getProof(['a']);
// ```
hex_to_bytes_32! {
root = "0xf2129b5a697531ef818f644564a6552b35c549722385bc52aa7fe46c0b5f46b1";
leaf = "0x9c15a6a0eaeed500fd9eed4cbeab71f797cefcc67bfd46683e4d2e6ff7f06d1c";
bytes! {
root = "f2129b5a697531ef818f644564a6552b35c549722385bc52aa7fe46c0b5f46b1";
leaf = "9c15a6a0eaeed500fd9eed4cbeab71f797cefcc67bfd46683e4d2e6ff7f06d1c";
};
let proof: Vec<_> = str_to_bytes_32! {
"0x19ba6c6333e0e9a15bf67523e0676e2f23eb8e574092552d5e888c64a4bb3681
0x9cf5a63718145ba968a01c1d557020181c5b252f665cf7386d370eddb176517b"
let proof = bytes_array! {
"19ba6c6333e0e9a15bf67523e0676e2f23eb8e574092552d5e888c64a4bb3681",
"9cf5a63718145ba968a01c1d557020181c5b252f665cf7386d370eddb176517b",
};

let bad_proof = &proof[..1];
Expand All @@ -528,17 +499,17 @@ mod tests {
// const { proof, proofFlags, leaves } = merkleTree.getMultiProof(toElements('bdf'));
// const hashes = leaves.map(e => merkleTree.leafHash(e));
// ```
hex_to_bytes_32! {
root = "0x6deb52b5da8fd108f79fab00341f38d2587896634c646ee52e49f845680a70c8";
bytes! {
root = "6deb52b5da8fd108f79fab00341f38d2587896634c646ee52e49f845680a70c8";
};
let leaves: Vec<_> = str_to_bytes_32! {
"0x19ba6c6333e0e9a15bf67523e0676e2f23eb8e574092552d5e888c64a4bb3681
0xc62a8cfa41edc0ef6f6ae27a2985b7d39c7fea770787d7e104696c6e81f64848
0xeba909cf4bb90c6922771d7f126ad0fd11dfde93f3937a196274e1ac20fd2f5b"
let leaves = bytes_array! {
"19ba6c6333e0e9a15bf67523e0676e2f23eb8e574092552d5e888c64a4bb3681",
"c62a8cfa41edc0ef6f6ae27a2985b7d39c7fea770787d7e104696c6e81f64848",
"eba909cf4bb90c6922771d7f126ad0fd11dfde93f3937a196274e1ac20fd2f5b",
};
let proof: Vec<_> = str_to_bytes_32! {
"0x9a4f64e953595df82d1b4f570d34c4f4f0cfaf729a61e9d60e83e579e1aa283e
0x8076923e76cf01a7c048400a2304c9a9c23bbbdac3a98ea3946340fdafbba34f"
let proof = bytes_array! {
"9a4f64e953595df82d1b4f570d34c4f4f0cfaf729a61e9d60e83e579e1aa283e",
"8076923e76cf01a7c048400a2304c9a9c23bbbdac3a98ea3946340fdafbba34f",
};

let proof_flags = [false, true, false, true];
Expand All @@ -557,13 +528,13 @@ mod tests {
// const { proof, proofFlags, leaves } = otherMerkleTree.getMultiProof(toElements('ghi'));
// const hashes = leaves.map(e => merkleTree.leafHash(e));
// ```
hex_to_bytes_32! {
root = "0x6deb52b5da8fd108f79fab00341f38d2587896634c646ee52e49f845680a70c8";
bytes! {
root = "6deb52b5da8fd108f79fab00341f38d2587896634c646ee52e49f845680a70c8";
};
let leaves: Vec<_> = str_to_bytes_32! {
"0x34e6ce3d0d73f6bff2ee1e865833d58e283570976d70b05f45c989ef651ef742
0xaa28358fb75b314c899e16d7975e029d18b4457fd8fd831f2e6c17ffd17a1d7e
0xe0fd7e6916ff95d933525adae392a17e247819ebecc2e63202dfec7005c60560"
let leaves = bytes_array! {
"34e6ce3d0d73f6bff2ee1e865833d58e283570976d70b05f45c989ef651ef742",
"aa28358fb75b314c899e16d7975e029d18b4457fd8fd831f2e6c17ffd17a1d7e",
"e0fd7e6916ff95d933525adae392a17e247819ebecc2e63202dfec7005c60560",
};
let proof = [];
let proof_flags = [true, true];
Expand All @@ -588,12 +559,12 @@ mod tests {
// const hashE = merkleTree.leafHash(['e']); // incorrect (not part of the tree)
// const fill = ethers.randomBytes(32);
// ```
hex_to_bytes_32! {
root = "0x8f7234e8cfe39c08ca84a3a3e3274f574af26fd15165fe29e09cbab742daccd9";
hash_a = "0x9c15a6a0eaeed500fd9eed4cbeab71f797cefcc67bfd46683e4d2e6ff7f06d1c";
hash_b = "0x19ba6c6333e0e9a15bf67523e0676e2f23eb8e574092552d5e888c64a4bb3681";
hash_cd = "0x03707d7802a71ca56a8ad8028da98c4f1dbec55b31b4a25d536b5309cc20eda9";
hash_e = "0x9a4f64e953595df82d1b4f570d34c4f4f0cfaf729a61e9d60e83e579e1aa283e";
bytes! {
root = "8f7234e8cfe39c08ca84a3a3e3274f574af26fd15165fe29e09cbab742daccd9";
hash_a = "9c15a6a0eaeed500fd9eed4cbeab71f797cefcc67bfd46683e4d2e6ff7f06d1c";
hash_b = "19ba6c6333e0e9a15bf67523e0676e2f23eb8e574092552d5e888c64a4bb3681";
hash_cd = "03707d7802a71ca56a8ad8028da98c4f1dbec55b31b4a25d536b5309cc20eda9";
hash_e = "9a4f64e953595df82d1b4f570d34c4f4f0cfaf729a61e9d60e83e579e1aa283e";
};

let mut random_bytes = [0u8; 32];
Expand Down Expand Up @@ -624,12 +595,12 @@ mod tests {
// const hashE = merkleTree.leafHash(['e']); // incorrect (not part of the tree)
// const fill = ethers.randomBytes(32);
// ```
hex_to_bytes_32! {
root = "0x8f7234e8cfe39c08ca84a3a3e3274f574af26fd15165fe29e09cbab742daccd9";
hash_a = "0x9c15a6a0eaeed500fd9eed4cbeab71f797cefcc67bfd46683e4d2e6ff7f06d1c";
hash_b = "0x19ba6c6333e0e9a15bf67523e0676e2f23eb8e574092552d5e888c64a4bb3681";
hash_cd = "0x03707d7802a71ca56a8ad8028da98c4f1dbec55b31b4a25d536b5309cc20eda9";
hash_e = "0x9a4f64e953595df82d1b4f570d34c4f4f0cfaf729a61e9d60e83e579e1aa283e";
bytes! {
root = "8f7234e8cfe39c08ca84a3a3e3274f574af26fd15165fe29e09cbab742daccd9";
hash_a = "9c15a6a0eaeed500fd9eed4cbeab71f797cefcc67bfd46683e4d2e6ff7f06d1c";
hash_b = "19ba6c6333e0e9a15bf67523e0676e2f23eb8e574092552d5e888c64a4bb3681";
hash_cd = "03707d7802a71ca56a8ad8028da98c4f1dbec55b31b4a25d536b5309cc20eda9";
hash_e = "9a4f64e953595df82d1b4f570d34c4f4f0cfaf729a61e9d60e83e579e1aa283e";
};

let mut random_bytes = [0u8; 32];
Expand All @@ -654,7 +625,7 @@ mod tests {
// const { proof, proofFlags, leaves } = merkleTree.getMultiProof(toElements('a'));
// const hashes = leaves.map(e => merkleTree.leafHash(e));
// ```
hex_to_bytes_32!(root = "0x9c15a6a0eaeed500fd9eed4cbeab71f797cefcc67bfd46683e4d2e6ff7f06d1c");
bytes!(root = "9c15a6a0eaeed500fd9eed4cbeab71f797cefcc67bfd46683e4d2e6ff7f06d1c");
let proof = [];
let proof_flags = [];
let leaves = [root];
Expand All @@ -675,7 +646,7 @@ mod tests {
//
// const root = merkleTree.root;
// ```
hex_to_bytes_32!(root = "0x8f7234e8cfe39c08ca84a3a3e3274f574af26fd15165fe29e09cbab742daccd9");
bytes!(root = "8f7234e8cfe39c08ca84a3a3e3274f574af26fd15165fe29e09cbab742daccd9");
let proof = [root];
let proof_flags = [];
let leaves = [];
Expand All @@ -700,13 +671,13 @@ mod tests {
// const maliciousProof = [leave, leave];
// const maliciousProofFlags = [true, true, false];
// ```
hex_to_bytes_32! {
root = "0xf2d552e1e4c59d4f0fa2b80859febc9e4bdc915dff37c56c858550d8b64659a5";
leaf = "0x5e941ddd8f313c0b39f92562c0eca709c3d91360965d396aaef584b3fa76889a";
bytes! {
root = "f2d552e1e4c59d4f0fa2b80859febc9e4bdc915dff37c56c858550d8b64659a5";
leaf = "5e941ddd8f313c0b39f92562c0eca709c3d91360965d396aaef584b3fa76889a";
};
let malicious_leaves: Vec<_> = str_to_bytes_32! {
"0x1f23ad5fc0ee6ccbe2f3d30df856758f05ad9d03408a51a99c1c9f0854309db2
0x613994f4e324d0667c07857cd5d147994bc917da5d07ee63fc3f0a1fe8a18e34"
let malicious_leaves = bytes_array! {
"1f23ad5fc0ee6ccbe2f3d30df856758f05ad9d03408a51a99c1c9f0854309db2",
"613994f4e324d0667c07857cd5d147994bc917da5d07ee63fc3f0a1fe8a18e34",
};
let malicious_proof = [leaf, leaf];
let malicious_proof_flags = [true, true, false];
Expand Down

0 comments on commit ab37411

Please sign in to comment.