1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
use crate::{Error, Index, Result};
use itertools::Itertools;
use std::prelude::v1::*;
use zkp_error_utils::require;
use zkp_hash::Hash;
#[derive(Clone, Default)]
#[cfg_attr(feature = "std", derive(Debug))]
pub struct Commitment {
size: usize,
hash: Hash,
}
impl Commitment {
pub fn from_size_hash(size: usize, hash: &Hash) -> Result<Self> {
require!(
size == 0 || size.is_power_of_two(),
Error::NumLeavesNotPowerOfTwo
);
Ok(Self {
size,
hash: hash.clone(),
})
}
pub fn size(&self) -> usize {
self.size
}
pub fn hash(&self) -> &Hash {
&self.hash
}
pub fn sort_indices(&self, indices: &[usize]) -> Result<Vec<Index>> {
let mut indices = indices
.iter()
.map(|&i| Index::from_size_offset(self.size, i))
.collect::<Result<Vec<_>>>()?;
indices.sort_unstable();
indices.dedup();
Ok(indices)
}
pub fn proof_size(&self, indices: &[usize]) -> Result<usize> {
let indices = self.sort_indices(indices)?;
let depth = self.size.trailing_zeros() as usize;
let mut size = depth * indices.len();
for (¤t, &next) in indices.iter().tuple_windows() {
let ancestor = current.last_common_ancestor(next);
size -= ancestor.depth() + 2;
}
Ok(size)
}
}