1use crate::keys::{BlsKeypairShare, SignatureShare};
11use crate::{utils, Error, PublicKey, Signature};
12use ed25519_dalek::{Keypair as Ed25519Keypair, PublicKey as Ed25519PublicKey};
13use hex_fmt::HexFmt;
14use rand::{CryptoRng, Rng};
15use serde::{Deserialize, Deserializer, Serialize, Serializer};
16use signature::Signer;
17use std::{
18 cmp::Ordering,
19 fmt::{self, Debug, Display, Formatter},
20 hash::{Hash, Hasher},
21};
22use threshold_crypto::{
23 serde_impl::SerdeSecret, PublicKeySet, PublicKeyShare as BlsPublicKeyShare,
24 SecretKeyShare as BlsSecretKeyShare,
25};
26use xor_name::XorName;
27
28#[derive(Serialize, Deserialize)]
31pub struct FullId {
32 ed25519: Ed25519Keypair,
33 bls: Option<BlsKeypairShare>,
34 public_id: PublicId,
35}
36
37impl FullId {
38 pub fn new<T: CryptoRng + Rng>(rng: &mut T) -> Self {
40 let ed25519 = Ed25519Keypair::generate(rng);
41 let name = PublicKey::Ed25519(ed25519.public).into();
42 let public_id = PublicId {
43 name,
44 ed25519: ed25519.public,
45 bls: None,
46 };
47 Self {
48 ed25519,
49 bls: None,
50 public_id,
51 }
52 }
53
54 pub fn within_range<T: CryptoRng + Rng>(start: &XorName, end: &XorName, rng: &mut T) -> Self {
56 let mut ed25519 = Ed25519Keypair::generate(rng);
57 loop {
58 let name = PublicKey::Ed25519(ed25519.public).into();
59 if name >= *start && name <= *end {
60 let public_id = PublicId {
61 name,
62 ed25519: ed25519.public,
63 bls: None,
64 };
65 return Self {
66 ed25519,
67 bls: None,
68 public_id,
69 };
70 }
71 ed25519 = Ed25519Keypair::generate(rng);
72 }
73 }
74
75 pub fn public_id(&self) -> &PublicId {
77 &self.public_id
78 }
79
80 pub fn sign_using_ed25519<T: AsRef<[u8]>>(&self, data: T) -> Signature {
82 Signature::Ed25519(self.ed25519.sign(data.as_ref()))
83 }
84
85 pub fn sign_using_bls<T: AsRef<[u8]>>(&self, data: T) -> Option<Signature> {
87 self.bls.as_ref().map(|keys| {
88 Signature::BlsShare(SignatureShare {
89 index: keys.index,
90 share: keys.secret.inner().sign(data),
91 })
92 })
93 }
94
95 pub fn set_bls_keys(&mut self, secret_share: BlsSecretKeyShare, public_set: PublicKeySet) {
97 let public = secret_share.public_key_share();
98 let secret = SerdeSecret(secret_share);
99 self.public_id.bls = Some(public);
100 self.bls = Some(BlsKeypairShare {
101 index: 0,
102 secret,
103 public,
104 public_key_set: public_set,
105 });
106 }
107
108 pub fn clear_bls_keys(&mut self) {
110 self.public_id.bls = None;
111 self.bls = None;
112 }
113}
114
115#[derive(Clone, Eq, PartialEq)]
120pub struct PublicId {
121 name: XorName,
122 ed25519: Ed25519PublicKey,
123 bls: Option<BlsPublicKeyShare>,
124}
125
126impl PublicId {
127 pub fn name(&self) -> &XorName {
129 &self.name
130 }
131
132 pub fn ed25519_public_key(&self) -> &Ed25519PublicKey {
134 &self.ed25519
135 }
136
137 pub fn bls_public_key(&self) -> &Option<BlsPublicKeyShare> {
139 &self.bls
140 }
141
142 pub fn encode_to_zbase32(&self) -> String {
144 utils::encode(&self)
145 }
146
147 pub fn decode_from_zbase32<T: AsRef<str>>(encoded: T) -> Result<Self, Error> {
149 utils::decode(encoded)
150 }
151}
152
153impl Serialize for PublicId {
154 fn serialize<S: Serializer>(&self, serialiser: S) -> Result<S::Ok, S::Error> {
155 (&self.ed25519, &self.bls).serialize(serialiser)
156 }
157}
158
159impl<'de> Deserialize<'de> for PublicId {
160 fn deserialize<D: Deserializer<'de>>(deserialiser: D) -> Result<Self, D::Error> {
161 let (ed25519, bls): (Ed25519PublicKey, Option<BlsPublicKeyShare>) =
162 Deserialize::deserialize(deserialiser)?;
163 let name = PublicKey::Ed25519(ed25519).into();
164 Ok(PublicId { name, ed25519, bls })
165 }
166}
167
168impl Ord for PublicId {
169 fn cmp(&self, other: &PublicId) -> Ordering {
170 utils::serialise(&self).cmp(&utils::serialise(other))
171 }
172}
173
174impl PartialOrd for PublicId {
175 fn partial_cmp(&self, other: &PublicId) -> Option<Ordering> {
176 Some(self.cmp(other))
177 }
178}
179
180#[allow(clippy::derive_hash_xor_eq)]
181impl Hash for PublicId {
182 fn hash<H: Hasher>(&self, state: &mut H) {
183 utils::serialise(&self).hash(state)
184 }
185}
186
187impl Debug for PublicId {
188 fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
189 write!(formatter, "Node({:<8})", HexFmt(&self.ed25519.to_bytes()))
190 }
191}
192
193impl Display for PublicId {
194 fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
195 Debug::fmt(self, formatter)
196 }
197}
198
199#[derive(Serialize, Deserialize)]
205pub struct NodeKeypairs {
206 ed25519: Ed25519Keypair,
207 bls: Option<BlsKeypairShare>,
208 public_id: PublicId,
209}
210
211impl NodeKeypairs {
212 pub fn new<T: CryptoRng + Rng>(rng: &mut T) -> Self {
214 let ed25519 = Ed25519Keypair::generate(rng);
215 let name = PublicKey::Ed25519(ed25519.public).into();
216 let public_id = PublicId {
217 name,
218 ed25519: ed25519.public,
219 bls: None,
220 };
221 Self {
222 ed25519,
223 bls: None,
224 public_id,
225 }
226 }
227
228 pub fn within_range<T: CryptoRng + Rng>(start: &XorName, end: &XorName, rng: &mut T) -> Self {
230 let mut ed25519 = Ed25519Keypair::generate(rng);
231 loop {
232 let name = PublicKey::Ed25519(ed25519.public).into();
233 if name >= *start && name <= *end {
234 let public_id = PublicId {
235 name,
236 ed25519: ed25519.public,
237 bls: None,
238 };
239 return Self {
240 ed25519,
241 bls: None,
242 public_id,
243 };
244 }
245 ed25519 = Ed25519Keypair::generate(rng);
246 }
247 }
248
249 pub fn public_key(&self) -> PublicKey {
251 if let Some(key) = self.public_id.bls {
252 PublicKey::BlsShare(key)
253 } else {
254 PublicKey::Ed25519(self.public_id.ed25519)
255 }
256 }
257
258 pub fn public_id(&self) -> &PublicId {
260 &self.public_id
261 }
262
263 pub fn public_key_set(&self) -> Option<&PublicKeySet> {
265 self.bls.as_ref().map(|s| &s.public_key_set)
266 }
267
268 pub fn sign(&self, data: &[u8]) -> Signature {
270 if let Some(sig) = self.sign_using_bls(data) {
271 sig
272 } else {
273 self.sign_using_ed25519(data)
274 }
275 }
276
277 pub fn sign_using_ed25519<T: AsRef<[u8]>>(&self, data: T) -> Signature {
279 Signature::Ed25519(self.ed25519.sign(data.as_ref()))
280 }
281
282 pub fn sign_using_bls<T: AsRef<[u8]>>(&self, data: T) -> Option<Signature> {
284 self.bls.as_ref().map(|keys| {
285 Signature::BlsShare(SignatureShare {
286 index: keys.index,
287 share: keys.secret.inner().sign(data),
288 })
289 })
290 }
291
292 pub fn set_bls_keys(
294 &mut self,
295 index: usize,
296 secret_share: BlsSecretKeyShare,
297 public_set: PublicKeySet,
298 ) {
299 let public = secret_share.public_key_share();
300 let secret = SerdeSecret(secret_share);
301 self.public_id.bls = Some(public);
302 self.bls = Some(BlsKeypairShare {
303 index,
304 secret,
305 public,
306 public_key_set: public_set,
307 });
308 }
309
310 pub fn clear_bls_keys(&mut self) {
312 self.public_id.bls = None;
313 self.bls = None;
314 }
315}