feat: Merkle tree list hashing
This commit is contained in:
parent
27e5aaa777
commit
d4f07b4f04
2 changed files with 37 additions and 0 deletions
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
|
@ -1,5 +1,6 @@
|
||||||
{
|
{
|
||||||
"cSpell.words": [
|
"cSpell.words": [
|
||||||
|
"hasher",
|
||||||
"Merkle",
|
"Merkle",
|
||||||
"Precertificate"
|
"Precertificate"
|
||||||
],
|
],
|
||||||
|
|
|
@ -1 +1,37 @@
|
||||||
|
use sha2::{Digest, Sha256};
|
||||||
|
|
||||||
|
use super::types::MerkleTreeLeaf;
|
||||||
|
|
||||||
|
pub enum MerkleTreeNode<'a> {
|
||||||
|
Leaf(MerkleTreeLeaf<'a>),
|
||||||
|
Intermediate(String)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Hashes a merkle leaf list. This takes in a slice of u8 slices, each
|
||||||
|
/// representing the binary form of a merkle tree leaf. This implementation is
|
||||||
|
/// not optimized for extra-long lists as its implementation is recursive,
|
||||||
|
/// however, the current-largest CT log as of 11/5/24 would theoretically only
|
||||||
|
/// go 32 levels deep.
|
||||||
|
pub fn hash_merkle_leaf_list(leaves: &[&[u8]]) -> [u8; 32] {
|
||||||
|
let mut hasher = Sha256::default();
|
||||||
|
|
||||||
|
// The hash of an empty list is the empty hash, no branch necessary
|
||||||
|
if leaves.len() == 1 {
|
||||||
|
// The hash of one element is 0x00 + the hash of its data
|
||||||
|
hasher.update([0x00u8]);
|
||||||
|
hasher.update(leaves[0]);
|
||||||
|
} else if leaves.len() > 1 {
|
||||||
|
// For n > 1, let k be the largest power of two smaller than n (i.e., k < n <=
|
||||||
|
// 2k)
|
||||||
|
// MTH(D[n]) = SHA-256(0x01 || MTH(D[0:k]) || MTH(D[k:n]))
|
||||||
|
|
||||||
|
// This can be calculated by taking log_2(n), flooring it, then taking 2
|
||||||
|
// to the power of it again
|
||||||
|
let k = 2usize.pow(leaves.len().ilog2());
|
||||||
|
hasher.update([0x01u8]);
|
||||||
|
hasher.update(hash_merkle_leaf_list(&leaves[0..k]));
|
||||||
|
hasher.update(hash_merkle_leaf_list(&leaves[k..leaves.len()]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return hasher.finalize().into();
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue