From fbb9875c5602811cbcfa59aa939c5cd3a71f5607 Mon Sep 17 00:00:00 2001
From: qh11 <qh11@illinois.edu>
Date: Sun, 13 Feb 2022 15:35:17 -0600
Subject: [PATCH] Update merkle.rs

---
 src/types/merkle.rs | 73 +++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 68 insertions(+), 5 deletions(-)

diff --git a/src/types/merkle.rs b/src/types/merkle.rs
index b63d0b8..8d4385e 100755
--- a/src/types/merkle.rs
+++ b/src/types/merkle.rs
@@ -1,29 +1,92 @@
 use super::hash::{Hashable, H256};
+use ring::digest;
+use std::collections::VecDeque;
+
+
 
 /// A Merkle tree.
 #[derive(Debug, Default)]
 pub struct MerkleTree {
+    nodes: VecDeque<VecDeque<H256>>,
 }
+ 
 
 impl MerkleTree {
     pub fn new<T>(data: &[T]) -> Self where T: Hashable, {
-        unimplemented!()
+        let curr_size = data.len();
+        let mut nodes : VecDeque<VecDeque<H256>> = VecDeque::new();
+        let mut deque : VecDeque<H256> = VecDeque::new();
+        for datum in data {
+            deque.push_back(datum.hash());
+        }
+        if curr_size % 2 != 0 {
+            deque.push_back(data[curr_size - 1].hash());
+        }
+        nodes.push_back(deque);
+        loop {
+            if nodes[0].len() == 1 {
+                return Self{ 
+                    nodes: nodes,
+                }
+            }
+            deque = VecDeque::new();
+            let curr_len = nodes[0].len();
+            for i in (1..curr_len).step_by(2) {
+                let left_hash = nodes[0][i-1];
+                let right_hash = nodes[0][i];
+                let curr_hash : H256 = hash_from(&left_hash, &right_hash);
+                deque.push_back(curr_hash);
+            }
+            if deque.len() != 1 && deque.len() % 2 == 1 {
+                deque.push_back(deque[deque.len()-1]);
+            }
+            nodes.push_front(deque);
+        }
     }
 
     pub fn root(&self) -> H256 {
-        unimplemented!()
+        self.nodes[0][0]
     }
 
     /// Returns the Merkle Proof of data at index i
     pub fn proof(&self, index: usize) -> Vec<H256> {
-        unimplemented!()
+        let mut result : Vec<H256> = Vec::new();
+        let mut pos = index;
+        for i in (1..self.nodes.len()).rev(){
+            if pos % 2 == 1{
+                result.push(self.nodes[i][pos-1]);
+            } else {
+                result.push(self.nodes[i][pos+1]);
+            }
+            pos /= 2;
+        }
+        result
     }
+    
+}
+
+fn hash_from(left: &H256, right: &H256) -> H256{
+    let mut combined = [0u8; 64];
+    combined[..32].copy_from_slice(left.as_ref());
+    combined[32..64].copy_from_slice(right.as_ref());
+    digest::digest(&digest::SHA256, &combined).into()
 }
 
 /// Verify that the datum hash with a vector of proofs will produce the Merkle root. Also need the
 /// index of datum and `leaf_size`, the total number of leaves.
 pub fn verify(root: &H256, datum: &H256, proof: &[H256], index: usize, leaf_size: usize) -> bool {
-    unimplemented!()
+    let mut curr_hash = datum.clone();
+    let mut pos = index;
+    for hash in proof{
+        if pos % 2 == 1{
+            curr_hash = hash_from(&hash, &curr_hash);
+        } else {
+            curr_hash = hash_from(&curr_hash, &hash);
+        }
+        pos /= 2;
+    }
+    curr_hash == *root
+
 }
 // DO NOT CHANGE THIS COMMENT, IT IS FOR AUTOGRADER. BEFORE TEST
 
@@ -80,4 +143,4 @@ mod tests {
     }
 }
 
-// DO NOT CHANGE THIS COMMENT, IT IS FOR AUTOGRADER. AFTER TEST
\ No newline at end of file
+// DO NOT CHANGE THIS COMMENT, IT IS FOR AUTOGRADER. AFTER TEST
-- 
GitLab