1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
use crate::keys::{BlsKeypairShare, SignatureShare};
use crate::{PublicKey, Signature};
use ed25519_dalek::Keypair as Ed25519Keypair;
use rand::{CryptoRng, Rng};
use serde::{Deserialize, Serialize};
use signature::Signer;
use threshold_crypto::{
serde_impl::SerdeSecret, PublicKeySet, SecretKeyShare as BlsSecretKeyShare,
};
use xor_name::XorName;
#[derive(Serialize, Deserialize)]
pub struct NodeKeypairs {
ed25519: Ed25519Keypair,
bls: Option<BlsKeypairShare>,
}
impl NodeKeypairs {
pub fn new<T: CryptoRng + Rng>(rng: &mut T) -> Self {
let ed25519 = Ed25519Keypair::generate(rng);
Self { ed25519, bls: None }
}
pub fn within_range<T: CryptoRng + Rng>(start: &XorName, end: &XorName, rng: &mut T) -> Self {
let mut ed25519 = Ed25519Keypair::generate(rng);
loop {
let name: XorName = PublicKey::Ed25519(ed25519.public).into();
if name >= *start && name <= *end {
return Self { ed25519, bls: None };
}
ed25519 = Ed25519Keypair::generate(rng);
}
}
pub fn public_key(&self) -> PublicKey {
if let Some(keys) = &self.bls {
PublicKey::BlsShare(keys.public)
} else {
PublicKey::Ed25519(self.ed25519.public)
}
}
pub fn public_key_set(&self) -> Option<&PublicKeySet> {
self.bls.as_ref().map(|s| &s.public_key_set)
}
pub fn sign(&self, data: &[u8]) -> Signature {
if let Some(sig) = self.sign_using_bls(data) {
sig
} else {
self.sign_using_ed25519(data)
}
}
pub fn sign_using_ed25519<T: AsRef<[u8]>>(&self, data: T) -> Signature {
Signature::Ed25519(self.ed25519.sign(data.as_ref()))
}
pub fn sign_using_bls<T: AsRef<[u8]>>(&self, data: T) -> Option<Signature> {
self.bls.as_ref().map(|keys| {
Signature::BlsShare(SignatureShare {
index: keys.index,
share: keys.secret.inner().sign(data),
})
})
}
pub fn set_bls_keys(
&mut self,
index: usize,
secret_share: BlsSecretKeyShare,
public_set: PublicKeySet,
) {
let public = secret_share.public_key_share();
let secret = SerdeSecret(secret_share);
self.bls = Some(BlsKeypairShare {
index,
secret,
public,
public_key_set: public_set,
});
}
pub fn clear_bls_keys(&mut self) {
self.bls = None;
}
}