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}