#![no_std]
#![allow(stable_features)]
#![feature(alloc)]
#[cfg(not(test))]
extern crate alloc;
#[cfg(test)]
#[macro_use]
extern crate alloc;
use alloc::collections::btree_map::BTreeMap;
use alloc::vec::Vec;
mod bit_op;
#[cfg(test)]
mod tests;
pub type Key = [u8; 32];
pub type Value = [u8; 32];
pub type Hash256 = [u8; 32];
lazy_static::lazy_static! {
static ref DEFAULT_HASHES: [Hash256; 257] = {
let mut hashes: [Hash256; 257] = [[0; 32]; 257];
for i in 1..=256 {
hashes[i] = merge_hashes(&hashes[i-1], &hashes[i-1]);
}
hashes
};
}
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
struct TreeNodeIndex {
bit_path: [u8; 32],
depth: usize,
}
impl TreeNodeIndex {
fn leaf(key: Key) -> Self {
Self {
bit_path: key,
depth: 256,
}
}
fn root() -> Self {
Self {
bit_path: [0; 32],
depth: 0,
}
}
fn is_root(&self) -> bool {
self.depth == 0
}
fn is_left(&self) -> bool {
self.depth > 0 && !bit_op::get_bit(&self.bit_path, self.depth - 1)
}
fn sibling(&self) -> Option<TreeNodeIndex> {
if self.is_root() {
return None;
}
let mut result = self.clone();
bit_op::flip_bit(&mut result.bit_path, result.depth - 1);
Some(result)
}
fn move_up(&mut self) {
assert!(self.depth > 0, "Cannot move up from the root");
bit_op::clear_bit(&mut self.bit_path, self.depth - 1);
self.depth -= 1;
}
}
#[derive(PartialEq, Eq, Debug)]
pub struct MerkleProof {
pub bitmap: [u8; 32],
pub hashes: Vec<Hash256>,
}
#[derive(Clone, Default)]
pub struct SmtMap256 {
kvs: BTreeMap<Key, Value>,
hashes: BTreeMap<TreeNodeIndex, Hash256>,
}
impl SmtMap256 {
pub fn new() -> Self {
Self {
kvs: BTreeMap::new(),
hashes: BTreeMap::new(),
}
}
pub fn set(&mut self, key: &Key, value: Value) -> Value {
let mut index = TreeNodeIndex::leaf(*key);
let mut hash: Hash256 = value;
self.update_hash(&index, &hash);
while !index.is_root() {
let sibling_hash = self.get_hash(&index.sibling().unwrap());
hash = if index.is_left() {
merge_hashes(&hash, &sibling_hash)
} else {
merge_hashes(&sibling_hash, &hash)
};
index.move_up();
self.update_hash(&index, &hash);
}
self.kvs.insert(*key, value).unwrap_or([0; 32])
}
pub fn get(&self, key: &Key) -> &Value {
self.kvs.get(key).unwrap_or(&[0; 32])
}
pub fn get_with_proof(&self, key: &Key) -> (&Value, MerkleProof) {
let mut bitmap = [0_u8; 32];
let mut sibling_hashes = Vec::new();
let mut index = TreeNodeIndex::leaf(*key);
for i in 0..256 {
if let Some(sibling_hash) = self.hashes.get(&index.sibling().unwrap()) {
bit_op::set_bit(&mut bitmap, i);
sibling_hashes.push(*sibling_hash);
}
index.move_up();
}
(
self.get(key),
MerkleProof {
bitmap,
hashes: sibling_hashes,
},
)
}
pub fn merkle_root(&self) -> &Hash256 {
self.get_hash(&TreeNodeIndex::root())
}
pub fn check_merkle_proof(&self, key: &Key, value: &Value, proof: &MerkleProof) -> bool {
check_merkle_proof(self.merkle_root(), key, value, proof)
}
fn get_hash(&self, index: &TreeNodeIndex) -> &Hash256 {
self.hashes
.get(index)
.unwrap_or(&(*DEFAULT_HASHES)[256 - index.depth])
}
fn update_hash(&mut self, index: &TreeNodeIndex, hash: &Hash256) {
if (*DEFAULT_HASHES)[256 - index.depth] == *hash {
self.hashes.remove(index);
} else {
self.hashes.insert(index.clone(), *hash);
}
}
}
pub fn check_merkle_proof(
merkle_root: &Hash256,
key: &Key,
value: &Value,
proof: &MerkleProof,
) -> bool {
let mut hash = *value;
let mut iter = proof.hashes.iter();
for i in 0..256 {
let sibling_hash = if !bit_op::get_bit(&proof.bitmap, i) {
&(*DEFAULT_HASHES)[i]
} else {
if let Some(h) = iter.next() {
h
} else {
return false;
}
};
let depth = 256 - i;
hash = if bit_op::get_bit(key, depth - 1) {
merge_hashes(sibling_hash, &hash)
} else {
merge_hashes(&hash, sibling_hash)
};
}
iter.next() == None && hash == *merkle_root
}
fn merge_hashes(left: &Hash256, right: &Hash256) -> Hash256 {
use tiny_keccak::Keccak;
let mut hasher = Keccak::new_keccak256();
hasher.update(&*left);
hasher.update(&*right);
let mut result: Hash256 = [0; 32];
hasher.finalize(&mut result);
result
}