1#[cfg(any(
22 feature = "ecdsa",
23 feature = "secp256k1",
24 feature = "ed25519",
25 feature = "rsa"
26))]
27use prost::Message;
28
29#[cfg(feature = "ecdsa")]
30use crate::ecdsa;
31#[cfg(any(
32 feature = "ecdsa",
33 feature = "secp256k1",
34 feature = "ed25519",
35 feature = "rsa"
36))]
37#[cfg(feature = "ed25519")]
38use crate::ed25519;
39#[cfg(any(
40 feature = "ecdsa",
41 feature = "secp256k1",
42 feature = "ed25519",
43 feature = "rsa"
44))]
45use crate::error::OtherVariantError;
46#[cfg(any(
47 feature = "ecdsa",
48 feature = "secp256k1",
49 feature = "ed25519",
50 feature = "rsa"
51))]
52use crate::proto;
53#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
54use crate::rsa;
55#[cfg(feature = "secp256k1")]
56use crate::secp256k1;
57use crate::{
58 error::{DecodingError, SigningError},
59 KeyType,
60};
61
62#[derive(Debug, Clone)]
79pub struct Keypair {
80 keypair: KeyPairInner,
81}
82
83#[derive(Debug, Clone)]
84#[allow(clippy::large_enum_variant)]
85enum KeyPairInner {
86 #[cfg(feature = "ed25519")]
88 Ed25519(ed25519::Keypair),
89 #[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
91 Rsa(rsa::Keypair),
92 #[cfg(feature = "secp256k1")]
94 Secp256k1(secp256k1::Keypair),
95 #[cfg(feature = "ecdsa")]
97 Ecdsa(ecdsa::Keypair),
98}
99
100impl Keypair {
101 #[cfg(all(feature = "ed25519", feature = "rand"))]
103 pub fn generate_ed25519() -> Keypair {
104 Keypair {
105 keypair: KeyPairInner::Ed25519(ed25519::Keypair::generate()),
106 }
107 }
108
109 #[cfg(all(feature = "secp256k1", feature = "rand"))]
111 pub fn generate_secp256k1() -> Keypair {
112 Keypair {
113 keypair: KeyPairInner::Secp256k1(secp256k1::Keypair::generate()),
114 }
115 }
116
117 #[cfg(all(feature = "ecdsa", feature = "rand"))]
119 pub fn generate_ecdsa() -> Keypair {
120 Keypair {
121 keypair: KeyPairInner::Ecdsa(ecdsa::Keypair::generate()),
122 }
123 }
124
125 #[cfg(feature = "ed25519")]
126 pub fn try_into_ed25519(self) -> Result<ed25519::Keypair, OtherVariantError> {
127 self.try_into()
128 }
129
130 #[cfg(feature = "secp256k1")]
131 pub fn try_into_secp256k1(self) -> Result<secp256k1::Keypair, OtherVariantError> {
132 self.try_into()
133 }
134
135 #[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
136 pub fn try_into_rsa(self) -> Result<rsa::Keypair, OtherVariantError> {
137 self.try_into()
138 }
139
140 #[cfg(feature = "ecdsa")]
141 pub fn try_into_ecdsa(self) -> Result<ecdsa::Keypair, OtherVariantError> {
142 self.try_into()
143 }
144
145 #[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
150 pub fn rsa_from_pkcs8(pkcs8_der: &mut [u8]) -> Result<Keypair, DecodingError> {
151 rsa::Keypair::try_decode_pkcs8(pkcs8_der).map(|kp| Keypair {
152 keypair: KeyPairInner::Rsa(kp),
153 })
154 }
155
156 #[cfg(feature = "secp256k1")]
161 pub fn secp256k1_from_der(der: &mut [u8]) -> Result<Keypair, DecodingError> {
162 secp256k1::SecretKey::from_der(der).map(|sk| Keypair {
163 keypair: KeyPairInner::Secp256k1(secp256k1::Keypair::from(sk)),
164 })
165 }
166
167 #[cfg(feature = "ed25519")]
168 pub fn ed25519_from_bytes(bytes: impl AsMut<[u8]>) -> Result<Keypair, DecodingError> {
169 Ok(Keypair {
170 keypair: KeyPairInner::Ed25519(ed25519::Keypair::from(
171 ed25519::SecretKey::try_from_bytes(bytes)?,
172 )),
173 })
174 }
175
176 #[allow(unused_variables)]
179 pub fn sign(&self, msg: &[u8]) -> Result<Vec<u8>, SigningError> {
180 match self.keypair {
181 #[cfg(feature = "ed25519")]
182 KeyPairInner::Ed25519(ref pair) => Ok(pair.sign(msg)),
183 #[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
184 KeyPairInner::Rsa(ref pair) => pair.sign(msg),
185 #[cfg(feature = "secp256k1")]
186 KeyPairInner::Secp256k1(ref pair) => Ok(pair.secret().sign(msg)),
187 #[cfg(feature = "ecdsa")]
188 KeyPairInner::Ecdsa(ref pair) => Ok(pair.secret().sign(msg)),
189 }
190 }
191
192 pub fn public(&self) -> PublicKey {
194 match self.keypair {
195 #[cfg(feature = "ed25519")]
196 KeyPairInner::Ed25519(ref pair) => PublicKey {
197 publickey: PublicKeyInner::Ed25519(pair.public()),
198 },
199 #[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
200 KeyPairInner::Rsa(ref pair) => PublicKey {
201 publickey: PublicKeyInner::Rsa(pair.public()),
202 },
203 #[cfg(feature = "secp256k1")]
204 KeyPairInner::Secp256k1(ref pair) => PublicKey {
205 publickey: PublicKeyInner::Secp256k1(pair.public().clone()),
206 },
207 #[cfg(feature = "ecdsa")]
208 KeyPairInner::Ecdsa(ref pair) => PublicKey {
209 publickey: PublicKeyInner::Ecdsa(pair.public().clone()),
210 },
211 }
212 }
213
214 pub fn to_protobuf_encoding(&self) -> Result<Vec<u8>, DecodingError> {
216 #[cfg(any(
217 feature = "ecdsa",
218 feature = "secp256k1",
219 feature = "ed25519",
220 feature = "rsa"
221 ))]
222 {
223 let pk: proto::PrivateKey = match self.keypair {
224 #[cfg(feature = "ed25519")]
225 KeyPairInner::Ed25519(ref data) => proto::PrivateKey {
226 r#type: proto::KeyType::Ed25519 as i32,
227 data: data.to_bytes().to_vec(),
228 },
229 #[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
230 KeyPairInner::Rsa(_) => return Err(DecodingError::encoding_unsupported("RSA")),
231 #[cfg(feature = "secp256k1")]
232 KeyPairInner::Secp256k1(ref data) => proto::PrivateKey {
233 r#type: proto::KeyType::Secp256k1 as i32,
234 data: data.secret().to_bytes().to_vec(),
235 },
236 #[cfg(feature = "ecdsa")]
237 KeyPairInner::Ecdsa(ref data) => proto::PrivateKey {
238 r#type: proto::KeyType::Ecdsa as i32,
239 data: data.secret().encode_der(),
240 },
241 };
242
243 Ok(pk.encode_to_vec())
244 }
245
246 #[cfg(not(any(
247 feature = "ecdsa",
248 feature = "secp256k1",
249 feature = "ed25519",
250 feature = "rsa"
251 )))]
252 unreachable!()
253 }
254
255 #[allow(unused_variables)]
257 pub fn from_protobuf_encoding(bytes: &[u8]) -> Result<Keypair, DecodingError> {
258 #[cfg(any(
259 feature = "ecdsa",
260 feature = "secp256k1",
261 feature = "ed25519",
262 feature = "rsa"
263 ))]
264 {
265 let mut private_key = proto::PrivateKey::decode(bytes)
266 .map_err(|e| DecodingError::bad_protobuf("private key bytes", e))
267 .map(zeroize::Zeroizing::new)?;
268
269 let key_type = proto::KeyType::try_from(private_key.r#type)
270 .map_err(|_| DecodingError::unknown_key_type(private_key.r#type))?;
271
272 #[allow(unreachable_code)]
273 match key_type {
274 proto::KeyType::Ed25519 => {
275 #[cfg(feature = "ed25519")]
276 return ed25519::Keypair::try_from_bytes(&mut private_key.data).map(|sk| {
277 Keypair {
278 keypair: KeyPairInner::Ed25519(sk),
279 }
280 });
281 Err(DecodingError::missing_feature("ed25519"))
282 }
283 proto::KeyType::Rsa => {
284 #[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
285 return rsa::Keypair::try_decode_pkcs1(&mut private_key.data).map(|sk| {
286 Keypair {
287 keypair: KeyPairInner::Rsa(sk),
288 }
289 });
290 Err(DecodingError::missing_feature("rsa"))
291 }
292 proto::KeyType::Secp256k1 => {
293 #[cfg(feature = "secp256k1")]
294 return secp256k1::SecretKey::try_from_bytes(&mut private_key.data).map(
295 |key| Keypair {
296 keypair: KeyPairInner::Secp256k1(key.into()),
297 },
298 );
299
300 Err(DecodingError::missing_feature("secp256k1"))
301 }
302 proto::KeyType::Ecdsa => {
303 #[cfg(feature = "ecdsa")]
304 return ecdsa::SecretKey::try_decode_der(&mut private_key.data).map(|key| {
305 Keypair {
306 keypair: KeyPairInner::Ecdsa(key.into()),
307 }
308 });
309
310 Err(DecodingError::missing_feature("ecdsa"))
311 }
312 }
313 }
314
315 #[cfg(not(any(
316 feature = "ecdsa",
317 feature = "secp256k1",
318 feature = "ed25519",
319 feature = "rsa"
320 )))]
321 unreachable!()
322 }
323
324 pub fn key_type(&self) -> KeyType {
326 match self.keypair {
327 #[cfg(feature = "ed25519")]
328 KeyPairInner::Ed25519(_) => KeyType::Ed25519,
329 #[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
330 KeyPairInner::Rsa(_) => KeyType::RSA,
331 #[cfg(feature = "secp256k1")]
332 KeyPairInner::Secp256k1(_) => KeyType::Secp256k1,
333 #[cfg(feature = "ecdsa")]
334 KeyPairInner::Ecdsa(_) => KeyType::Ecdsa,
335 }
336 }
337
338 #[cfg(any(
356 feature = "ecdsa",
357 feature = "secp256k1",
358 feature = "ed25519",
359 feature = "rsa"
360 ))]
361 pub fn derive_secret(&self, domain: &[u8]) -> Option<[u8; 32]> {
362 let mut okm = [0u8; 32];
363 hkdf::Hkdf::<sha2::Sha256>::new(None, &self.secret()?)
364 .expand(domain, &mut okm)
365 .expect("okm.len() == 32");
366
367 Some(okm)
368 }
369
370 #[cfg(not(any(
372 feature = "ecdsa",
373 feature = "secp256k1",
374 feature = "ed25519",
375 feature = "rsa"
376 )))]
377 pub fn derive_secret(&self, _: &[u8]) -> Option<[u8; 32]> {
378 None
379 }
380
381 #[allow(dead_code)]
383 pub(crate) fn secret(&self) -> Option<[u8; 32]> {
384 match self.keypair {
385 #[cfg(feature = "ed25519")]
386 KeyPairInner::Ed25519(ref inner) => Some(inner.secret().to_bytes()),
387 #[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
388 KeyPairInner::Rsa(_) => None,
389 #[cfg(feature = "secp256k1")]
390 KeyPairInner::Secp256k1(ref inner) => Some(inner.secret().to_bytes()),
391 #[cfg(feature = "ecdsa")]
392 KeyPairInner::Ecdsa(ref inner) => Some(
393 inner
394 .secret()
395 .to_bytes()
396 .try_into()
397 .expect("Ecdsa's private key should be 32 bytes"),
398 ),
399 }
400 }
401}
402
403#[cfg(feature = "ecdsa")]
404impl From<ecdsa::Keypair> for Keypair {
405 fn from(kp: ecdsa::Keypair) -> Self {
406 Keypair {
407 keypair: KeyPairInner::Ecdsa(kp),
408 }
409 }
410}
411
412#[cfg(feature = "ed25519")]
413impl From<ed25519::Keypair> for Keypair {
414 fn from(kp: ed25519::Keypair) -> Self {
415 Keypair {
416 keypair: KeyPairInner::Ed25519(kp),
417 }
418 }
419}
420
421#[cfg(feature = "secp256k1")]
422impl From<secp256k1::Keypair> for Keypair {
423 fn from(kp: secp256k1::Keypair) -> Self {
424 Keypair {
425 keypair: KeyPairInner::Secp256k1(kp),
426 }
427 }
428}
429
430#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
431impl From<rsa::Keypair> for Keypair {
432 fn from(kp: rsa::Keypair) -> Self {
433 Keypair {
434 keypair: KeyPairInner::Rsa(kp),
435 }
436 }
437}
438
439#[cfg(feature = "ed25519")]
440impl TryInto<ed25519::Keypair> for Keypair {
441 type Error = OtherVariantError;
442
443 fn try_into(self) -> Result<ed25519::Keypair, Self::Error> {
444 match self.keypair {
445 KeyPairInner::Ed25519(inner) => Ok(inner),
446 #[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
447 KeyPairInner::Rsa(_) => Err(OtherVariantError::new(crate::KeyType::RSA)),
448 #[cfg(feature = "secp256k1")]
449 KeyPairInner::Secp256k1(_) => Err(OtherVariantError::new(crate::KeyType::Secp256k1)),
450 #[cfg(feature = "ecdsa")]
451 KeyPairInner::Ecdsa(_) => Err(OtherVariantError::new(crate::KeyType::Ecdsa)),
452 }
453 }
454}
455
456#[cfg(feature = "ecdsa")]
457impl TryInto<ecdsa::Keypair> for Keypair {
458 type Error = OtherVariantError;
459
460 fn try_into(self) -> Result<ecdsa::Keypair, Self::Error> {
461 match self.keypair {
462 KeyPairInner::Ecdsa(inner) => Ok(inner),
463 #[cfg(feature = "ed25519")]
464 KeyPairInner::Ed25519(_) => Err(OtherVariantError::new(crate::KeyType::Ed25519)),
465 #[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
466 KeyPairInner::Rsa(_) => Err(OtherVariantError::new(crate::KeyType::RSA)),
467 #[cfg(feature = "secp256k1")]
468 KeyPairInner::Secp256k1(_) => Err(OtherVariantError::new(crate::KeyType::Secp256k1)),
469 }
470 }
471}
472
473#[cfg(feature = "secp256k1")]
474impl TryInto<secp256k1::Keypair> for Keypair {
475 type Error = OtherVariantError;
476
477 fn try_into(self) -> Result<secp256k1::Keypair, Self::Error> {
478 match self.keypair {
479 KeyPairInner::Secp256k1(inner) => Ok(inner),
480 #[cfg(feature = "ed25519")]
481 KeyPairInner::Ed25519(_) => Err(OtherVariantError::new(crate::KeyType::Ed25519)),
482 #[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
483 KeyPairInner::Rsa(_) => Err(OtherVariantError::new(crate::KeyType::RSA)),
484 #[cfg(feature = "ecdsa")]
485 KeyPairInner::Ecdsa(_) => Err(OtherVariantError::new(crate::KeyType::Ecdsa)),
486 }
487 }
488}
489
490#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
491impl TryInto<rsa::Keypair> for Keypair {
492 type Error = OtherVariantError;
493
494 fn try_into(self) -> Result<rsa::Keypair, Self::Error> {
495 match self.keypair {
496 KeyPairInner::Rsa(inner) => Ok(inner),
497 #[cfg(feature = "ed25519")]
498 KeyPairInner::Ed25519(_) => Err(OtherVariantError::new(crate::KeyType::Ed25519)),
499 #[cfg(feature = "secp256k1")]
500 KeyPairInner::Secp256k1(_) => Err(OtherVariantError::new(crate::KeyType::Secp256k1)),
501 #[cfg(feature = "ecdsa")]
502 KeyPairInner::Ecdsa(_) => Err(OtherVariantError::new(crate::KeyType::Ecdsa)),
503 }
504 }
505}
506
507#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
508pub(crate) enum PublicKeyInner {
509 #[cfg(feature = "ed25519")]
511 Ed25519(ed25519::PublicKey),
512 #[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
513 Rsa(rsa::PublicKey),
515 #[cfg(feature = "secp256k1")]
516 Secp256k1(secp256k1::PublicKey),
518 #[cfg(feature = "ecdsa")]
520 Ecdsa(ecdsa::PublicKey),
521}
522
523#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
525pub struct PublicKey {
526 pub(crate) publickey: PublicKeyInner,
527}
528
529impl PublicKey {
530 #[must_use]
535 #[allow(unused_variables)]
536 pub fn verify(&self, msg: &[u8], sig: &[u8]) -> bool {
537 match self.publickey {
538 #[cfg(feature = "ed25519")]
539 PublicKeyInner::Ed25519(ref pk) => pk.verify(msg, sig),
540 #[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
541 PublicKeyInner::Rsa(ref pk) => pk.verify(msg, sig),
542 #[cfg(feature = "secp256k1")]
543 PublicKeyInner::Secp256k1(ref pk) => pk.verify(msg, sig),
544 #[cfg(feature = "ecdsa")]
545 PublicKeyInner::Ecdsa(ref pk) => pk.verify(msg, sig),
546 }
547 }
548
549 #[cfg(feature = "ed25519")]
550 pub fn try_into_ed25519(self) -> Result<ed25519::PublicKey, OtherVariantError> {
551 self.try_into()
552 }
553
554 #[cfg(feature = "secp256k1")]
555 pub fn try_into_secp256k1(self) -> Result<secp256k1::PublicKey, OtherVariantError> {
556 self.try_into()
557 }
558
559 #[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
560 pub fn try_into_rsa(self) -> Result<rsa::PublicKey, OtherVariantError> {
561 self.try_into()
562 }
563
564 #[cfg(feature = "ecdsa")]
565 pub fn try_into_ecdsa(self) -> Result<ecdsa::PublicKey, OtherVariantError> {
566 self.try_into()
567 }
568
569 pub fn encode_protobuf(&self) -> Vec<u8> {
572 #[cfg(any(
573 feature = "ecdsa",
574 feature = "secp256k1",
575 feature = "ed25519",
576 feature = "rsa"
577 ))]
578 {
579 let public_key = proto::PublicKey::from(self);
580
581 public_key.encode_to_vec()
582 }
583
584 #[cfg(not(any(
585 feature = "ecdsa",
586 feature = "secp256k1",
587 feature = "ed25519",
588 feature = "rsa"
589 )))]
590 unreachable!()
591 }
592
593 #[allow(unused_variables)]
596 pub fn try_decode_protobuf(bytes: &[u8]) -> Result<PublicKey, DecodingError> {
597 #[cfg(any(
598 feature = "ecdsa",
599 feature = "secp256k1",
600 feature = "ed25519",
601 feature = "rsa"
602 ))]
603 {
604 let pubkey = proto::PublicKey::decode(bytes)
605 .map_err(|e| DecodingError::bad_protobuf("public key bytes", e))?;
606
607 pubkey.try_into()
608 }
609
610 #[cfg(not(any(
611 feature = "ecdsa",
612 feature = "secp256k1",
613 feature = "ed25519",
614 feature = "rsa"
615 )))]
616 unreachable!()
617 }
618
619 #[cfg(feature = "peerid")]
621 pub fn to_peer_id(&self) -> crate::PeerId {
622 self.into()
623 }
624
625 pub fn key_type(&self) -> KeyType {
627 match self.publickey {
628 #[cfg(feature = "ed25519")]
629 PublicKeyInner::Ed25519(_) => KeyType::Ed25519,
630 #[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
631 PublicKeyInner::Rsa(_) => KeyType::RSA,
632 #[cfg(feature = "secp256k1")]
633 PublicKeyInner::Secp256k1(_) => KeyType::Secp256k1,
634 #[cfg(feature = "ecdsa")]
635 PublicKeyInner::Ecdsa(_) => KeyType::Ecdsa,
636 }
637 }
638}
639
640#[cfg(any(
641 feature = "ecdsa",
642 feature = "secp256k1",
643 feature = "ed25519",
644 feature = "rsa"
645))]
646impl TryFrom<proto::PublicKey> for PublicKey {
647 type Error = DecodingError;
648
649 fn try_from(pubkey: proto::PublicKey) -> Result<Self, Self::Error> {
650 let key_type = proto::KeyType::try_from(pubkey.r#type)
651 .map_err(|_| DecodingError::unknown_key_type(pubkey.r#type))?;
652
653 match key_type {
654 #[cfg(feature = "ed25519")]
655 proto::KeyType::Ed25519 => Ok(ed25519::PublicKey::try_from_bytes(&pubkey.data).map(
656 |kp| PublicKey {
657 publickey: PublicKeyInner::Ed25519(kp),
658 },
659 )?),
660 #[cfg(not(feature = "ed25519"))]
661 proto::KeyType::Ed25519 => {
662 tracing::debug!("support for ed25519 was disabled at compile-time");
663 Err(DecodingError::missing_feature("ed25519"))
664 }
665 #[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
666 proto::KeyType::Rsa => {
667 Ok(
668 rsa::PublicKey::try_decode_x509(&pubkey.data).map(|kp| PublicKey {
669 publickey: PublicKeyInner::Rsa(kp),
670 })?,
671 )
672 }
673 #[cfg(any(not(feature = "rsa"), target_arch = "wasm32"))]
674 proto::KeyType::Rsa => {
675 tracing::debug!("support for RSA was disabled at compile-time");
676 Err(DecodingError::missing_feature("rsa"))
677 }
678 #[cfg(feature = "secp256k1")]
679 proto::KeyType::Secp256k1 => Ok(secp256k1::PublicKey::try_from_bytes(&pubkey.data)
680 .map(|kp| PublicKey {
681 publickey: PublicKeyInner::Secp256k1(kp),
682 })?),
683 #[cfg(not(feature = "secp256k1"))]
684 proto::KeyType::Secp256k1 => {
685 tracing::debug!("support for secp256k1 was disabled at compile-time");
686 Err(DecodingError::missing_feature("secp256k1"))
687 }
688 #[cfg(feature = "ecdsa")]
689 proto::KeyType::Ecdsa => Ok(ecdsa::PublicKey::try_decode_der(&pubkey.data).map(
690 |kp| PublicKey {
691 publickey: PublicKeyInner::Ecdsa(kp),
692 },
693 )?),
694 #[cfg(not(feature = "ecdsa"))]
695 proto::KeyType::Ecdsa => {
696 tracing::debug!("support for ECDSA was disabled at compile-time");
697 Err(DecodingError::missing_feature("ecdsa"))
698 }
699 }
700 }
701}
702
703#[cfg(feature = "ed25519")]
704impl TryInto<ed25519::PublicKey> for PublicKey {
705 type Error = OtherVariantError;
706
707 fn try_into(self) -> Result<ed25519::PublicKey, Self::Error> {
708 match self.publickey {
709 PublicKeyInner::Ed25519(inner) => Ok(inner),
710 #[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
711 PublicKeyInner::Rsa(_) => Err(OtherVariantError::new(crate::KeyType::RSA)),
712 #[cfg(feature = "secp256k1")]
713 PublicKeyInner::Secp256k1(_) => Err(OtherVariantError::new(crate::KeyType::Secp256k1)),
714 #[cfg(feature = "ecdsa")]
715 PublicKeyInner::Ecdsa(_) => Err(OtherVariantError::new(crate::KeyType::Ecdsa)),
716 }
717 }
718}
719
720#[cfg(feature = "ecdsa")]
721impl TryInto<ecdsa::PublicKey> for PublicKey {
722 type Error = OtherVariantError;
723
724 fn try_into(self) -> Result<ecdsa::PublicKey, Self::Error> {
725 match self.publickey {
726 PublicKeyInner::Ecdsa(inner) => Ok(inner),
727 #[cfg(feature = "ed25519")]
728 PublicKeyInner::Ed25519(_) => Err(OtherVariantError::new(crate::KeyType::Ed25519)),
729 #[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
730 PublicKeyInner::Rsa(_) => Err(OtherVariantError::new(crate::KeyType::RSA)),
731 #[cfg(feature = "secp256k1")]
732 PublicKeyInner::Secp256k1(_) => Err(OtherVariantError::new(crate::KeyType::Secp256k1)),
733 }
734 }
735}
736
737#[cfg(feature = "secp256k1")]
738impl TryInto<secp256k1::PublicKey> for PublicKey {
739 type Error = OtherVariantError;
740
741 fn try_into(self) -> Result<secp256k1::PublicKey, Self::Error> {
742 match self.publickey {
743 PublicKeyInner::Secp256k1(inner) => Ok(inner),
744 #[cfg(feature = "ed25519")]
745 PublicKeyInner::Ed25519(_) => Err(OtherVariantError::new(crate::KeyType::Ed25519)),
746 #[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
747 PublicKeyInner::Rsa(_) => Err(OtherVariantError::new(crate::KeyType::RSA)),
748 #[cfg(feature = "ecdsa")]
749 PublicKeyInner::Ecdsa(_) => Err(OtherVariantError::new(crate::KeyType::Ecdsa)),
750 }
751 }
752}
753
754#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
755impl TryInto<rsa::PublicKey> for PublicKey {
756 type Error = OtherVariantError;
757
758 fn try_into(self) -> Result<rsa::PublicKey, Self::Error> {
759 match self.publickey {
760 PublicKeyInner::Rsa(inner) => Ok(inner),
761 #[cfg(feature = "ed25519")]
762 PublicKeyInner::Ed25519(_) => Err(OtherVariantError::new(crate::KeyType::Ed25519)),
763 #[cfg(feature = "secp256k1")]
764 PublicKeyInner::Secp256k1(_) => Err(OtherVariantError::new(crate::KeyType::Secp256k1)),
765 #[cfg(feature = "ecdsa")]
766 PublicKeyInner::Ecdsa(_) => Err(OtherVariantError::new(crate::KeyType::Ecdsa)),
767 }
768 }
769}
770
771#[cfg(feature = "ed25519")]
772impl From<ed25519::PublicKey> for PublicKey {
773 fn from(key: ed25519::PublicKey) -> Self {
774 PublicKey {
775 publickey: PublicKeyInner::Ed25519(key),
776 }
777 }
778}
779
780#[cfg(feature = "secp256k1")]
781impl From<secp256k1::PublicKey> for PublicKey {
782 fn from(key: secp256k1::PublicKey) -> Self {
783 PublicKey {
784 publickey: PublicKeyInner::Secp256k1(key),
785 }
786 }
787}
788
789#[cfg(feature = "ecdsa")]
790impl From<ecdsa::PublicKey> for PublicKey {
791 fn from(key: ecdsa::PublicKey) -> Self {
792 PublicKey {
793 publickey: PublicKeyInner::Ecdsa(key),
794 }
795 }
796}
797
798#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
799impl From<rsa::PublicKey> for PublicKey {
800 fn from(key: rsa::PublicKey) -> Self {
801 PublicKey {
802 publickey: PublicKeyInner::Rsa(key),
803 }
804 }
805}
806
807#[cfg(test)]
808mod tests {
809 use super::*;
810
811 #[test]
812 #[cfg(feature = "ed25519")]
813 #[cfg(feature = "peerid")]
814 fn keypair_protobuf_roundtrip_ed25519() {
815 let priv_key = Keypair::from_protobuf_encoding(&hex_literal::hex!(
816 "080112407e0830617c4a7de83925dfb2694556b12936c477a0e1feb2e148ec9da60fee7d1ed1e8fae2c4a144b8be8fd4b47bf3d3b34b871c3cacf6010f0e42d474fce27e"
817 ))
818 .unwrap();
819
820 let pub_key = PublicKey::try_decode_protobuf(&hex_literal::hex!(
821 "080112201ed1e8fae2c4a144b8be8fd4b47bf3d3b34b871c3cacf6010f0e42d474fce27e"
822 ))
823 .unwrap();
824
825 roundtrip_protobuf_encoding(&priv_key, &pub_key, KeyType::Ed25519);
826 }
827
828 #[test]
829 #[cfg(all(feature = "ecdsa", feature = "peerid"))]
830 fn keypair_protobuf_roundtrip_ecdsa() {
831 let priv_key = Keypair::from_protobuf_encoding(&hex_literal::hex!(
832 "08031279307702010104203E5B1FE9712E6C314942A750BD67485DE3C1EFE85B1BFB520AE8F9AE3DFA4A4CA00A06082A8648CE3D030107A14403420004DE3D300FA36AE0E8F5D530899D83ABAB44ABF3161F162A4BC901D8E6ECDA020E8B6D5F8DA30525E71D6851510C098E5C47C646A597FB4DCEC034E9F77C409E62"
833 ))
834 .unwrap();
835 let pub_key = PublicKey::try_decode_protobuf(&hex_literal::hex!("0803125b3059301306072a8648ce3d020106082a8648ce3d03010703420004de3d300fa36ae0e8f5d530899d83abab44abf3161f162a4bc901d8e6ecda020e8b6d5f8da30525e71d6851510c098e5c47c646a597fb4dcec034e9f77c409e62")).unwrap();
836
837 roundtrip_protobuf_encoding(&priv_key, &pub_key, KeyType::Ecdsa);
838 }
839
840 #[test]
841 #[cfg(all(feature = "secp256k1", feature = "peerid"))]
842 fn keypair_protobuf_roundtrip_secp256k1() {
843 let priv_key = Keypair::from_protobuf_encoding(&hex_literal::hex!(
844 "0802122053DADF1D5A164D6B4ACDB15E24AA4C5B1D3461BDBD42ABEDB0A4404D56CED8FB"
845 ))
846 .unwrap();
847 let pub_key = PublicKey::try_decode_protobuf(&hex_literal::hex!(
848 "08021221037777e994e452c21604f91de093ce415f5432f701dd8cd1a7a6fea0e630bfca99"
849 ))
850 .unwrap();
851
852 roundtrip_protobuf_encoding(&priv_key, &pub_key, KeyType::Secp256k1);
853 }
854
855 #[cfg(feature = "peerid")]
856 fn roundtrip_protobuf_encoding(private_key: &Keypair, public_key: &PublicKey, tpe: KeyType) {
857 assert_eq!(&private_key.public(), public_key);
858
859 let encoded_priv = private_key.to_protobuf_encoding().unwrap();
860 let decoded_priv = Keypair::from_protobuf_encoding(&encoded_priv).unwrap();
861
862 assert_eq!(
863 private_key.public().to_peer_id(),
864 decoded_priv.public().to_peer_id(),
865 "PeerId from roundtripped private key should be the same"
866 );
867
868 let encoded_public = private_key.public().encode_protobuf();
869 let decoded_public = PublicKey::try_decode_protobuf(&encoded_public).unwrap();
870
871 assert_eq!(
872 private_key.public().to_peer_id(),
873 decoded_public.to_peer_id(),
874 "PeerId from roundtripped public key should be the same"
875 );
876 assert_eq!(private_key.key_type(), tpe)
877 }
878
879 #[test]
880 #[cfg(feature = "peerid")]
881 fn keypair_from_protobuf_encoding() {
882 let priv_key = Keypair::from_protobuf_encoding(&hex_literal::hex!(
883 "080012ae123082092a0201000282020100e1beab071d08200bde24eef00d049449b07770ff9910257b2d7d5dda242ce8f0e2f12e1af4b32d9efd2c090f66b0f29986dbb645dae9880089704a94e5066d594162ae6ee8892e6ec70701db0a6c445c04778eb3de1293aa1a23c3825b85c6620a2bc3f82f9b0c309bc0ab3aeb1873282bebd3da03c33e76c21e9beb172fd44c9e43be32e2c99827033cf8d0f0c606f4579326c930eb4e854395ad941256542c793902185153c474bed109d6ff5141ebf9cd256cf58893a37f83729f97e7cb435ec679d2e33901d27bb35aa0d7e20561da08885ef0abbf8e2fb48d6a5487047a9ecb1ad41fa7ed84f6e3e8ecd5d98b3982d2a901b4454991766da295ab78822add5612a2df83bcee814cf50973e80d7ef38111b1bd87da2ae92438a2c8cbcc70b31ee319939a3b9c761dbc13b5c086d6b64bf7ae7dacc14622375d92a8ff9af7eb962162bbddebf90acb32adb5e4e4029f1c96019949ecfbfeffd7ac1e3fbcc6b6168c34be3d5a2e5999fcbb39bba7adbca78eab09b9bc39f7fa4b93411f4cc175e70c0a083e96bfaefb04a9580b4753c1738a6a760ae1afd851a1a4bdad231cf56e9284d832483df215a46c1c21bdf0c6cfe951c18f1ee4078c79c13d63edb6e14feaeffabc90ad317e4875fe648101b0864097e998f0ca3025ef9638cd2b0caecd3770ab54a1d9c6ca959b0f5dcbc90caeefc4135baca6fd475224269bbe1b02030100010282020100a472ffa858efd8588ce59ee264b957452f3673acdf5631d7bfd5ba0ef59779c231b0bc838a8b14cae367b6d9ef572c03c7883b0a3c652f5c24c316b1ccfd979f13d0cd7da20c7d34d9ec32dfdc81ee7292167e706d705efde5b8f3edfcba41409e642f8897357df5d320d21c43b33600a7ae4e505db957c1afbc189d73f0b5d972d9aaaeeb232ca20eebd5de6fe7f29d01470354413cc9a0af1154b7af7c1029adcd67c74b4798afeb69e09f2cb387305e73a1b5f450202d54f0ef096fe1bde340219a1194d1ac9026e90b366cce0c59b239d10e4888f52ca1780824d39ae01a6b9f4dd6059191a7f12b2a3d8db3c2868cd4e5a5862b8b625a4197d52c6ac77710116ebd3ced81c4d91ad5fdfbed68312ebce7eea45c1833ca3acf7da2052820eacf5c6b07d086dabeb893391c71417fd8a4b1829ae2cf60d1749d0e25da19530d889461c21da3492a8dc6ccac7de83ac1c2185262c7473c8cc42f547cc9864b02a8073b6aa54a037d8c0de3914784e6205e83d97918b944f11b877b12084c0dd1d36592f8a4f8b8da5bb404c3d2c079b22b6ceabfbcb637c0dbe0201f0909d533f8bf308ada47aee641a012a494d31b54c974e58b87f140258258bb82f31692659db7aa07e17a5b2a0832c24e122d3a8babcc9ee74cbb07d3058bb85b15f6f6b2674aba9fd34367be9782d444335fbed31e3c4086c652597c27104938b47fa10282010100e9fdf843c1550070ca711cb8ff28411466198f0e212511c3186623890c0071bf6561219682fe7dbdfd81176eba7c4faba21614a20721e0fcd63768e6d925688ecc90992059ac89256e0524de90bf3d8a052ce6a9f6adafa712f3107a016e20c80255c9e37d8206d1bc327e06e66eb24288da866b55904fd8b59e6b2ab31bc5eab47e597093c63fab7872102d57b4c589c66077f534a61f5f65127459a33c91f6db61fc431b1ae90be92b4149a3255291baf94304e3efb77b1107b5a3bda911359c40a53c347ff9100baf8f36dc5cd991066b5bdc28b39ed644f404afe9213f4d31c9d4e40f3a5f5e3c39bebeb244e84137544e1a1839c1c8aaebf0c78a7fad590282010100f6fa1f1e6b803742d5490b7441152f500970f46feb0b73a6e4baba2aaf3c0e245ed852fc31d86a8e46eb48e90fac409989dfee45238f97e8f1f8e83a136488c1b04b8a7fb695f37b8616307ff8a8d63e8cfa0b4fb9b9167ffaebabf111aa5a4344afbabd002ae8961c38c02da76a9149abdde93eb389eb32595c29ba30d8283a7885218a5a9d33f7f01dbdf85f3aad016c071395491338ec318d39220e1c7bd69d3d6b520a13a30d745c102b827ad9984b0dd6aed73916ffa82a06c1c111e7047dcd2668f988a0570a71474992eecf416e068f029ec323d5d635fd24694fc9bf96973c255d26c772a95bf8b7f876547a5beabf86f06cd21b67994f944e7a5493028201010095b02fd30069e547426a8bea58e8a2816f33688dac6c6f6974415af8402244a22133baedf34ce499d7036f3f19b38eb00897c18949b0c5a25953c71aeeccfc8f6594173157cc854bd98f16dffe8f28ca13b77eb43a2730585c49fc3f608cd811bb54b03b84bddaa8ef910988567f783012266199667a546a18fd88271fbf63a45ae4fd4884706da8befb9117c0a4d73de5172f8640b1091ed8a4aea3ed4641463f5ff6a5e3401ad7d0c92811f87956d1fd5f9a1d15c7f3839a08698d9f35f9d966e5000f7cb2655d7b6c4adcd8a9d950ea5f61bb7c9a33c17508f9baa313eecfee4ae493249ebe05a5d7770bbd3551b2eeb752e3649e0636de08e3d672e66cb90282010100ad93e4c31072b063fc5ab5fe22afacece775c795d0efdf7c704cfc027bde0d626a7646fc905bb5a80117e3ca49059af14e0160089f9190065be9bfecf12c3b2145b211c8e89e42dd91c38e9aa23ca73697063564f6f6aa6590088a738722df056004d18d7bccac62b3bafef6172fc2a4b071ea37f31eff7a076bcab7dd144e51a9da8754219352aef2c73478971539fa41de4759285ea626fa3c72e7085be47d554d915bbb5149cb6ef835351f231043049cd941506a034bf2f8767f3e1e42ead92f91cb3d75549b57ef7d56ac39c2d80d67f6a2b4ca192974bfc5060e2dd171217971002193dba12e7e4133ab201f07500a90495a38610279b13a48d54f0c99028201003e3a1ac0c2b67d54ed5c4bbe04a7db99103659d33a4f9d35809e1f60c282e5988dddc964527f3b05e6cc890eab3dcb571d66debf3a5527704c87264b3954d7265f4e8d2c637dd89b491b9cf23f264801f804b90454d65af0c4c830d1aef76f597ef61b26ca857ecce9cb78d4f6c2218c00d2975d46c2b013fbf59b750c3b92d8d3ed9e6d1fd0ef1ec091a5c286a3fe2dead292f40f380065731e2079ebb9f2a7ef2c415ecbb488da98f3a12609ca1b6ec8c734032c8bd513292ff842c375d4acd1b02dfb206b24cd815f8e2f9d4af8e7dea0370b19c1b23cc531d78b40e06e1119ee2e08f6f31c6e2e8444c568d13c5d451a291ae0c9f1d4f27d23b3a00d60ad"
884 ))
885 .unwrap();
886 let pub_key = PublicKey::try_decode_protobuf(&hex_literal::hex!(
887 "080012a60430820222300d06092a864886f70d01010105000382020f003082020a0282020100e1beab071d08200bde24eef00d049449b07770ff9910257b2d7d5dda242ce8f0e2f12e1af4b32d9efd2c090f66b0f29986dbb645dae9880089704a94e5066d594162ae6ee8892e6ec70701db0a6c445c04778eb3de1293aa1a23c3825b85c6620a2bc3f82f9b0c309bc0ab3aeb1873282bebd3da03c33e76c21e9beb172fd44c9e43be32e2c99827033cf8d0f0c606f4579326c930eb4e854395ad941256542c793902185153c474bed109d6ff5141ebf9cd256cf58893a37f83729f97e7cb435ec679d2e33901d27bb35aa0d7e20561da08885ef0abbf8e2fb48d6a5487047a9ecb1ad41fa7ed84f6e3e8ecd5d98b3982d2a901b4454991766da295ab78822add5612a2df83bcee814cf50973e80d7ef38111b1bd87da2ae92438a2c8cbcc70b31ee319939a3b9c761dbc13b5c086d6b64bf7ae7dacc14622375d92a8ff9af7eb962162bbddebf90acb32adb5e4e4029f1c96019949ecfbfeffd7ac1e3fbcc6b6168c34be3d5a2e5999fcbb39bba7adbca78eab09b9bc39f7fa4b93411f4cc175e70c0a083e96bfaefb04a9580b4753c1738a6a760ae1afd851a1a4bdad231cf56e9284d832483df215a46c1c21bdf0c6cfe951c18f1ee4078c79c13d63edb6e14feaeffabc90ad317e4875fe648101b0864097e998f0ca3025ef9638cd2b0caecd3770ab54a1d9c6ca959b0f5dcbc90caeefc4135baca6fd475224269bbe1b0203010001"
888 ))
889 .unwrap();
890
891 assert_eq!(priv_key.public(), pub_key);
892 }
893
894 #[test]
895 fn public_key_implements_hash() {
896 use std::hash::Hash;
897
898 use crate::PublicKey;
899
900 fn assert_implements_hash<T: Hash>() {}
901
902 assert_implements_hash::<PublicKey>();
903 }
904
905 #[test]
906 fn public_key_implements_ord() {
907 use std::cmp::Ord;
908
909 use crate::PublicKey;
910
911 fn assert_implements_ord<T: Ord>() {}
912
913 assert_implements_ord::<PublicKey>();
914 }
915
916 #[test]
917 #[cfg(all(feature = "ed25519", feature = "rand"))]
918 fn test_publickey_from_ed25519_public_key() {
919 let pubkey = Keypair::generate_ed25519().public();
920 let ed25519_pubkey = pubkey
921 .clone()
922 .try_into_ed25519()
923 .expect("A ed25519 keypair");
924
925 let converted_pubkey = PublicKey::from(ed25519_pubkey);
926
927 assert_eq!(converted_pubkey, pubkey);
928 assert_eq!(converted_pubkey.key_type(), KeyType::Ed25519)
929 }
930
931 #[test]
932 #[cfg(all(feature = "secp256k1", feature = "rand"))]
933 fn test_publickey_from_secp256k1_public_key() {
934 let pubkey = Keypair::generate_secp256k1().public();
935 let secp256k1_pubkey = pubkey
936 .clone()
937 .try_into_secp256k1()
938 .expect("A secp256k1 keypair");
939 let converted_pubkey = PublicKey::from(secp256k1_pubkey);
940
941 assert_eq!(converted_pubkey, pubkey);
942 assert_eq!(converted_pubkey.key_type(), KeyType::Secp256k1)
943 }
944
945 #[test]
946 #[cfg(all(feature = "ecdsa", feature = "rand"))]
947 fn test_publickey_from_ecdsa_public_key() {
948 let pubkey = Keypair::generate_ecdsa().public();
949 let ecdsa_pubkey = pubkey.clone().try_into_ecdsa().expect("A ecdsa keypair");
950 let converted_pubkey = PublicKey::from(ecdsa_pubkey);
951
952 assert_eq!(converted_pubkey, pubkey);
953 assert_eq!(converted_pubkey.key_type(), KeyType::Ecdsa)
954 }
955
956 #[test]
957 #[cfg(feature = "ecdsa")]
958 fn test_secret_from_ecdsa_private_key() {
959 let keypair = Keypair::generate_ecdsa();
960 assert!(keypair.derive_secret(b"domain separator!").is_some())
961 }
962}