1mod proof;
17
18use crate::{utils, Error, Result};
19use hex_fmt::HexFmt;
20pub use proof::{BlsProof, BlsProofShare, Ed25519Proof, Proof, Proven};
21use rand::{CryptoRng, Rng};
22use serde::{Deserialize, Serialize};
23use signature::{Signer, Verifier};
24use std::{
25 cmp::Ordering,
26 fmt::{self, Debug, Display, Formatter},
27 hash::{Hash, Hasher},
28};
29use threshold_crypto::{self, serde_impl::SerdeSecret};
30use unwrap::unwrap;
31use xor_name::{XorName, XOR_NAME_LEN};
32
33#[derive(Clone, Copy, Eq, PartialEq, Serialize, Deserialize)]
35pub enum PublicKey {
36 Ed25519(ed25519_dalek::PublicKey),
38 Bls(threshold_crypto::PublicKey),
40 BlsShare(threshold_crypto::PublicKeyShare),
42}
43
44impl PublicKey {
45 pub fn ed25519(&self) -> Option<ed25519_dalek::PublicKey> {
47 if let Self::Ed25519(key) = self {
48 Some(*key)
49 } else {
50 None
51 }
52 }
53
54 pub fn bls(&self) -> Option<threshold_crypto::PublicKey> {
56 if let Self::Bls(key) = self {
57 Some(*key)
58 } else {
59 None
60 }
61 }
62
63 pub fn bls_share(&self) -> Option<threshold_crypto::PublicKeyShare> {
65 if let Self::BlsShare(key) = self {
66 Some(*key)
67 } else {
68 None
69 }
70 }
71
72 pub fn verify<T: AsRef<[u8]>>(&self, signature: &Signature, data: T) -> Result<()> {
75 let is_valid = match (self, signature) {
76 (Self::Ed25519(pub_key), Signature::Ed25519(sig)) => {
77 pub_key.verify(data.as_ref(), sig).is_ok()
78 }
79 (Self::Bls(pub_key), Signature::Bls(sig)) => pub_key.verify(sig, data),
80 (Self::BlsShare(pub_key), Signature::BlsShare(sig)) => pub_key.verify(&sig.share, data),
81 _ => return Err(Error::SigningKeyTypeMismatch),
82 };
83 if is_valid {
84 Ok(())
85 } else {
86 Err(Error::InvalidSignature)
87 }
88 }
89
90 pub fn encode_to_zbase32(&self) -> String {
92 utils::encode(&self)
93 }
94
95 pub fn decode_from_zbase32<I: AsRef<str>>(encoded: I) -> Result<Self> {
97 utils::decode(encoded)
98 }
99}
100
101#[allow(clippy::derive_hash_xor_eq)]
102impl Hash for PublicKey {
103 fn hash<H: Hasher>(&self, state: &mut H) {
104 utils::serialise(&self).hash(state)
105 }
106}
107
108impl Ord for PublicKey {
109 fn cmp(&self, other: &PublicKey) -> Ordering {
110 utils::serialise(&self).cmp(&utils::serialise(other))
111 }
112}
113
114impl PartialOrd for PublicKey {
115 fn partial_cmp(&self, other: &PublicKey) -> Option<Ordering> {
116 Some(self.cmp(other))
117 }
118}
119
120impl From<PublicKey> for XorName {
121 fn from(public_key: PublicKey) -> Self {
122 let bytes = match public_key {
123 PublicKey::Ed25519(pub_key) => {
124 return XorName(pub_key.to_bytes());
125 }
126 PublicKey::Bls(pub_key) => pub_key.to_bytes(),
127 PublicKey::BlsShare(pub_key) => pub_key.to_bytes(),
128 };
129 let mut xor_name = XorName::random();
130 xor_name.0.clone_from_slice(&bytes[..XOR_NAME_LEN]);
131 xor_name
132 }
133}
134
135impl From<ed25519_dalek::PublicKey> for PublicKey {
136 fn from(public_key: ed25519_dalek::PublicKey) -> Self {
137 Self::Ed25519(public_key)
138 }
139}
140
141impl From<threshold_crypto::PublicKey> for PublicKey {
142 fn from(public_key: threshold_crypto::PublicKey) -> Self {
143 Self::Bls(public_key)
144 }
145}
146
147impl From<threshold_crypto::PublicKeyShare> for PublicKey {
148 fn from(public_key: threshold_crypto::PublicKeyShare) -> Self {
149 Self::BlsShare(public_key)
150 }
151}
152
153impl From<&Keypair> for PublicKey {
154 fn from(keypair: &Keypair) -> Self {
155 keypair.public_key()
156 }
157}
158
159impl Debug for PublicKey {
160 fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
161 write!(formatter, "PublicKey::")?;
162 match self {
163 Self::Ed25519(pub_key) => {
164 write!(formatter, "Ed25519({:<8})", HexFmt(&pub_key.to_bytes()))
165 }
166 Self::Bls(pub_key) => write!(
167 formatter,
168 "Bls({:<8})",
169 HexFmt(&pub_key.to_bytes()[..XOR_NAME_LEN])
170 ),
171 Self::BlsShare(pub_key) => write!(
172 formatter,
173 "BlsShare({:<8})",
174 HexFmt(&pub_key.to_bytes()[..XOR_NAME_LEN])
175 ),
176 }
177 }
178}
179
180impl Display for PublicKey {
181 fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
182 Debug::fmt(self, formatter)
183 }
184}
185
186#[derive(Clone, Hash, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Debug)]
188pub struct SignatureShare {
189 pub index: usize,
191 pub share: threshold_crypto::SignatureShare,
193}
194
195#[derive(Clone, Eq, PartialEq, Serialize, Deserialize)]
197#[allow(clippy::large_enum_variant)]
198pub enum Signature {
199 Ed25519(ed25519_dalek::Signature),
201 Bls(threshold_crypto::Signature),
203 BlsShare(SignatureShare),
205}
206
207impl Signature {
208 pub fn into_bls(self) -> Option<threshold_crypto::Signature> {
210 match self {
211 Self::Bls(sig) => Some(sig),
212 _ => None,
213 }
214 }
215}
216
217impl From<threshold_crypto::Signature> for Signature {
218 fn from(sig: threshold_crypto::Signature) -> Self {
219 Self::Bls(sig)
220 }
221}
222
223impl From<ed25519_dalek::Signature> for Signature {
224 fn from(sig: ed25519_dalek::Signature) -> Self {
225 Self::Ed25519(sig)
226 }
227}
228
229impl From<SignatureShare> for Signature {
230 fn from(sig: SignatureShare) -> Self {
231 Self::BlsShare(sig)
232 }
233}
234
235impl From<(usize, threshold_crypto::SignatureShare)> for Signature {
236 fn from(sig: (usize, threshold_crypto::SignatureShare)) -> Self {
237 let (index, share) = sig;
238 Self::BlsShare(SignatureShare { index, share })
239 }
240}
241
242#[allow(clippy::derive_hash_xor_eq)]
243impl Hash for Signature {
244 fn hash<H: Hasher>(&self, state: &mut H) {
245 utils::serialise(&self).hash(state)
246 }
247}
248
249impl Ord for Signature {
250 fn cmp(&self, other: &Signature) -> Ordering {
251 utils::serialise(&self).cmp(&utils::serialise(other))
252 }
253}
254
255impl PartialOrd for Signature {
256 fn partial_cmp(&self, other: &Signature) -> Option<Ordering> {
257 Some(self.cmp(other))
258 }
259}
260
261impl Debug for Signature {
262 fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
263 write!(formatter, "Signature::")?;
264 match self {
265 Self::Ed25519(_) => write!(formatter, "Ed25519(..)"),
266 Self::Bls(_) => write!(formatter, "Bls(..)"),
267 Self::BlsShare(_) => write!(formatter, "BlsShare(..)"),
268 }
269 }
270}
271
272#[derive(Serialize, Deserialize)]
274pub enum Keypair {
275 Ed25519(ed25519_dalek::Keypair),
277 Bls(BlsKeypair),
279 BlsShare(BlsKeypairShare),
281}
282
283impl Clone for Keypair {
285 fn clone(&self) -> Self {
286 match self {
287 Self::Ed25519(keypair) => Self::Ed25519(unwrap!(ed25519_dalek::Keypair::from_bytes(
288 &keypair.to_bytes()
289 ))),
290 Self::Bls(keypair) => Self::Bls(keypair.clone()),
291 Self::BlsShare(keypair) => Self::BlsShare(keypair.clone()),
292 }
293 }
294}
295
296impl Debug for Keypair {
297 fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
298 write!(formatter, "Keypair::")?;
299 match self {
300 Self::Ed25519(_) => write!(formatter, "Ed25519(..)"),
301 Self::Bls(_) => write!(formatter, "Bls(..)"),
302 Self::BlsShare(_) => write!(formatter, "BlsShare(..)"),
303 }
304 }
305}
306
307impl PartialEq for Keypair {
309 fn eq(&self, other: &Self) -> bool {
310 match (self, other) {
311 (Self::Ed25519(keypair), Self::Ed25519(other_keypair)) => {
312 keypair.to_bytes().to_vec() == other_keypair.to_bytes().to_vec()
314 }
315 (Self::Bls(keypair), Self::Bls(other_keypair)) => keypair == other_keypair,
316 (Self::BlsShare(keypair), Self::BlsShare(other_keypair)) => keypair == other_keypair,
317 _ => false,
318 }
319 }
320}
321
322impl Eq for Keypair {}
324
325impl Keypair {
326 pub fn new_ed25519<T: CryptoRng + Rng>(rng: &mut T) -> Self {
328 let keypair = ed25519_dalek::Keypair::generate(rng);
329 Self::Ed25519(keypair)
330 }
331
332 pub fn new_bls<T: CryptoRng + Rng>(rng: &mut T) -> Self {
334 let bls_secret_key: threshold_crypto::SecretKey = rng.gen();
335 let bls_public_key = bls_secret_key.public_key();
336 let keypair = BlsKeypair {
337 secret: SerdeSecret(bls_secret_key),
338 public: bls_public_key,
339 };
340 Self::Bls(keypair)
341 }
342
343 pub fn new_bls_share(
345 index: usize,
346 secret_share: threshold_crypto::SecretKeyShare,
347 public_key_set: threshold_crypto::PublicKeySet,
348 ) -> Self {
349 let public_share = secret_share.public_key_share();
350 let keypair_share = BlsKeypairShare {
351 index,
352 secret: SerdeSecret(secret_share),
353 public: public_share,
354 public_key_set,
355 };
356 Self::BlsShare(keypair_share)
357 }
358
359 pub fn public_key(&self) -> PublicKey {
361 match self {
362 Self::Ed25519(keypair) => PublicKey::Ed25519(keypair.public),
363 Self::Bls(keypair) => PublicKey::Bls(keypair.public),
364 Self::BlsShare(keypair) => PublicKey::BlsShare(keypair.public),
365 }
366 }
367
368 pub fn sign(&self, data: &[u8]) -> Signature {
370 match self {
371 Self::Ed25519(keypair) => Signature::Ed25519(keypair.sign(&data)),
372 Self::Bls(keypair) => Signature::Bls(keypair.secret.sign(data)),
373 Self::BlsShare(keypair) => {
374 let index = keypair.index;
375 let share = keypair.secret.sign(data);
376 Signature::BlsShare(SignatureShare { index, share })
377 }
378 }
379 }
380}
381
382#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
384pub struct BlsKeypair {
385 pub secret: SerdeSecret<threshold_crypto::SecretKey>,
387 pub public: threshold_crypto::PublicKey,
389}
390
391#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
393pub struct BlsKeypairShare {
394 pub index: usize,
396 pub secret: SerdeSecret<threshold_crypto::SecretKeyShare>,
398 pub public: threshold_crypto::PublicKeyShare,
400 pub public_key_set: threshold_crypto::PublicKeySet,
402}
403
404#[cfg(test)]
405mod tests {
406 use super::*;
407 use crate::utils;
408 use bincode::deserialize as deserialise;
409 use threshold_crypto::{self};
410
411 fn gen_keypairs() -> Vec<Keypair> {
412 let mut rng = rand::thread_rng();
413 let bls_secret_key = threshold_crypto::SecretKeySet::random(1, &mut rng);
414 vec![
415 Keypair::new_ed25519(&mut rng),
416 Keypair::new_bls(&mut rng),
417 Keypair::new_bls_share(
418 0,
419 bls_secret_key.secret_key_share(0),
420 bls_secret_key.public_keys(),
421 ),
422 ]
423 }
424
425 fn gen_keys() -> Vec<PublicKey> {
426 gen_keypairs().iter().map(PublicKey::from).collect()
427 }
428
429 #[test]
430 fn zbase32_encode_decode_public_key() {
431 use unwrap::unwrap;
432
433 let keys = gen_keys();
434
435 for key in keys {
436 assert_eq!(
437 key,
438 unwrap!(PublicKey::decode_from_zbase32(&key.encode_to_zbase32()))
439 );
440 }
441 }
442
443 #[test]
445 fn serialisation_public_key() {
446 let keys = gen_keys();
447
448 for key in keys {
449 let encoded = utils::serialise(&key);
450 let decoded: PublicKey = unwrap!(deserialise(&encoded));
451
452 assert_eq!(decoded, key);
453 }
454 }
455
456 #[test]
458 fn serialisation_key_pair() {
459 let keypairs = gen_keypairs();
460
461 for keypair in keypairs {
462 let encoded = utils::serialise(&keypair);
463 let decoded: Keypair = unwrap!(deserialise(&encoded));
464
465 assert_eq!(decoded, keypair);
466 }
467 }
468}