mithril_stm/protocol/aggregate_signature/
clerk.rs

1use anyhow::Context;
2use std::marker::PhantomData;
3
4#[cfg(feature = "future_snark")]
5use anyhow::anyhow;
6
7use crate::{
8    AggregateVerificationKey, ClosedKeyRegistration, LotteryIndex, MembershipDigest, Parameters,
9    Signer, SingleSignature, Stake, StmResult, VerificationKeyForConcatenation,
10    proof_system::{ConcatenationClerk, ConcatenationProof},
11};
12
13use super::{AggregateSignature, AggregateSignatureType};
14
15#[cfg(feature = "future_snark")]
16use super::AggregationError;
17
18/// Clerk for aggregate signatures.
19#[derive(Debug, Clone)]
20pub struct Clerk<D: MembershipDigest> {
21    concatenation_proof_clerk: ConcatenationClerk,
22    phantom_data: PhantomData<D>,
23}
24
25impl<D: MembershipDigest> Clerk<D> {
26    /// Create a Clerk from a signer.
27    pub fn new_clerk_from_signer(signer: &Signer<D>) -> Self {
28        Self {
29            concatenation_proof_clerk: ConcatenationClerk::new_clerk_from_signer(signer),
30            phantom_data: PhantomData,
31        }
32    }
33
34    /// Create a Clerk from a closed key registration.
35    pub fn new_clerk_from_closed_key_registration(
36        parameters: &Parameters,
37        closed_reg: &ClosedKeyRegistration,
38    ) -> Self {
39        Self {
40            concatenation_proof_clerk: ConcatenationClerk::new_clerk_from_closed_key_registration(
41                parameters, closed_reg,
42            ),
43            phantom_data: PhantomData,
44        }
45    }
46    /// Aggregate a set of signatures with a given proof type.
47    pub fn aggregate_signatures_with_type(
48        &self,
49        sigs: &[SingleSignature],
50        msg: &[u8],
51        aggregate_signature_type: AggregateSignatureType,
52    ) -> StmResult<AggregateSignature<D>> {
53        match aggregate_signature_type {
54            AggregateSignatureType::Concatenation => Ok(AggregateSignature::Concatenation(
55                ConcatenationProof::aggregate_signatures(self.get_concatenation_clerk(), sigs, msg)
56                    .with_context(|| {
57                        format!(
58                            "Signatures failed to aggregate for type {}",
59                            AggregateSignatureType::Concatenation
60                        )
61                    })?,
62            )),
63            #[cfg(feature = "future_snark")]
64            AggregateSignatureType::Future => Err(anyhow!(
65                AggregationError::UnsupportedProofSystem(aggregate_signature_type)
66            )),
67        }
68    }
69
70    /// Get the concatenation clerk.
71    pub fn get_concatenation_clerk(&self) -> &ConcatenationClerk {
72        &self.concatenation_proof_clerk
73    }
74
75    /// Compute the aggregate verification key.
76    /// It computes only the concatenation aggregate verification key for now.
77    /// Needs to be revised when implementing SNARK pre-aggregation primitives
78    pub fn compute_aggregate_verification_key(&self) -> AggregateVerificationKey<D> {
79        AggregateVerificationKey::new(
80            self.concatenation_proof_clerk
81                .compute_aggregate_verification_key_for_concatenation(),
82        )
83    }
84
85    /// Get the concatenation registered party for a given index.
86    pub fn get_concatenation_registered_party_for_index(
87        &self,
88        party_index: &LotteryIndex,
89    ) -> StmResult<(VerificationKeyForConcatenation, Stake)> {
90        let entry = self
91            .get_concatenation_clerk()
92            .closed_key_registration
93            .key_registration
94            .get_registration_entry_for_index(party_index)?;
95        Ok((entry.get_bls_verification_key(), entry.get_stake()))
96    }
97
98    #[cfg(test)]
99    pub fn update_k(&mut self, k: u64) {
100        self.concatenation_proof_clerk.update_k(k);
101    }
102
103    #[cfg(test)]
104    pub fn update_m(&mut self, m: u64) {
105        self.concatenation_proof_clerk.update_m(m);
106    }
107}