Conversation
There was a problem hiding this comment.
Code Review
This pull request updates the sparse-Merkle-tree inclusion path verification to incorporate canonical radix regions (prefix_region) when hashing internal nodes, aligning with the RSMT v6a specification. It also updates integration tests to reject pre-v6a multi-leaf fixtures while verifying single-leaf fixtures. Feedback was provided on src/radix.rs to add an assertion in prefix_region ensuring depth does not exceed 256, preventing potential out-of-bounds panics.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| pub(crate) fn prefix_region(key: &[u8; 32], depth: usize) -> [u8; 32] { | ||
| let mut region = [0u8; 32]; | ||
| let full_bytes = depth / 8; | ||
| let partial_bits = depth % 8; | ||
|
|
||
| region[..full_bytes].copy_from_slice(&key[..full_bytes]); | ||
| if partial_bits != 0 { | ||
| let mask = (1u8 << partial_bits) - 1; | ||
| region[full_bytes] = key[full_bytes] & mask; | ||
| } | ||
|
|
||
| region | ||
| } |
There was a problem hiding this comment.
The prefix_region function takes depth: usize and performs indexing on a 32-byte array ([u8; 32]). If depth is greater than 256, full_bytes will be greater than or equal to 32, which will cause a panic due to out-of-bounds slicing (region[..full_bytes]) or out-of-bounds indexing (region[full_bytes]).
While the current caller in verify bounds depth to MAX_DEPTH (255), as a general pub(crate) helper function, it is safer and more robust to add an assertion to prevent potential panic-based DoS or unexpected out-of-bounds panics if it is ever called with larger depths in the future.
| pub(crate) fn prefix_region(key: &[u8; 32], depth: usize) -> [u8; 32] { | |
| let mut region = [0u8; 32]; | |
| let full_bytes = depth / 8; | |
| let partial_bits = depth % 8; | |
| region[..full_bytes].copy_from_slice(&key[..full_bytes]); | |
| if partial_bits != 0 { | |
| let mask = (1u8 << partial_bits) - 1; | |
| region[full_bytes] = key[full_bytes] & mask; | |
| } | |
| region | |
| } | |
| pub(crate) fn prefix_region(key: &[u8; 32], depth: usize) -> [u8; 32] { | |
| assert!(depth <= 256, "depth cannot exceed 256"); | |
| let mut region = [0u8; 32]; | |
| let full_bytes = depth / 8; | |
| let partial_bits = depth % 8; | |
| region[..full_bytes].copy_from_slice(&key[..full_bytes]); | |
| if partial_bits != 0 { | |
| let mask = (1u8 << partial_bits) - 1; | |
| region[full_bytes] = key[full_bytes] & mask; | |
| } | |
| region | |
| } |
Changed:
src/radix.rs
prefix_region(key, depth)using the repo’s existing LSB-first radix convention.< depth, split bit and later bits zeroed.src/api/inclusion_certificate.rs
0x01 || depth || region || left_hash || right_hashtests/transition_flow.rs
Validation:
cargo test --libpassed: 92/92.cargo testpassed: full default suite.