fluence_keypair/
public_key.rs1use crate::ed25519;
17use crate::error::{DecodingError, VerificationError};
18#[cfg(not(target_arch = "wasm32"))]
19use crate::rsa;
20use crate::secp256k1;
21use crate::signature::Signature;
22
23use crate::key_pair::KeyFormat;
24use libp2p_identity::{KeyType, PeerId};
25use serde::{Deserialize, Serialize};
26use std::convert::TryFrom;
27
28#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
30pub enum PublicKey {
31 Ed25519(ed25519::PublicKey),
33 #[cfg(not(target_arch = "wasm32"))]
34 Rsa(rsa::PublicKey),
36 Secp256k1(secp256k1::PublicKey),
38}
39
40impl PublicKey {
41 pub fn verify(&self, msg: &[u8], sig: &Signature) -> Result<(), VerificationError> {
47 use PublicKey::*;
48 match self {
49 Ed25519(pk) => pk.verify(msg, sig.to_vec()),
50 #[cfg(not(target_arch = "wasm32"))]
51 Rsa(pk) => pk.verify(msg, sig.to_vec()),
52 Secp256k1(pk) => pk.verify(msg, sig.to_vec()),
53 }
54 }
55
56 pub fn encode(&self) -> Vec<u8> {
57 use PublicKey::*;
58 let mut result: Vec<u8> = vec![self.get_prefix()];
59
60 match self {
61 Ed25519(pk) => result.extend(pk.encode().to_vec()),
62 #[cfg(not(target_arch = "wasm32"))]
63 Rsa(pk) => result.extend(pk.to_pkcs1()),
64 Secp256k1(pk) => result.extend(pk.encode().to_vec()),
65 };
66
67 result
68 }
69
70 pub fn decode(bytes: &[u8]) -> Result<PublicKey, DecodingError> {
71 match KeyFormat::try_from(bytes[0])? {
72 KeyFormat::Ed25519 => Ok(PublicKey::Ed25519(ed25519::PublicKey::decode(&bytes[1..])?)),
73 #[cfg(not(target_arch = "wasm32"))]
74 KeyFormat::Rsa => Ok(PublicKey::Rsa(rsa::PublicKey::from_pkcs1(
75 bytes[1..].to_owned(),
76 )?)),
77 KeyFormat::Secp256k1 => Ok(PublicKey::Secp256k1(secp256k1::PublicKey::decode(
78 &bytes[1..],
79 )?)),
80 }
81 }
82
83 fn get_prefix(&self) -> u8 {
84 use PublicKey::*;
85 match self {
86 Ed25519(_) => KeyFormat::Ed25519.into(),
87 #[cfg(not(target_arch = "wasm32"))]
88 Rsa(_) => KeyFormat::Rsa.into(),
89 Secp256k1(_) => KeyFormat::Secp256k1.into(),
90 }
91 }
92
93 pub fn from_base58(str: &str) -> Result<PublicKey, DecodingError> {
94 let bytes = bs58::decode(str)
95 .into_vec()
96 .map_err(DecodingError::Base58DecodeError)?;
97 Self::decode(&bytes)
98 }
99
100 pub fn to_vec(&self) -> Vec<u8> {
101 use PublicKey::*;
102
103 match self {
104 Ed25519(pk) => pk.encode().to_vec(),
105 #[cfg(not(target_arch = "wasm32"))]
106 Rsa(pk) => pk.to_pkcs1().to_vec(),
107 Secp256k1(pk) => pk.encode().to_vec(),
108 }
109 }
110
111 pub fn to_peer_id(&self) -> PeerId {
112 PeerId::from_public_key(&self.clone().into())
113 }
114
115 pub fn get_key_format(&self) -> KeyFormat {
116 use PublicKey::*;
117
118 match self {
119 Ed25519(_) => KeyFormat::Ed25519,
120 #[cfg(not(target_arch = "wasm32"))]
121 Rsa(_) => KeyFormat::Rsa,
122 Secp256k1(_) => KeyFormat::Secp256k1,
123 }
124 }
125}
126
127impl From<libp2p_identity::PublicKey> for PublicKey {
128 fn from(key: libp2p_identity::PublicKey) -> Self {
129 fn convert_key(key: libp2p_identity::PublicKey) -> eyre::Result<PublicKey> {
130 match key.key_type() {
131 KeyType::Ed25519 => {
132 let pk = key.try_into_ed25519()?;
133 let raw_pk = ed25519::PublicKey::decode(&pk.to_bytes())?;
134 Ok(PublicKey::Ed25519(raw_pk))
135 }
136 #[cfg(not(target_arch = "wasm32"))]
137 KeyType::RSA => {
138 let pk = key.try_into_rsa()?;
139 let raw_pk = rsa::PublicKey::from_pkcs1(pk.encode_pkcs1())?;
140 Ok(PublicKey::Rsa(raw_pk))
141 }
142 KeyType::Secp256k1 => {
143 let pk = key.try_into_secp256k1()?;
144 let raw_pk = secp256k1::PublicKey::decode(&pk.to_bytes())?;
145 Ok(PublicKey::Secp256k1(raw_pk))
146 }
147 _ => unreachable!(),
148 }
149 }
150
151 convert_key(key).expect("Could not convert public key")
152 }
153}
154
155impl From<PublicKey> for libp2p_identity::PublicKey {
156 fn from(key: PublicKey) -> Self {
157 fn convert_key(key: PublicKey) -> eyre::Result<libp2p_identity::PublicKey> {
158 match key {
159 PublicKey::Ed25519(key) => {
160 let raw_pk =
161 libp2p_identity::ed25519::PublicKey::try_from_bytes(&key.encode())?;
162 let pk = libp2p_identity::PublicKey::from(raw_pk);
163 Ok(pk)
164 }
165 #[cfg(not(target_arch = "wasm32"))]
166 PublicKey::Rsa(key) => {
167 let raw_pk =
168 libp2p_identity::rsa::PublicKey::try_decode_x509(&key.encode_x509())?;
169 let pk = libp2p_identity::PublicKey::from(raw_pk);
170 Ok(pk)
171 }
172 PublicKey::Secp256k1(key) => {
173 let raw_pk =
174 libp2p_identity::secp256k1::PublicKey::try_from_bytes(&key.encode())?;
175 let pk = libp2p_identity::PublicKey::from(raw_pk);
176 Ok(pk)
177 }
178 }
179 }
180 convert_key(key).expect("Could not convert key")
181 }
182}
183
184impl TryFrom<PeerId> for PublicKey {
185 type Error = DecodingError;
186
187 fn try_from(peer_id: PeerId) -> Result<Self, Self::Error> {
188 Ok(as_public_key(&peer_id)
189 .ok_or_else(|| DecodingError::PublicKeyNotInlined(peer_id.to_base58()))?
190 .into())
191 }
192}
193
194fn as_public_key(peer_id: &PeerId) -> Option<libp2p_identity::PublicKey> {
196 let mhash = peer_id.as_ref();
197
198 match multihash::Code::try_from(mhash.code()) {
199 Ok(multihash::Code::Identity) => {
200 libp2p_identity::PublicKey::try_decode_protobuf(mhash.digest()).ok()
201 }
202 _ => None,
203 }
204}
205
206#[cfg(test)]
207mod tests {
208 use super::*;
209 use crate::KeyPair;
210
211 #[test]
212 fn public_key_encode_decode_ed25519() {
213 let kp = KeyPair::generate_ed25519();
214 let pk = kp.public();
215 let encoded_pk = pk.encode();
216 assert_eq!(pk, PublicKey::decode(&encoded_pk).unwrap());
217 }
218
219 #[test]
220 fn public_key_encode_decode_secp256k1() {
221 let kp = KeyPair::generate_secp256k1();
222 let pk = kp.public();
223 let encoded_pk = pk.encode();
224 assert_eq!(pk, PublicKey::decode(&encoded_pk).unwrap());
225 }
226
227 #[test]
228 fn public_key_peer_id_conversions() {
229 let kp = KeyPair::generate_secp256k1();
230 let fluence_pk = kp.public();
231 let libp2p_pk: libp2p_identity::PublicKey = fluence_pk.clone().into();
232 let peer_id = PeerId::from_public_key(&libp2p_pk);
233 let fluence_pk_converted = PublicKey::try_from(peer_id).unwrap();
234
235 assert_eq!(fluence_pk, fluence_pk_converted);
236 }
237}