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}