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
10pub type VerificationKeyProofOfPossession = BlsVerificationKeyProofOfPossession;
12
13#[derive(Debug, Clone, Serialize, Deserialize)]
17pub struct Initializer {
18 pub stake: Stake,
20 pub params: Parameters,
22 pub(crate) sk: BlsSigningKey,
24 pub(crate) pk: VerificationKeyProofOfPossession,
26}
27
28impl Initializer {
29 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 #[deprecated(since = "0.5.0", 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 pub fn get_verification_key_proof_of_possession(&self) -> VerificationKeyProofOfPossession {
51 self.pk
52 }
53
54 #[deprecated(
56 since = "0.5.0",
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 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 #[deprecated(since = "0.5.0", 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 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 #[deprecated(since = "0.5.0", 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 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 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}
200
201impl PartialEq for Initializer {
202 fn eq(&self, other: &Self) -> bool {
203 self.stake == other.stake
204 && self.params == other.params
205 && self.sk.to_bytes() == other.sk.to_bytes()
206 && self.get_verification_key_proof_of_possession()
207 == other.get_verification_key_proof_of_possession()
208 }
209}
210
211#[cfg(test)]
212mod tests {
213 use super::*;
214
215 mod golden {
216 use rand_chacha::ChaCha20Rng;
217 use rand_core::SeedableRng;
218
219 use super::*;
220
221 const GOLDEN_JSON: &str = r#"
222 {
223 "stake":1,
224 "params":
225 {
226 "m":20973,
227 "k":2422,
228 "phi_f":0.2
229 },
230 "sk":[64,129,87,121,27,239,221,215,2,103,45,207,207,201,157,163,81,47,156,14,168,24,137,15,203,106,183,73,88,14,242,207],
231 "pk":
232 {
233 "vk":[143,161,255,48,78,57,204,220,25,221,164,252,248,14,56,126,186,135,228,188,145,181,52,200,97,99,213,46,0,199,193,89,187,88,29,135,173,244,86,36,83,54,67,164,6,137,94,72,6,105,128,128,93,48,176,11,4,246,138,48,180,133,90,142,192,24,193,111,142,31,76,111,110,234,153,90,208,192,31,124,95,102,49,158,99,52,220,165,94,251,68,69,121,16,224,194],
234 "pop":[168,50,233,193,15,136,65,72,123,148,129,176,38,198,209,47,28,204,176,144,57,251,42,28,66,76,89,97,158,63,54,198,194,176,135,221,14,185,197,225,202,98,243,74,233,225,143,151,147,177,170,117,66,165,66,62,33,216,232,75,68,114,195,22,100,65,44,198,4,166,102,233,253,240,59,175,60,117,142,114,140,122,17,87,110,187,1,17,10,195,154,13,249,86,54,226]
235 }
236 }
237 "#;
238
239 fn golden_value() -> Initializer {
240 let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
241 let sk = BlsSigningKey::generate(&mut rng);
242 let pk = BlsVerificationKeyProofOfPossession::from(&sk);
243 Initializer {
244 stake: 1,
245 params: Parameters {
246 m: 20973,
247 k: 2422,
248 phi_f: 0.2,
249 },
250 sk,
251 pk,
252 }
253 }
254
255 #[test]
256 fn golden_conversions() {
257 let value = serde_json::from_str(GOLDEN_JSON)
258 .expect("This JSON deserialization should not fail");
259 assert_eq!(golden_value(), value);
260
261 let serialized =
262 serde_json::to_string(&value).expect("This JSON serialization should not fail");
263 let golden_serialized = serde_json::to_string(&golden_value())
264 .expect("This JSON serialization should not fail");
265 assert_eq!(golden_serialized, serialized);
266 }
267 }
268}