1use libp2p_identity::{
2 ed25519 as libp2p_ed25519, secp256k1 as libp2p_secp256k1, Keypair as libp2p_Keypair,
3 PublicKey as libp2p_PublicKey,
4};
5use rand::SeedableRng;
6
7const ENCODE_KEYPAIR_CODE: u8 = b'a';
8const ENCODE_PUBLIC_KEY_CODE: u8 = b'p';
9
10#[derive(Clone)]
12pub struct Keypair {
13 keypair: libp2p_Keypair,
14 keypair_type: KeypairType,
15}
16
17#[derive(Clone)]
18enum KeypairType {
19 Ed25519 { keypair: libp2p_ed25519::Keypair },
20 Secp256k1 { _keypair: libp2p_secp256k1::Keypair },
21}
22
23impl Keypair {
24 pub fn from_libp2p(keypair: libp2p_Keypair) -> Keypair {
25 let keypair_type = match keypair.key_type() {
26 libp2p_identity::KeyType::Ed25519 => KeypairType::Ed25519 {
27 keypair: keypair.clone().try_into_ed25519().unwrap(),
28 },
29 libp2p_identity::KeyType::Secp256k1 => KeypairType::Secp256k1 {
30 _keypair: keypair.clone().try_into_secp256k1().unwrap(),
31 },
32 _ => unimplemented!(),
33 };
34
35 Keypair {
36 keypair,
37 keypair_type,
38 }
39 }
40
41 pub fn generate_ed25519() -> Keypair {
42 Self::from_libp2p(libp2p_Keypair::generate_ed25519())
43 }
44
45 pub fn public(&self) -> PublicKey {
46 PublicKey::from_libp2p(self.keypair.public())
47 }
48
49 pub fn algorithm(&self) -> Algorithm {
50 match self.keypair_type {
51 KeypairType::Ed25519 { keypair: _ } => Algorithm::Ed25519,
52 KeypairType::Secp256k1 { _keypair: _ } => Algorithm::Secp256k1,
53 }
54 }
55
56 pub fn to_libp2p(&self) -> &libp2p_Keypair {
57 &self.keypair
58 }
59
60 pub fn sign(&self, msg: &[u8]) -> Result<Vec<u8>, Error> {
63 self.keypair
64 .sign(msg)
65 .map_err(|err| Error::Libp2pSigning(err.to_string()))
66 }
67
68 pub fn encode(&self) -> Vec<u8> {
70 match &self.keypair_type {
71 KeypairType::Ed25519 { keypair } => {
72 let mut vec = vec![0; 66];
73 vec[0] = ENCODE_KEYPAIR_CODE;
74 vec[1] = Algorithm::Ed25519.to_code();
75 vec[2..].copy_from_slice(&keypair.to_bytes());
76 vec
77 }
78 _ => unimplemented!(),
79 }
80 }
81
82 pub fn encode_base58_string(&self) -> String {
84 encode_base58(&self.encode())
85 }
86
87 pub fn decode(bytes: &mut [u8]) -> Result<Keypair, Error> {
90 if bytes.len() < 3 {
91 return Err(Error::DecodeInvalidSize);
92 }
93
94 if bytes[0] != ENCODE_KEYPAIR_CODE {
95 return Err(Error::DecodeExpectedPair);
96 }
97
98 match Algorithm::from_code(bytes[1])? {
99 Algorithm::Ed25519 => {
100 let keypair = libp2p_ed25519::Keypair::try_from_bytes(&mut bytes[2..])
101 .map_err(|err| Error::Libp2pDecode(err.to_string()))?;
102
103 Ok(Self::from_libp2p(keypair.into()))
104 }
105 _ => unimplemented!(),
106 }
107 }
108
109 pub fn decode_base58_string(input: &str) -> Result<Keypair, Error> {
111 let mut bytes = decode_base58(input)?;
112 Self::decode(&mut bytes)
113 }
114}
115
116#[derive(Clone, Debug, PartialEq, Eq)]
118pub struct PublicKey {
119 key: libp2p_PublicKey,
120 key_type: PublicKeyType,
121}
122
123#[derive(Clone, Debug, PartialEq, Eq)]
124enum PublicKeyType {
125 Ed25519(libp2p_ed25519::PublicKey),
126 Secp256k1(libp2p_secp256k1::PublicKey),
127}
128
129impl PublicKey {
130 pub fn from_libp2p(key: libp2p_PublicKey) -> PublicKey {
131 let key_type = match key.key_type() {
132 libp2p_identity::KeyType::Ed25519 => {
133 PublicKeyType::Ed25519(key.clone().try_into_ed25519().unwrap())
134 }
135 libp2p_identity::KeyType::Secp256k1 => {
136 PublicKeyType::Secp256k1(key.clone().try_into_secp256k1().unwrap())
137 }
138 _ => unimplemented!(),
139 };
140
141 PublicKey { key, key_type }
142 }
143
144 pub fn to_libp2p(&self) -> &libp2p_PublicKey {
145 &self.key
146 }
147
148 pub fn verify(&self, msg: &[u8], sig: &[u8]) -> bool {
151 self.key.verify(msg, sig)
152 }
153
154 pub fn encode(&self) -> Vec<u8> {
156 match &self.key_type {
157 PublicKeyType::Ed25519(pk) => {
158 let mut vec = vec![0; 34];
159 vec[0] = ENCODE_PUBLIC_KEY_CODE;
160 vec[1] = Algorithm::Ed25519.to_code();
161 vec[2..].copy_from_slice(&pk.to_bytes());
162 vec
163 }
164 _ => unimplemented!(),
165 }
166 }
167
168 pub fn encode_base58_string(&self) -> String {
170 encode_base58(&self.encode())
171 }
172
173 pub fn decode(bytes: &[u8]) -> Result<PublicKey, Error> {
175 if bytes.len() < 3 {
176 return Err(Error::DecodeInvalidSize);
177 }
178
179 if bytes[0] != ENCODE_PUBLIC_KEY_CODE {
180 return Err(Error::DecodeExpectedPublic);
181 }
182
183 match Algorithm::from_code(bytes[1])? {
184 Algorithm::Ed25519 => {
185 let pk = libp2p_ed25519::PublicKey::try_from_bytes(&bytes[2..])
186 .map_err(|err| Error::Libp2pDecode(err.to_string()))?;
187
188 Ok(PublicKey::from_libp2p(pk.into()))
189 }
190 _ => unimplemented!(),
191 }
192 }
193
194 pub fn decode_base58_string(input: &str) -> Result<PublicKey, Error> {
196 let bytes = decode_base58(input)?;
197 Self::decode(&bytes)
198 }
199
200 pub fn generate_name(&self) -> String {
202 let bytes = self.encode();
203 let bytes_len = bytes.len();
204
205 let mut rng = rand::prelude::StdRng::seed_from_u64(u64::from_le_bytes([
206 bytes[bytes_len - 1],
207 bytes[bytes_len - 2],
208 bytes[bytes_len - 3],
209 bytes[bytes_len - 4],
210 bytes[bytes_len - 5],
211 bytes[bytes_len - 6],
212 bytes[bytes_len - 7],
213 bytes[bytes_len - 8],
214 ]));
215 petname::Petnames::default().generate(&mut rng, 3, "-")
216 }
217}
218
219fn encode_base58(bytes: &[u8]) -> String {
221 format!(
222 "{}{}{}",
223 char::from(bytes[0]),
224 char::from(bytes[1]),
225 bs58::encode(&bytes[2..]).into_string()
226 )
227}
228
229fn decode_base58(input: &str) -> Result<Vec<u8>, Error> {
231 let input_bytes = input.as_bytes();
232 if input_bytes.len() < 3 {
233 return Err(Error::DecodeInvalidSize);
234 }
235
236 let mut output = vec![0; (input_bytes.len() / 8 + 1) * 6];
238 output[0..2].copy_from_slice(&input_bytes[0..2]);
239
240 let len = bs58::decode(&input[2..]).onto(&mut output[2..])?;
241
242 output.truncate(len + 2);
243
244 Ok(output)
245}
246
247#[derive(Clone, Copy, PartialEq, Eq, Debug)]
249pub enum Algorithm {
250 Ed25519,
251 Secp256k1,
252}
253
254impl Algorithm {
255 fn to_code(self) -> u8 {
256 match self {
257 Algorithm::Ed25519 => b'e',
258 Algorithm::Secp256k1 => b'c',
259 }
260 }
261
262 fn from_code(code: u8) -> Result<Algorithm, Error> {
263 match code {
264 b'e' => Ok(Algorithm::Ed25519),
265 b'c' => Ok(Algorithm::Secp256k1),
266 _ => Err(Error::InvalidAlgorithmCode(code)),
267 }
268 }
269}
270
271#[derive(Debug, thiserror::Error)]
273pub enum Error {
274 #[error("Given bytes to decode doesn't have the right size")]
275 DecodeInvalidSize,
276
277 #[error("Given bytes to decode wasn't a keypair")]
278 DecodeExpectedPair,
279
280 #[error("Given bytes to decode wasn't a public key")]
281 DecodeExpectedPublic,
282
283 #[error("Given bytes couldn't be decoded by libp2p: {0}")]
284 Libp2pDecode(String),
285
286 #[error("Couldn't decode base58 string into bytes: {0}")]
287 Base58Decode(#[from] bs58::decode::Error),
288
289 #[error("Algorithm code is invalid: {0}")]
290 InvalidAlgorithmCode(u8),
291
292 #[error("Libp2p signing error: {0}")]
293 Libp2pSigning(String),
294}
295
296#[cfg(test)]
297mod tests {
298 use super::*;
299
300 #[test]
301 pub fn ed25519_keypair_encode_decode() -> anyhow::Result<()> {
302 let keypair = Keypair::generate_ed25519();
303
304 let mut encoded = keypair.encode();
305 let keypair_decoded = Keypair::decode(&mut encoded)?;
306 assert_eq!(keypair.public(), keypair_decoded.public());
307
308 assert!(Keypair::decode(&mut []).is_err());
309 assert!(Keypair::decode(&mut [0]).is_err());
310 assert!(Keypair::decode(&mut [0, 0]).is_err());
311 assert!(Keypair::decode(&mut [0, 0, 0]).is_err());
312
313 Ok(())
314 }
315
316 #[test]
317 pub fn ed25519_keypair_base58_encode_decode() -> anyhow::Result<()> {
318 let keypair = Keypair::generate_ed25519();
319
320 let encoded_bytes = keypair.encode();
321 let encoded_base58 = encode_base58(&encoded_bytes);
322 let decoded_base58 = decode_base58(&encoded_base58)?;
323 assert_eq!(encoded_bytes, decoded_base58);
324
325 let encoded = keypair.encode_base58_string();
326 let keypair_decoded = Keypair::decode_base58_string(&encoded)?;
327 assert_eq!(keypair.public(), keypair_decoded.public());
328
329 assert!(Keypair::decode_base58_string("").is_err());
330 assert!(Keypair::decode_base58_string("a").is_err());
331 assert!(Keypair::decode_base58_string("ae").is_err());
332 assert!(Keypair::decode_base58_string("aeb").is_err());
333
334 Ok(())
335 }
336
337 #[test]
338 pub fn ed25519_public_key_encode_decode() -> anyhow::Result<()> {
339 let keypair = Keypair::generate_ed25519();
340
341 let encoded = keypair.public().encode();
342 let public_decoded = PublicKey::decode(&encoded)?;
343
344 assert_eq!(keypair.public(), public_decoded);
345
346 assert!(PublicKey::decode(&[]).is_err());
347 assert!(PublicKey::decode(&[0]).is_err());
348 assert!(PublicKey::decode(&[0, 0]).is_err());
349 assert!(PublicKey::decode(&[0, 0, 0]).is_err());
350
351 Ok(())
352 }
353
354 #[test]
355 pub fn ed25519_public_key_base58_encode_decode() -> anyhow::Result<()> {
356 let keypair = Keypair::generate_ed25519();
357
358 let encoded_bytes = keypair.public().encode();
359 let encoded_base58 = encode_base58(&encoded_bytes);
360 let decoded_base58 = decode_base58(&encoded_base58)?;
361 assert_eq!(encoded_bytes, decoded_base58);
362
363 let encoded = keypair.public().encode_base58_string();
364 let public_decoded = PublicKey::decode_base58_string(&encoded)?;
365 assert_eq!(keypair.public(), public_decoded);
366
367 assert!(PublicKey::decode_base58_string("").is_err());
368 assert!(PublicKey::decode_base58_string("p").is_err());
369 assert!(PublicKey::decode_base58_string("pe").is_err());
370 assert!(PublicKey::decode_base58_string("peb").is_err());
371
372 Ok(())
373 }
374
375 #[test]
376 pub fn signature_and_verification() -> anyhow::Result<()> {
377 let keypair = Keypair::generate_ed25519();
378
379 let msg = String::from("hello world").into_bytes();
380 let sig = keypair.sign(&msg)?;
381
382 let pk = keypair.public();
383 assert!(pk.verify(&msg, &sig));
384
385 let mut invalid_sig = sig.clone();
386 invalid_sig[5] = b'c';
387 invalid_sig[6] = b'd';
388 invalid_sig[7] = b'd';
389
390 assert!(!pk.verify(&msg, &invalid_sig));
391
392 let tampered_msg = String::from("h4x0r").into_bytes();
393 assert!(!pk.verify(&tampered_msg, &sig));
394 Ok(())
395 }
396}