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