fluence_keypair/
key_pair.rs1use crate::ed25519;
23use crate::error::{DecodingError, Error, SigningError, VerificationError};
24use crate::public_key::PublicKey;
25#[cfg(not(target_arch = "wasm32"))]
26use crate::rsa;
27use crate::secp256k1;
28use crate::signature::Signature;
29use libp2p_identity::{KeyType, Keypair, PeerId};
30use std::convert::TryFrom;
31use std::str::FromStr;
32
33#[derive(Debug, Clone, Copy, PartialEq, Eq)]
51pub enum KeyFormat {
52 Ed25519,
53 #[cfg(not(target_arch = "wasm32"))]
54 Rsa,
55 Secp256k1,
56}
57
58impl FromStr for KeyFormat {
59 type Err = Error;
60
61 #[inline]
62 fn from_str(s: &str) -> Result<Self, Self::Err> {
63 match s {
64 "ed25519" => Ok(KeyFormat::Ed25519),
65 "secp256k1" => Ok(KeyFormat::Secp256k1),
66 #[cfg(not(target_arch = "wasm32"))]
67 "rsa" => Ok(KeyFormat::Rsa),
68 _ => Err(Error::InvalidKeyFormat(s.to_string())),
69 }
70 }
71}
72
73impl TryFrom<u8> for KeyFormat {
74 type Error = DecodingError;
75
76 fn try_from(value: u8) -> Result<Self, Self::Error> {
77 match value {
78 0 => Ok(KeyFormat::Ed25519),
79 #[cfg(not(target_arch = "wasm32"))]
80 1 => Ok(KeyFormat::Rsa),
81 2 => Ok(KeyFormat::Secp256k1),
82 _ => Err(DecodingError::InvalidTypeByte),
83 }
84 }
85}
86
87impl From<KeyFormat> for u8 {
88 fn from(kf: KeyFormat) -> Self {
89 match kf {
90 KeyFormat::Ed25519 => 0,
91 #[cfg(not(target_arch = "wasm32"))]
92 KeyFormat::Rsa => 1,
93 KeyFormat::Secp256k1 => 2,
94 }
95 }
96}
97
98impl From<KeyFormat> for String {
99 fn from(kf: KeyFormat) -> Self {
100 match kf {
101 KeyFormat::Ed25519 => "ed25519".to_string(),
102 #[cfg(not(target_arch = "wasm32"))]
103 KeyFormat::Rsa => "rsa".to_string(),
104 KeyFormat::Secp256k1 => "secp256k1".to_string(),
105 }
106 }
107}
108
109#[derive(Clone)]
110pub enum KeyPair {
111 Ed25519(ed25519::Keypair),
113 #[cfg(not(target_arch = "wasm32"))]
114 Rsa(rsa::Keypair),
116 Secp256k1(secp256k1::Keypair),
118}
119
120impl KeyPair {
121 pub fn generate(format: KeyFormat) -> KeyPair {
122 match format {
123 KeyFormat::Ed25519 => KeyPair::generate_ed25519(),
124 KeyFormat::Secp256k1 => KeyPair::generate_secp256k1(),
125 #[cfg(not(target_arch = "wasm32"))]
126 KeyFormat::Rsa => todo!("rsa generation is not supported yet!"),
127 }
128 }
129
130 pub fn generate_ed25519() -> KeyPair {
132 KeyPair::Ed25519(ed25519::Keypair::generate())
133 }
134
135 pub fn generate_secp256k1() -> KeyPair {
137 KeyPair::Secp256k1(secp256k1::Keypair::generate())
138 }
139
140 #[cfg(not(target_arch = "wasm32"))]
145 pub fn rsa_from_pkcs8(pkcs8_der: &mut [u8]) -> Result<KeyPair, DecodingError> {
146 rsa::Keypair::from_pkcs8(pkcs8_der).map(KeyPair::Rsa)
147 }
148
149 pub fn secp256k1_from_der(der: &mut [u8]) -> Result<KeyPair, DecodingError> {
154 secp256k1::SecretKey::from_der(der)
155 .map(|sk| KeyPair::Secp256k1(secp256k1::Keypair::from(sk)))
156 }
157
158 pub fn sign(&self, msg: &[u8]) -> Result<Signature, SigningError> {
161 use KeyPair::*;
162 match self {
163 Ed25519(ref pair) => Ok(Signature::Ed25519(ed25519::Signature(pair.sign(msg)?))),
164 #[cfg(not(target_arch = "wasm32"))]
165 Rsa(ref pair) => Ok(Signature::Rsa(rsa::Signature(pair.sign(msg)?))),
166 Secp256k1(ref pair) => Ok(Signature::Secp256k1(secp256k1::Signature(
167 pair.secret().sign(msg)?,
168 ))),
169 }
170 }
171
172 pub fn key_format(&self) -> KeyFormat {
174 use KeyPair::*;
175
176 match self {
177 Ed25519(_) => KeyFormat::Ed25519,
178 #[cfg(not(target_arch = "wasm32"))]
179 Rsa(_) => KeyFormat::Rsa,
180 Secp256k1(_) => KeyFormat::Secp256k1,
181 }
182 }
183
184 pub fn public(&self) -> PublicKey {
186 use KeyPair::*;
187 match self {
188 Ed25519(pair) => PublicKey::Ed25519(pair.public()),
189 #[cfg(not(target_arch = "wasm32"))]
190 Rsa(pair) => PublicKey::Rsa(pair.public()),
191 Secp256k1(pair) => PublicKey::Secp256k1(pair.public().clone()),
192 }
193 }
194
195 pub fn secret(&self) -> eyre::Result<Vec<u8>> {
196 use KeyPair::*;
197 match self {
198 Ed25519(pair) => Ok(pair.secret().0.to_vec()),
199 #[cfg(not(target_arch = "wasm32"))]
200 Rsa(_) => Err(eyre::eyre!("secret key is not available for RSA")),
201 Secp256k1(pair) => Ok(pair.secret().to_bytes().to_vec()),
202 }
203 }
204
205 pub fn verify(
207 pk: &PublicKey,
208 msg: &[u8],
209 signature: &Signature,
210 ) -> Result<(), VerificationError> {
211 pk.verify(msg, signature)
212 }
213
214 pub fn to_vec(&self) -> Vec<u8> {
215 use KeyPair::*;
216 match self {
217 Ed25519(kp) => kp.encode().to_vec(),
218 #[cfg(not(target_arch = "wasm32"))]
219 Rsa(_) => todo!("rsa encoding is not supported yet!"),
220 Secp256k1(kp) => kp.secret().to_bytes().to_vec(),
221 }
222 }
223
224 pub fn from_vec(mut bytes: Vec<u8>, format: KeyFormat) -> Result<Self, DecodingError> {
225 use KeyPair::*;
226
227 match format {
228 KeyFormat::Ed25519 => Ok(Ed25519(ed25519::Keypair::decode(&mut bytes)?)),
229 KeyFormat::Secp256k1 => Ok(Secp256k1(secp256k1::SecretKey::from_bytes(bytes)?.into())),
230 #[cfg(not(target_arch = "wasm32"))]
231 KeyFormat::Rsa => Err(DecodingError::KeypairDecodingIsNotSupported),
232 }
233 }
234
235 pub fn from_secret_key(bytes: Vec<u8>, format: KeyFormat) -> Result<Self, DecodingError> {
236 use KeyPair::*;
237
238 match format {
239 KeyFormat::Ed25519 => Ok(Ed25519(ed25519::SecretKey::from_bytes(bytes)?.into())),
240 KeyFormat::Secp256k1 => Ok(Secp256k1(secp256k1::SecretKey::from_bytes(bytes)?.into())),
241 #[cfg(not(target_arch = "wasm32"))]
242 KeyFormat::Rsa => Err(DecodingError::KeypairDecodingIsNotSupported),
243 }
244 }
245
246 pub fn get_peer_id(&self) -> PeerId {
247 self.public().to_peer_id()
248 }
249}
250
251impl From<libp2p_identity::Keypair> for KeyPair {
252 fn from(key: libp2p_identity::Keypair) -> Self {
253 fn convert_keypair(key: Keypair) -> eyre::Result<KeyPair> {
254 match key.key_type() {
255 KeyType::Ed25519 => {
256 let kp = key.try_into_ed25519()?;
257 let raw_kp = ed25519::Keypair::decode(&mut kp.to_bytes())?;
258 Ok(KeyPair::Ed25519(raw_kp))
259 }
260 #[cfg(not(target_arch = "wasm32"))]
261 KeyType::RSA => {
262 let kp = key.try_into_rsa()?;
263 let raw_kp = unsafe {
264 std::mem::transmute::<libp2p_identity::rsa::Keypair, rsa::Keypair>(kp)
265 };
266 Ok(KeyPair::Rsa(raw_kp))
267 }
268 KeyType::Secp256k1 => {
269 let kp = key.try_into_secp256k1()?;
270 let raw_kp = secp256k1::SecretKey::from_bytes(kp.secret().to_bytes())?;
271 Ok(KeyPair::Secp256k1(secp256k1::Keypair::from(raw_kp)))
272 }
273 _ => unreachable!(),
274 }
275 }
276
277 convert_keypair(key).expect("Could not convert keypair")
278 }
279}
280
281impl From<KeyPair> for libp2p_identity::Keypair {
282 fn from(key: KeyPair) -> Self {
283 fn convert_keypair(key: KeyPair) -> eyre::Result<libp2p_identity::Keypair> {
284 match key {
285 KeyPair::Ed25519(kp) => {
286 let secret_bytes = kp.secret().0;
288 let kp = libp2p_identity::Keypair::ed25519_from_bytes(secret_bytes)?;
289 Ok(kp)
290 }
291 #[cfg(not(target_arch = "wasm32"))]
292 KeyPair::Rsa(kp) => {
294 let kp = unsafe {
295 std::mem::transmute::<rsa::Keypair, libp2p_identity::rsa::Keypair>(kp)
296 };
297 let kp = Keypair::from(kp);
298 Ok(kp)
299 }
300 KeyPair::Secp256k1(kp) => {
301 let sk = libp2p_identity::secp256k1::SecretKey::try_from_bytes(
302 kp.secret().to_bytes(),
303 )?;
304 let kp = libp2p_identity::secp256k1::Keypair::from(sk);
305 let kp = Keypair::from(kp);
306 Ok(kp)
307 }
308 }
309 }
310 convert_keypair(key).expect("Could not convert key pair")
311 }
312}