1pub mod ed25519;
24#[cfg(not(target_arch = "wasm32"))]
25pub mod rsa;
26#[cfg(feature = "secp256k1")]
27pub mod secp256k1;
28
29pub mod error;
30
31use self::error::*;
32use crate::{PeerId, keys_proto};
33
34#[derive(Clone)]
52pub enum Keypair {
53 Ed25519(ed25519::Keypair),
55 #[cfg(not(target_arch = "wasm32"))]
56 Rsa(rsa::Keypair),
58 #[cfg(feature = "secp256k1")]
60 Secp256k1(secp256k1::Keypair)
61}
62
63impl Keypair {
64 pub fn generate_ed25519() -> Keypair {
66 Keypair::Ed25519(ed25519::Keypair::generate())
67 }
68
69 #[cfg(feature = "secp256k1")]
71 pub fn generate_secp256k1() -> Keypair {
72 Keypair::Secp256k1(secp256k1::Keypair::generate())
73 }
74
75 #[cfg(not(target_arch = "wasm32"))]
80 pub fn rsa_from_pkcs8(pkcs8_der: &mut [u8]) -> Result<Keypair, DecodingError> {
81 rsa::Keypair::from_pkcs8(pkcs8_der).map(Keypair::Rsa)
82 }
83
84 #[cfg(feature = "secp256k1")]
89 pub fn secp256k1_from_der(der: &mut [u8]) -> Result<Keypair, DecodingError> {
90 secp256k1::SecretKey::from_der(der)
91 .map(|sk| Keypair::Secp256k1(secp256k1::Keypair::from(sk)))
92 }
93
94 pub fn sign(&self, msg: &[u8]) -> Result<Vec<u8>, SigningError> {
97 use Keypair::*;
98 match self {
99 Ed25519(ref pair) => Ok(pair.sign(msg)),
100 #[cfg(not(target_arch = "wasm32"))]
101 Rsa(ref pair) => pair.sign(msg),
102 #[cfg(feature = "secp256k1")]
103 Secp256k1(ref pair) => pair.secret().sign(msg)
104 }
105 }
106
107 pub fn public(&self) -> PublicKey {
109 use Keypair::*;
110 match self {
111 Ed25519(pair) => PublicKey::Ed25519(pair.public()),
112 #[cfg(not(target_arch = "wasm32"))]
113 Rsa(pair) => PublicKey::Rsa(pair.public()),
114 #[cfg(feature = "secp256k1")]
115 Secp256k1(pair) => PublicKey::Secp256k1(pair.public().clone()),
116 }
117 }
118}
119
120#[derive(Clone, Debug, PartialEq, Eq)]
122pub enum PublicKey {
123 Ed25519(ed25519::PublicKey),
125 #[cfg(not(target_arch = "wasm32"))]
126 Rsa(rsa::PublicKey),
128 #[cfg(feature = "secp256k1")]
129 Secp256k1(secp256k1::PublicKey)
131}
132
133impl PublicKey {
134 pub fn verify(&self, msg: &[u8], sig: &[u8]) -> bool {
139 use PublicKey::*;
140 match self {
141 Ed25519(pk) => pk.verify(msg, sig),
142 #[cfg(not(target_arch = "wasm32"))]
143 Rsa(pk) => pk.verify(msg, sig),
144 #[cfg(feature = "secp256k1")]
145 Secp256k1(pk) => pk.verify(msg, sig)
146 }
147 }
148
149 pub fn into_protobuf_encoding(self) -> Vec<u8> {
152 use prost::Message;
153
154 let public_key = match self {
155 PublicKey::Ed25519(key) =>
156 keys_proto::PublicKey {
157 r#type: keys_proto::KeyType::Ed25519 as i32,
158 data: key.encode().to_vec()
159 },
160 #[cfg(not(target_arch = "wasm32"))]
161 PublicKey::Rsa(key) =>
162 keys_proto::PublicKey {
163 r#type: keys_proto::KeyType::Rsa as i32,
164 data: key.encode_x509()
165 },
166 #[cfg(feature = "secp256k1")]
167 PublicKey::Secp256k1(key) =>
168 keys_proto::PublicKey {
169 r#type: keys_proto::KeyType::Secp256k1 as i32,
170 data: key.encode().to_vec()
171 }
172 };
173
174 let mut buf = Vec::with_capacity(public_key.encoded_len());
175 public_key.encode(&mut buf).expect("Vec<u8> provides capacity as needed");
176 buf
177 }
178
179 pub fn from_protobuf_encoding(bytes: &[u8]) -> Result<PublicKey, DecodingError> {
182 use prost::Message;
183
184 #[allow(unused_mut)] let mut pubkey = keys_proto::PublicKey::decode(bytes)
186 .map_err(|e| DecodingError::new("Protobuf").source(e))?;
187
188 let key_type = keys_proto::KeyType::from_i32(pubkey.r#type)
189 .ok_or_else(|| DecodingError::new(format!("unknown key type: {}", pubkey.r#type)))?;
190
191 match key_type {
192 keys_proto::KeyType::Ed25519 => {
193 ed25519::PublicKey::decode(&pubkey.data).map(PublicKey::Ed25519)
194 },
195 #[cfg(not(target_arch = "wasm32"))]
196 keys_proto::KeyType::Rsa => {
197 rsa::PublicKey::decode_x509(&pubkey.data).map(PublicKey::Rsa)
198 }
199 #[cfg(target_arch = "wasm32")]
200 keys_proto::KeyType::Rsa => {
201 log::debug!("support for RSA was disabled at compile-time");
202 Err(DecodingError::new("Unsupported"))
203 },
204 #[cfg(feature = "secp256k1")]
205 keys_proto::KeyType::Secp256k1 => {
206 secp256k1::PublicKey::decode(&pubkey.data).map(PublicKey::Secp256k1)
207 }
208 #[cfg(not(feature = "secp256k1"))]
209 keys_proto::KeyType::Secp256k1 => {
210 log::debug!("support for secp256k1 was disabled at compile-time");
211 Err("Unsupported".to_string().into())
212 }
213 }
214 }
215
216 pub fn into_peer_id(self) -> PeerId {
218 self.into()
219 }
220}
221