libp2p_identity/lib.rs
1// Copyright 2019 Parity Technologies (UK) Ltd.
2// Copyright 2023 Protocol Labs.
3//
4// Permission is hereby granted, free of charge, to any person obtaining a
5// copy of this software and associated documentation files (the "Software"),
6// to deal in the Software without restriction, including without limitation
7// the rights to use, copy, modify, merge, publish, distribute, sublicense,
8// and/or sell copies of the Software, and to permit persons to whom the
9// Software is furnished to do so, subject to the following conditions:
10//
11// The above copyright notice and this permission notice shall be included in
12// all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20// DEALINGS IN THE SOFTWARE.
21
22//! A node's network identity keys.
23//!
24//! Such identity keys can be randomly generated on every startup,
25//! but using already existing, fixed keys is usually required.
26//! Though libp2p uses other crates (e.g. `ed25519_dalek`) internally,
27//! such details are not exposed as part of libp2p's public interface
28//! to keep them easily upgradable or replaceable (e.g. to `ed25519_zebra`).
29//! Consequently, keys of external ed25519 or secp256k1 crates cannot be
30//! directly converted into libp2p network identities.
31//! Instead, loading fixed keys must use the standard, thus more portable
32//! binary representation of the specific key type
33//! (e.g. [ed25519 binary format](https://datatracker.ietf.org/doc/html/rfc8032#section-5.1.5)).
34//! All key types have functions to enable conversion to/from their binary representations.
35
36#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
37#![allow(unreachable_pub)]
38#[cfg(any(
39 feature = "ecdsa",
40 feature = "secp256k1",
41 feature = "ed25519",
42 feature = "rsa"
43))]
44mod proto {
45 include!("generated/mod.rs");
46 pub(crate) use self::keys_proto::*;
47}
48
49#[cfg(feature = "ecdsa")]
50pub mod ecdsa;
51
52#[cfg(feature = "ed25519")]
53pub mod ed25519;
54
55#[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
56pub mod rsa;
57
58#[cfg(feature = "secp256k1")]
59pub mod secp256k1;
60
61mod error;
62mod keypair;
63#[cfg(feature = "peerid")]
64mod peer_id;
65
66#[cfg(any(
67 feature = "ecdsa",
68 feature = "secp256k1",
69 feature = "ed25519",
70 feature = "rsa"
71))]
72impl zeroize::Zeroize for proto::PrivateKey {
73 fn zeroize(&mut self) {
74 self.Data.zeroize();
75 }
76}
77
78#[cfg(any(
79 feature = "ecdsa",
80 feature = "secp256k1",
81 feature = "ed25519",
82 feature = "rsa"
83))]
84impl From<&PublicKey> for proto::PublicKey {
85 fn from(key: &PublicKey) -> Self {
86 match &key.publickey {
87 #[cfg(feature = "ed25519")]
88 keypair::PublicKeyInner::Ed25519(key) => proto::PublicKey {
89 Type: proto::KeyType::Ed25519,
90 Data: key.to_bytes().to_vec(),
91 },
92 #[cfg(all(feature = "rsa", not(target_arch = "wasm32")))]
93 keypair::PublicKeyInner::Rsa(key) => proto::PublicKey {
94 Type: proto::KeyType::RSA,
95 Data: key.encode_x509(),
96 },
97 #[cfg(feature = "secp256k1")]
98 keypair::PublicKeyInner::Secp256k1(key) => proto::PublicKey {
99 Type: proto::KeyType::Secp256k1,
100 Data: key.to_bytes().to_vec(),
101 },
102 #[cfg(feature = "ecdsa")]
103 keypair::PublicKeyInner::Ecdsa(key) => proto::PublicKey {
104 Type: proto::KeyType::ECDSA,
105 Data: key.encode_der(),
106 },
107 }
108 }
109}
110
111pub use error::{DecodingError, OtherVariantError, SigningError};
112pub use keypair::{Keypair, PublicKey};
113#[cfg(feature = "peerid")]
114pub use peer_id::{ParseError, PeerId};
115
116/// The type of key a `KeyPair` is holding.
117#[derive(Debug, PartialEq, Eq)]
118#[allow(clippy::upper_case_acronyms)]
119pub enum KeyType {
120 Ed25519,
121 RSA,
122 Secp256k1,
123 Ecdsa,
124}
125
126impl std::fmt::Display for KeyType {
127 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
128 match self {
129 KeyType::Ed25519 => f.write_str("Ed25519"),
130 KeyType::RSA => f.write_str("RSA"),
131 KeyType::Secp256k1 => f.write_str("Secp256k1"),
132 KeyType::Ecdsa => f.write_str("Ecdsa"),
133 }
134 }
135}