mithril_stm/protocol/aggregate_signature/
clerk.rs

1use anyhow::Context;
2use blake2::digest::{Digest, FixedOutput};
3
4#[cfg(feature = "future_proof_system")]
5use anyhow::anyhow;
6
7#[cfg(feature = "future_proof_system")]
8use crate::AggregationError;
9
10use super::{AggregateSignature, AggregateSignatureType, AggregateVerificationKey};
11use crate::{
12    ClosedKeyRegistration, Index, Parameters, Signer, SingleSignature, Stake, StmResult,
13    VerificationKey, proof_system::ConcatenationProof,
14};
15
16/// `Clerk` can verify and aggregate `SingleSignature`s and verify `AggregateSignature`s.
17/// Clerks can only be generated with the registration closed.
18/// This avoids that a Merkle Tree is computed before all parties have registered.
19#[derive(Debug, Clone)]
20pub struct Clerk<D: Clone + Digest> {
21    pub(crate) closed_reg: ClosedKeyRegistration<D>,
22    pub(crate) params: Parameters,
23}
24
25impl<D: Digest + Clone + FixedOutput + Send + Sync> Clerk<D> {
26    /// Create a new `Clerk` from a closed registration instance.
27    pub fn new_clerk_from_closed_key_registration(
28        params: &Parameters,
29        closed_reg: &ClosedKeyRegistration<D>,
30    ) -> Self {
31        Self {
32            params: *params,
33            closed_reg: closed_reg.clone(),
34        }
35    }
36
37    /// Create a new `Clerk` from a closed registration instance.
38    #[deprecated(
39        since = "0.5.0",
40        note = "Use `new_clerk_from_closed_key_registration` instead"
41    )]
42    pub fn from_registration(params: &Parameters, closed_reg: &ClosedKeyRegistration<D>) -> Self {
43        Self::new_clerk_from_closed_key_registration(params, closed_reg)
44    }
45
46    /// Create a Clerk from a signer.
47    pub fn new_clerk_from_signer(signer: &Signer<D>) -> Self {
48        let closed_reg = signer
49            .get_closed_key_registration()
50            .clone()
51            .expect("Core signer does not include closed registration. Clerk, and so, the Stm certificate cannot be built without closed registration!")
52            ;
53
54        Self {
55            params: signer.get_parameters(),
56            closed_reg,
57        }
58    }
59
60    /// Create a Clerk from a signer.
61    #[deprecated(since = "0.5.0", note = "Use `new_clerk_from_signer` instead")]
62    pub fn from_signer(signer: &Signer<D>) -> Self {
63        Self::new_clerk_from_signer(signer)
64    }
65
66    /// Aggregate a set of signatures.
67    #[deprecated(since = "0.5.3", note = "Use `aggregate_signatures_with_type` instead")]
68    pub fn aggregate_signatures(
69        &self,
70        sigs: &[SingleSignature],
71        msg: &[u8],
72    ) -> StmResult<AggregateSignature<D>> {
73        self.aggregate_signatures_with_type(sigs, msg, AggregateSignatureType::default())
74    }
75
76    /// Aggregate a set of signatures with a given proof type.
77    pub fn aggregate_signatures_with_type(
78        &self,
79        sigs: &[SingleSignature],
80        msg: &[u8],
81        aggregate_signature_type: AggregateSignatureType,
82    ) -> StmResult<AggregateSignature<D>> {
83        match aggregate_signature_type {
84            AggregateSignatureType::Concatenation => Ok(AggregateSignature::Concatenation(
85                ConcatenationProof::aggregate_signatures(self, sigs, msg).with_context(|| {
86                    format!(
87                        "Signatures failed to aggregate for type {}",
88                        AggregateSignatureType::Concatenation
89                    )
90                })?,
91            )),
92            #[cfg(feature = "future_proof_system")]
93            AggregateSignatureType::Future => Err(anyhow!(
94                AggregationError::UnsupportedProofSystem(aggregate_signature_type)
95            )),
96        }
97    }
98
99    /// Aggregate a set of signatures for their corresponding indices.
100    ///
101    /// This function first deduplicates the repeated signatures, and if there are enough signatures, it collects the merkle tree indexes of unique signatures.
102    /// The list of merkle tree indexes is used to create a batch proof, to prove that all signatures are from eligible signers.
103    ///
104    /// It returns an instance of `AggregateSignature`.
105    #[deprecated(since = "0.5.0", note = "Use `aggregate_signatures` instead")]
106    #[allow(deprecated)]
107    pub fn aggregate(
108        &self,
109        sigs: &[SingleSignature],
110        msg: &[u8],
111    ) -> StmResult<AggregateSignature<D>> {
112        Self::aggregate_signatures(self, sigs, msg)
113    }
114
115    /// Compute the `AggregateVerificationKey` related to the used registration.
116    pub fn compute_aggregate_verification_key(&self) -> AggregateVerificationKey<D> {
117        AggregateVerificationKey::from(&self.closed_reg)
118    }
119
120    /// Compute the `AggregateVerificationKey` related to the used registration.
121    #[deprecated(
122        since = "0.5.0",
123        note = "Use `compute_aggregate_verification_key` instead"
124    )]
125    pub fn compute_avk(&self) -> AggregateVerificationKey<D> {
126        Self::compute_aggregate_verification_key(self)
127    }
128
129    /// Get the (VK, stake) of a party given its index.
130    pub fn get_registered_party_for_index(
131        &self,
132        party_index: &Index,
133    ) -> Option<(VerificationKey, Stake)> {
134        self.closed_reg
135            .reg_parties
136            .get(*party_index as usize)
137            .map(|&r| r.into())
138    }
139
140    /// Get the (VK, stake) of a party given its index.
141    #[deprecated(since = "0.5.0", note = "Use `get_registered_party_for_index` instead")]
142    pub fn get_reg_party(&self, party_index: &Index) -> Option<(VerificationKey, Stake)> {
143        Self::get_registered_party_for_index(self, party_index)
144    }
145}