mithril_stm/participant/
initializer.rs

1use blake2::digest::Digest;
2use digest::FixedOutput;
3use rand_core::{CryptoRng, RngCore};
4use serde::{Deserialize, Serialize};
5
6use crate::bls_multi_signature::{BlsSigningKey, BlsVerificationKeyProofOfPossession};
7use crate::key_registration::*;
8use crate::{Parameters, RegisterError, Signer, Stake};
9
10/// Wrapper of the MultiSignature Verification key with proof of possession
11pub type VerificationKeyProofOfPossession = BlsVerificationKeyProofOfPossession;
12
13/// Initializer for `Signer`.
14/// This is the data that is used during the key registration procedure.
15/// Once the latter is finished, this instance is consumed into an `Signer`.
16#[derive(Debug, Clone, Serialize, Deserialize)]
17pub struct Initializer {
18    /// This participant's stake.
19    pub stake: Stake,
20    /// Current protocol instantiation parameters.
21    pub params: Parameters,
22    /// Secret key.
23    pub(crate) sk: BlsSigningKey,
24    /// Verification (public) key + proof of possession.
25    pub(crate) pk: VerificationKeyProofOfPossession,
26}
27
28impl Initializer {
29    /// Builds an `Initializer` that is ready to register with the key registration service.
30    /// This function generates the signing and verification key with a PoP, and initialises the structure.
31    pub fn new<R: RngCore + CryptoRng>(params: Parameters, stake: Stake, rng: &mut R) -> Self {
32        let sk = BlsSigningKey::generate(rng);
33        let pk = VerificationKeyProofOfPossession::from(&sk);
34        Self {
35            stake,
36            params,
37            sk,
38            pk,
39        }
40    }
41
42    /// Builds an `Initializer` that is ready to register with the key registration service.
43    /// This function generates the signing and verification key with a PoP, and initialises the structure.
44    #[deprecated(since = "0.4.9", note = "Use `new` instead")]
45    pub fn setup<R: RngCore + CryptoRng>(params: Parameters, stake: Stake, rng: &mut R) -> Self {
46        Self::new(params, stake, rng)
47    }
48
49    /// Extract the verification key with proof of possession.
50    pub fn get_verification_key_proof_of_possession(&self) -> VerificationKeyProofOfPossession {
51        self.pk
52    }
53
54    /// Extract the verification key.
55    #[deprecated(
56        since = "0.4.9",
57        note = "Use `get_verification_key_proof_of_possession` instead"
58    )]
59    pub fn verification_key(&self) -> VerificationKeyProofOfPossession {
60        Self::get_verification_key_proof_of_possession(self)
61    }
62
63    /// Build the `avk` for the given list of parties.
64    ///
65    /// Note that if this Initializer was modified *between* the last call to `register`,
66    /// then the resulting `Signer` may not be able to produce valid signatures.
67    ///
68    /// Returns an `Signer` specialized to
69    /// * this `Signer`'s ID and current stake
70    /// * this `Signer`'s parameter valuation
71    /// * the `avk` as built from the current registered parties (according to the registration service)
72    /// * the current total stake (according to the registration service)
73    /// # Error
74    /// This function fails if the initializer is not registered.
75    pub fn create_signer<D: Digest + Clone + FixedOutput>(
76        self,
77        closed_reg: ClosedKeyRegistration<D>,
78    ) -> Result<Signer<D>, RegisterError> {
79        let mut my_index = None;
80        for (i, rp) in closed_reg.reg_parties.iter().enumerate() {
81            if rp.0 == self.pk.vk {
82                my_index = Some(i as u64);
83                break;
84            }
85        }
86        if my_index.is_none() {
87            return Err(RegisterError::UnregisteredInitializer);
88        }
89
90        Ok(Signer::set_signer(
91            my_index.unwrap(),
92            self.stake,
93            self.params,
94            self.sk,
95            self.pk.vk,
96            closed_reg,
97        ))
98    }
99
100    /// Build the `avk` for the given list of parties.
101    ///
102    /// Note that if this Initializer was modified *between* the last call to `register`,
103    /// then the resulting `Signer` may not be able to produce valid signatures.
104    ///
105    /// Returns an `Signer` specialized to
106    /// * this `Signer`'s ID and current stake
107    /// * this `Signer`'s parameter valuation
108    /// * the `avk` as built from the current registered parties (according to the registration service)
109    /// * the current total stake (according to the registration service)
110    /// # Error
111    /// This function fails if the initializer is not registered.
112    #[deprecated(since = "0.4.9", note = "Use `create_signer` instead")]
113    pub fn new_signer<D: Digest + Clone + FixedOutput>(
114        self,
115        closed_reg: ClosedKeyRegistration<D>,
116    ) -> Result<Signer<D>, RegisterError> {
117        Self::create_signer(self, closed_reg)
118    }
119
120    /// Creates a new basic signer that does not include closed registration.
121    /// Takes `eligible_parties` as a parameter and determines the signer's index in the parties.
122    /// `eligible_parties` is verified and trusted which is only run by a full-node
123    /// that has already verified the parties.
124    pub fn create_basic_signer<D: Digest + Clone + FixedOutput>(
125        self,
126        eligible_parties: &[RegisteredParty],
127    ) -> Option<Signer<D>> {
128        let mut parties = eligible_parties.to_vec();
129        parties.sort_unstable();
130        let mut my_index = None;
131        for (i, rp) in parties.iter().enumerate() {
132            if rp.0 == self.pk.vk {
133                my_index = Some(i as u64);
134                break;
135            }
136        }
137        if let Some(index) = my_index {
138            Some(Signer::set_basic_signer(
139                index,
140                self.stake,
141                self.params,
142                self.sk,
143                self.pk.vk,
144            ))
145        } else {
146            None
147        }
148    }
149
150    /// Creates a new basic signer that does not include closed registration.
151    /// Takes `eligible_parties` as a parameter and determines the signer's index in the parties.
152    /// `eligible_parties` is verified and trusted which is only run by a full-node
153    /// that has already verified the parties.
154    #[deprecated(since = "0.4.9", note = "Use `create_basic_signer` instead")]
155    pub fn new_core_signer<D: Digest + Clone + FixedOutput>(
156        self,
157        eligible_parties: &[RegisteredParty],
158    ) -> Option<Signer<D>> {
159        Self::create_basic_signer(self, eligible_parties)
160    }
161
162    /// Convert to bytes
163    /// # Layout
164    /// * Stake (u64)
165    /// * Params
166    /// * Secret Key
167    /// * Public key (including PoP)
168    pub fn to_bytes(&self) -> [u8; 256] {
169        let mut out = [0u8; 256];
170        out[..8].copy_from_slice(&self.stake.to_be_bytes());
171        out[8..32].copy_from_slice(&self.params.to_bytes());
172        out[32..64].copy_from_slice(&self.sk.to_bytes());
173        out[64..].copy_from_slice(&self.pk.to_bytes());
174        out
175    }
176
177    /// Convert a slice of bytes to an `Initializer`
178    /// # Error
179    /// The function fails if the given string of bytes is not of required size.
180    pub fn from_bytes(bytes: &[u8]) -> Result<Initializer, RegisterError> {
181        let mut u64_bytes = [0u8; 8];
182        u64_bytes.copy_from_slice(bytes.get(..8).ok_or(RegisterError::SerializationError)?);
183        let stake = u64::from_be_bytes(u64_bytes);
184        let params =
185            Parameters::from_bytes(bytes.get(8..32).ok_or(RegisterError::SerializationError)?)?;
186        let sk =
187            BlsSigningKey::from_bytes(bytes.get(32..).ok_or(RegisterError::SerializationError)?)?;
188        let pk = VerificationKeyProofOfPossession::from_bytes(
189            bytes.get(64..).ok_or(RegisterError::SerializationError)?,
190        )?;
191
192        Ok(Self {
193            stake,
194            params,
195            sk,
196            pk,
197        })
198    }
199}