Skip to main content

vote_commitment_tree/
anchor.rs

1//! Anchor type for committed vote commitment tree roots.
2
3use ff::PrimeField;
4use incrementalmerkletree::{Hashable, Level};
5use pasta_curves::Fp;
6
7use crate::hash::{MerkleHashVote, TREE_DEPTH};
8
9// ---------------------------------------------------------------------------
10// Anchor
11// ---------------------------------------------------------------------------
12
13/// A committed vote commitment tree root at a specific block height.
14///
15/// This is the value that ZKP #2 and ZKP #3 verify Merkle inclusion proofs
16/// against. It must be a valid Pallas base field element.
17#[derive(Eq, PartialEq, Clone, Copy, Debug)]
18pub struct Anchor(Fp);
19
20impl From<Fp> for Anchor {
21    fn from(value: Fp) -> Self {
22        Anchor(value)
23    }
24}
25
26impl From<MerkleHashVote> for Anchor {
27    fn from(hash: MerkleHashVote) -> Self {
28        Anchor(hash.0)
29    }
30}
31
32impl Anchor {
33    /// The anchor of the empty vote commitment tree.
34    pub fn empty_tree() -> Self {
35        Anchor(MerkleHashVote::empty_root(Level::from(TREE_DEPTH as u8)).0)
36    }
37
38    /// Extract the inner field element.
39    pub fn inner(&self) -> Fp {
40        self.0
41    }
42
43    /// Serialize to canonical 32-byte little-endian representation.
44    pub fn to_bytes(&self) -> [u8; 32] {
45        self.0.to_repr()
46    }
47
48    /// Deserialize from 32 bytes. Returns `None` for non-canonical encodings.
49    pub fn from_bytes(bytes: [u8; 32]) -> Option<Self> {
50        Option::from(Fp::from_repr(bytes).map(Anchor))
51    }
52}