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
#[cfg(feature = "signatory-dalek")]
use crate::public_key::PublicKey;
use serde::{de, de::Error as _, ser, Deserialize, Serialize};
use signatory::ed25519;
#[cfg(feature = "signatory-dalek")]
use signatory::PublicKeyed;
#[cfg(feature = "signatory-dalek")]
use signatory_dalek::Ed25519Signer;
use subtle_encoding::{Base64, Encoding};
use zeroize::{Zeroize, Zeroizing};
pub const ED25519_KEYPAIR_SIZE: usize = 64;
#[derive(Serialize, Deserialize)]
#[serde(tag = "type", content = "value")]
pub enum PrivateKey {
#[serde(rename = "tendermint/PrivKeyEd25519")]
Ed25519(Ed25519Keypair),
}
impl PrivateKey {
#[cfg(feature = "signatory-dalek")]
pub fn public_key(&self) -> PublicKey {
match self {
PrivateKey::Ed25519(private_key) => private_key.public_key(),
}
}
pub fn ed25519_keypair(&self) -> Option<&Ed25519Keypair> {
match self {
PrivateKey::Ed25519(keypair) => Some(keypair),
}
}
}
#[derive(Zeroize)]
#[zeroize(drop)]
pub struct Ed25519Keypair([u8; ED25519_KEYPAIR_SIZE]);
impl Ed25519Keypair {
#[cfg(feature = "signatory-dalek")]
pub fn public_key(&self) -> PublicKey {
let seed = ed25519::Seed::from_keypair(&self.0[..]).unwrap();
let pk = signatory_dalek::Ed25519Signer::from(&seed)
.public_key()
.unwrap();
PublicKey::from(pk)
}
pub fn to_seed(&self) -> ed25519::Seed {
ed25519::Seed::from(self)
}
#[cfg(feature = "signatory-dalek")]
pub fn to_signer(&self) -> Ed25519Signer {
Ed25519Signer::from(&self.to_seed())
}
}
impl<'a> From<&'a Ed25519Keypair> for ed25519::Seed {
fn from(keypair: &'a Ed25519Keypair) -> ed25519::Seed {
ed25519::Seed::from_keypair(&keypair.0[..]).unwrap()
}
}
impl<'de> Deserialize<'de> for Ed25519Keypair {
fn deserialize<D: de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
let string = Zeroizing::new(String::deserialize(deserializer)?);
let mut keypair_bytes = [0u8; ED25519_KEYPAIR_SIZE];
let decoded_len = Base64::default()
.decode_to_slice(string.as_bytes(), &mut keypair_bytes)
.map_err(|_| D::Error::custom("invalid Ed25519 keypair"))?;
if decoded_len != ED25519_KEYPAIR_SIZE {
return Err(D::Error::custom("invalid Ed25519 keypair size"));
}
Ok(Ed25519Keypair(keypair_bytes))
}
}
impl Serialize for Ed25519Keypair {
fn serialize<S: ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
String::from_utf8(Base64::default().encode(&self.0[..]))
.unwrap()
.serialize(serializer)
}
}