plonky2/src/merkle_tree.rs

122 lines
3.3 KiB
Rust
Raw Normal View History

use rayon::prelude::*;
2021-04-21 22:31:45 +02:00
use crate::field::field::Field;
2021-04-22 15:50:08 +02:00
use crate::hash::{compress, hash_or_noop};
2021-04-21 22:31:45 +02:00
use crate::merkle_proofs::MerkleProof;
use crate::proof::Hash;
use crate::util::{log2_strict, reverse_bits, reverse_index_bits_in_place};
#[derive(Clone, Debug)]
pub struct MerkleTree<F: Field> {
/// The data in the leaves of the Merkle tree.
pub leaves: Vec<Vec<F>>,
/// The layers of hashes in the tree. The first layer is the one at the bottom.
pub layers: Vec<Vec<Hash<F>>>,
/// The Merkle root.
pub root: Hash<F>,
/// If true, the indices are in bit-reversed form, so that the leaf at index `i`
/// contains the leaf originally at index `reverse_bits(i)`.
pub reverse_bits: bool,
}
impl<F: Field> MerkleTree<F> {
pub fn new(mut leaves: Vec<Vec<F>>, reverse_bits: bool) -> Self {
if reverse_bits {
reverse_index_bits_in_place(&mut leaves);
}
let mut layers = vec![leaves
.par_iter()
2021-04-21 22:31:45 +02:00
.map(|l| hash_or_noop(l.clone()))
.collect::<Vec<_>>()];
while let Some(l) = layers.last() {
if l.len() == 1 {
break;
}
2021-04-22 15:50:08 +02:00
let next_layer = l
.par_chunks(2)
2021-04-22 15:50:08 +02:00
.map(|chunk| compress(chunk[0], chunk[1]))
.collect::<Vec<_>>();
layers.push(next_layer);
2021-04-21 22:31:45 +02:00
}
let root = layers.pop().unwrap()[0];
Self {
leaves,
layers,
root,
reverse_bits,
}
}
pub fn get(&self, i: usize) -> &[F] {
let n = log2_strict(self.leaves.len());
&self.leaves[if self.reverse_bits {
reverse_bits(i, n)
} else {
i
}]
}
/// Create a Merkle proof from a leaf index.
pub fn prove(&self, leaf_index: usize) -> MerkleProof<F> {
let index = if self.reverse_bits {
reverse_bits(leaf_index, log2_strict(self.leaves.len()))
} else {
leaf_index
};
MerkleProof {
siblings: self
.layers
.iter()
.scan(index, |acc, layer| {
let index = *acc ^ 1;
*acc >>= 1;
Some(layer[index])
})
.collect(),
}
}
}
#[cfg(test)]
mod tests {
use anyhow::Result;
use super::*;
2021-04-21 22:31:45 +02:00
use crate::field::crandall_field::CrandallField;
2021-04-28 18:41:59 +02:00
use crate::merkle_proofs::verify_merkle_proof;
2021-04-22 22:33:29 +02:00
fn random_data<F: Field>(n: usize, k: usize) -> Vec<Vec<F>> {
2021-05-06 15:14:43 +02:00
(0..n).map(|_| F::rand_vec(k)).collect()
2021-04-22 22:33:29 +02:00
}
2021-04-23 15:25:18 +02:00
fn verify_all_leaves<F: Field>(
leaves: Vec<Vec<F>>,
n: usize,
reverse_bits: bool,
) -> Result<()> {
let tree = MerkleTree::new(leaves.clone(), reverse_bits);
2021-04-21 22:31:45 +02:00
for i in 0..n {
let proof = tree.prove(i);
2021-04-23 15:25:18 +02:00
verify_merkle_proof(leaves[i].clone(), i, tree.root, &proof, reverse_bits)?;
2021-04-21 22:31:45 +02:00
}
2021-04-23 15:25:18 +02:00
Ok(())
}
2021-04-22 22:33:29 +02:00
2021-04-23 15:25:18 +02:00
#[test]
fn test_merkle_trees() -> Result<()> {
type F = CrandallField;
2021-04-22 09:27:59 +02:00
2021-04-23 15:25:18 +02:00
let log_n = 8;
let n = 1 << log_n;
let leaves = random_data::<F>(n, 7);
2021-04-23 11:05:31 +02:00
2021-04-23 15:25:18 +02:00
verify_all_leaves(leaves.clone(), n, false)?;
verify_all_leaves(leaves.clone(), n, true)?;
2021-04-22 22:33:29 +02:00
2021-04-22 09:27:59 +02:00
Ok(())
2021-04-21 22:31:45 +02:00
}
}