sc_network_types/
ed25519.rs1use crate::PeerId;
22use core::{cmp, fmt, hash};
23use ed25519_dalek::{self as ed25519, Signer as _, Verifier as _};
24use libp2p_identity::ed25519 as libp2p_ed25519;
25use litep2p::crypto::ed25519 as litep2p_ed25519;
26use zeroize::Zeroize;
27
28#[derive(Clone)]
30pub struct Keypair(ed25519::SigningKey);
31
32impl Keypair {
33 pub fn generate() -> Keypair {
35 Keypair::from(SecretKey::generate())
36 }
37
38 pub fn to_bytes(&self) -> [u8; 64] {
42 self.0.to_keypair_bytes()
43 }
44
45 pub fn try_from_bytes(kp: &mut [u8]) -> Result<Keypair, DecodingError> {
50 let bytes = <[u8; 64]>::try_from(&*kp)
51 .map_err(|e| DecodingError::KeypairParseError(Box::new(e)))?;
52
53 ed25519::SigningKey::from_keypair_bytes(&bytes)
54 .map(|k| {
55 kp.zeroize();
56 Keypair(k)
57 })
58 .map_err(|e| DecodingError::KeypairParseError(Box::new(e)))
59 }
60
61 pub fn sign(&self, msg: &[u8]) -> Vec<u8> {
63 self.0.sign(msg).to_bytes().to_vec()
64 }
65
66 pub fn public(&self) -> PublicKey {
68 PublicKey(self.0.verifying_key())
69 }
70
71 pub fn secret(&self) -> SecretKey {
73 SecretKey(self.0.to_bytes())
74 }
75}
76
77impl fmt::Debug for Keypair {
78 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
79 f.debug_struct("Keypair").field("public", &self.0.verifying_key()).finish()
80 }
81}
82
83impl From<litep2p_ed25519::Keypair> for Keypair {
84 fn from(kp: litep2p_ed25519::Keypair) -> Self {
85 Self::try_from_bytes(&mut kp.to_bytes())
86 .expect("ed25519_dalek in substrate & litep2p to use the same format")
87 }
88}
89
90impl From<Keypair> for litep2p_ed25519::Keypair {
91 fn from(kp: Keypair) -> Self {
92 Self::try_from_bytes(&mut kp.to_bytes())
93 .expect("ed25519_dalek in substrate & litep2p to use the same format")
94 }
95}
96
97impl From<libp2p_ed25519::Keypair> for Keypair {
98 fn from(kp: libp2p_ed25519::Keypair) -> Self {
99 Self::try_from_bytes(&mut kp.to_bytes())
100 .expect("ed25519_dalek in substrate & libp2p to use the same format")
101 }
102}
103
104impl From<Keypair> for libp2p_ed25519::Keypair {
105 fn from(kp: Keypair) -> Self {
106 Self::try_from_bytes(&mut kp.to_bytes())
107 .expect("ed25519_dalek in substrate & libp2p to use the same format")
108 }
109}
110
111impl From<Keypair> for SecretKey {
113 fn from(kp: Keypair) -> SecretKey {
114 SecretKey(kp.0.to_bytes())
115 }
116}
117
118impl From<SecretKey> for Keypair {
120 fn from(sk: SecretKey) -> Keypair {
121 let signing = ed25519::SigningKey::from_bytes(&sk.0);
122 Keypair(signing)
123 }
124}
125
126#[derive(Eq, Clone)]
128pub struct PublicKey(ed25519::VerifyingKey);
129
130impl fmt::Debug for PublicKey {
131 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
132 f.write_str("PublicKey(compressed): ")?;
133 for byte in self.0.as_bytes() {
134 write!(f, "{byte:x}")?;
135 }
136 Ok(())
137 }
138}
139
140impl cmp::PartialEq for PublicKey {
141 fn eq(&self, other: &Self) -> bool {
142 self.0.as_bytes().eq(other.0.as_bytes())
143 }
144}
145
146impl hash::Hash for PublicKey {
147 fn hash<H: hash::Hasher>(&self, state: &mut H) {
148 self.0.as_bytes().hash(state);
149 }
150}
151
152impl cmp::PartialOrd for PublicKey {
153 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
154 Some(self.cmp(other))
155 }
156}
157
158impl cmp::Ord for PublicKey {
159 fn cmp(&self, other: &Self) -> cmp::Ordering {
160 self.0.as_bytes().cmp(other.0.as_bytes())
161 }
162}
163
164impl PublicKey {
165 pub fn verify(&self, msg: &[u8], sig: &[u8]) -> bool {
167 ed25519::Signature::try_from(sig).and_then(|s| self.0.verify(msg, &s)).is_ok()
168 }
169
170 pub fn to_bytes(&self) -> [u8; 32] {
173 self.0.to_bytes()
174 }
175
176 pub fn try_from_bytes(k: &[u8]) -> Result<PublicKey, DecodingError> {
179 let k =
180 <[u8; 32]>::try_from(k).map_err(|e| DecodingError::PublicKeyParseError(Box::new(e)))?;
181 ed25519::VerifyingKey::from_bytes(&k)
182 .map_err(|e| DecodingError::PublicKeyParseError(Box::new(e)))
183 .map(PublicKey)
184 }
185
186 pub fn to_peer_id(&self) -> PeerId {
188 litep2p::PeerId::from(litep2p::crypto::PublicKey::Ed25519(self.clone().into())).into()
189 }
190}
191
192impl From<litep2p_ed25519::PublicKey> for PublicKey {
193 fn from(k: litep2p_ed25519::PublicKey) -> Self {
194 Self::try_from_bytes(&k.to_bytes())
195 .expect("ed25519_dalek in substrate & litep2p to use the same format")
196 }
197}
198
199impl From<PublicKey> for litep2p_ed25519::PublicKey {
200 fn from(k: PublicKey) -> Self {
201 Self::try_from_bytes(&k.to_bytes())
202 .expect("ed25519_dalek in substrate & litep2p to use the same format")
203 }
204}
205
206impl From<libp2p_ed25519::PublicKey> for PublicKey {
207 fn from(k: libp2p_ed25519::PublicKey) -> Self {
208 Self::try_from_bytes(&k.to_bytes())
209 .expect("ed25519_dalek in substrate & libp2p to use the same format")
210 }
211}
212
213impl From<PublicKey> for libp2p_ed25519::PublicKey {
214 fn from(k: PublicKey) -> Self {
215 Self::try_from_bytes(&k.to_bytes())
216 .expect("ed25519_dalek in substrate & libp2p to use the same format")
217 }
218}
219
220#[derive(Clone)]
222pub struct SecretKey(ed25519::SecretKey);
223
224impl AsRef<[u8]> for SecretKey {
226 fn as_ref(&self) -> &[u8] {
227 &self.0[..]
228 }
229}
230
231impl fmt::Debug for SecretKey {
232 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
233 write!(f, "SecretKey")
234 }
235}
236
237impl SecretKey {
238 pub fn generate() -> SecretKey {
240 let signing = ed25519::SigningKey::generate(&mut rand::rngs::OsRng);
241 SecretKey(signing.to_bytes())
242 }
243
244 pub fn try_from_bytes(mut sk_bytes: impl AsMut<[u8]>) -> Result<SecretKey, DecodingError> {
249 let sk_bytes = sk_bytes.as_mut();
250 let secret = <[u8; 32]>::try_from(&*sk_bytes)
251 .map_err(|e| DecodingError::SecretKeyParseError(Box::new(e)))?;
252 sk_bytes.zeroize();
253 Ok(SecretKey(secret))
254 }
255
256 pub fn to_bytes(&self) -> [u8; 32] {
257 self.0
258 }
259}
260
261impl Drop for SecretKey {
262 fn drop(&mut self) {
263 self.0.zeroize();
264 }
265}
266
267impl From<litep2p_ed25519::SecretKey> for SecretKey {
268 fn from(sk: litep2p_ed25519::SecretKey) -> Self {
269 Self::try_from_bytes(&mut sk.to_bytes()).expect("Ed25519 key to be 32 bytes length")
270 }
271}
272
273impl From<SecretKey> for litep2p_ed25519::SecretKey {
274 fn from(sk: SecretKey) -> Self {
275 Self::try_from_bytes(&mut sk.to_bytes())
276 .expect("litep2p `SecretKey` to accept 32 bytes as Ed25519 key")
277 }
278}
279
280impl From<libp2p_ed25519::SecretKey> for SecretKey {
281 fn from(sk: libp2p_ed25519::SecretKey) -> Self {
282 Self::try_from_bytes(&mut sk.as_ref().to_owned())
283 .expect("Ed25519 key to be 32 bytes length")
284 }
285}
286
287impl From<SecretKey> for libp2p_ed25519::SecretKey {
288 fn from(sk: SecretKey) -> Self {
289 Self::try_from_bytes(&mut sk.to_bytes())
290 .expect("libp2p `SecretKey` to accept 32 bytes as Ed25519 key")
291 }
292}
293
294#[derive(Debug, thiserror::Error)]
296pub enum DecodingError {
297 #[error("failed to parse Ed25519 keypair: {0}")]
298 KeypairParseError(Box<dyn std::error::Error + Send + Sync>),
299 #[error("failed to parse Ed25519 secret key: {0}")]
300 SecretKeyParseError(Box<dyn std::error::Error + Send + Sync>),
301 #[error("failed to parse Ed25519 public key: {0}")]
302 PublicKeyParseError(Box<dyn std::error::Error + Send + Sync>),
303}
304
305#[cfg(test)]
306mod tests {
307 use super::*;
308 use quickcheck::*;
309
310 fn eq_keypairs(kp1: &Keypair, kp2: &Keypair) -> bool {
311 kp1.public() == kp2.public() && kp1.0.to_bytes() == kp2.0.to_bytes()
312 }
313
314 #[test]
315 fn ed25519_keypair_encode_decode() {
316 fn prop() -> bool {
317 let kp1 = Keypair::generate();
318 let mut kp1_enc = kp1.to_bytes();
319 let kp2 = Keypair::try_from_bytes(&mut kp1_enc).unwrap();
320 eq_keypairs(&kp1, &kp2) && kp1_enc.iter().all(|b| *b == 0)
321 }
322 QuickCheck::new().tests(10).quickcheck(prop as fn() -> _);
323 }
324
325 #[test]
326 fn ed25519_keypair_from_secret() {
327 fn prop() -> bool {
328 let kp1 = Keypair::generate();
329 let mut sk = kp1.0.to_bytes();
330 let kp2 = Keypair::from(SecretKey::try_from_bytes(&mut sk).unwrap());
331 eq_keypairs(&kp1, &kp2) && sk == [0u8; 32]
332 }
333 QuickCheck::new().tests(10).quickcheck(prop as fn() -> _);
334 }
335
336 #[test]
337 fn ed25519_signature() {
338 let kp = Keypair::generate();
339 let pk = kp.public();
340
341 let msg = "hello world".as_bytes();
342 let sig = kp.sign(msg);
343 assert!(pk.verify(msg, &sig));
344
345 let mut invalid_sig = sig.clone();
346 invalid_sig[3..6].copy_from_slice(&[10, 23, 42]);
347 assert!(!pk.verify(msg, &invalid_sig));
348
349 let invalid_msg = "h3ll0 w0rld".as_bytes();
350 assert!(!pk.verify(invalid_msg, &sig));
351 }
352
353 #[test]
354 fn substrate_kp_to_libs() {
355 let kp = Keypair::generate();
356 let kp_bytes = kp.to_bytes();
357 let kp1: libp2p_ed25519::Keypair = kp.clone().into();
358 let kp2: litep2p_ed25519::Keypair = kp.clone().into();
359 let kp3 = libp2p_ed25519::Keypair::try_from_bytes(&mut kp_bytes.clone()).unwrap();
360 let kp4 = litep2p_ed25519::Keypair::try_from_bytes(&mut kp_bytes.clone()).unwrap();
361
362 assert_eq!(kp_bytes, kp1.to_bytes());
363 assert_eq!(kp_bytes, kp2.to_bytes());
364
365 let msg = "hello world".as_bytes();
366 let sig = kp.sign(msg);
367 let sig1 = kp1.sign(msg);
368 let sig2 = kp2.sign(msg);
369 let sig3 = kp3.sign(msg);
370 let sig4 = kp4.sign(msg);
371
372 assert_eq!(sig, sig1);
373 assert_eq!(sig, sig2);
374 assert_eq!(sig, sig3);
375 assert_eq!(sig, sig4);
376
377 let pk1 = kp1.public();
378 let pk2 = kp2.public();
379 let pk3 = kp3.public();
380 let pk4 = kp4.public();
381
382 assert!(pk1.verify(msg, &sig));
383 assert!(pk2.verify(msg, &sig));
384 assert!(pk3.verify(msg, &sig));
385 assert!(pk4.verify(msg, &sig));
386 }
387
388 #[test]
389 fn litep2p_kp_to_substrate_kp() {
390 let kp = litep2p_ed25519::Keypair::generate();
391 let kp1: Keypair = kp.clone().into();
392 let kp2 = Keypair::try_from_bytes(&mut kp.to_bytes()).unwrap();
393
394 assert_eq!(kp.to_bytes(), kp1.to_bytes());
395
396 let msg = "hello world".as_bytes();
397 let sig = kp.sign(msg);
398 let sig1 = kp1.sign(msg);
399 let sig2 = kp2.sign(msg);
400
401 assert_eq!(sig, sig1);
402 assert_eq!(sig, sig2);
403
404 let pk1 = kp1.public();
405 let pk2 = kp2.public();
406
407 assert!(pk1.verify(msg, &sig));
408 assert!(pk2.verify(msg, &sig));
409 }
410
411 #[test]
412 fn libp2p_kp_to_substrate_kp() {
413 let kp = libp2p_ed25519::Keypair::generate();
414 let kp1: Keypair = kp.clone().into();
415 let kp2 = Keypair::try_from_bytes(&mut kp.to_bytes()).unwrap();
416
417 assert_eq!(kp.to_bytes(), kp1.to_bytes());
418
419 let msg = "hello world".as_bytes();
420 let sig = kp.sign(msg);
421 let sig1 = kp1.sign(msg);
422 let sig2 = kp2.sign(msg);
423
424 assert_eq!(sig, sig1);
425 assert_eq!(sig, sig2);
426
427 let pk1 = kp1.public();
428 let pk2 = kp2.public();
429
430 assert!(pk1.verify(msg, &sig));
431 assert!(pk2.verify(msg, &sig));
432 }
433
434 #[test]
435 fn substrate_pk_to_libs() {
436 let kp = Keypair::generate();
437 let pk = kp.public();
438 let pk_bytes = pk.to_bytes();
439 let pk1: libp2p_ed25519::PublicKey = pk.clone().into();
440 let pk2: litep2p_ed25519::PublicKey = pk.clone().into();
441 let pk3 = libp2p_ed25519::PublicKey::try_from_bytes(&pk_bytes).unwrap();
442 let pk4 = litep2p_ed25519::PublicKey::try_from_bytes(&pk_bytes).unwrap();
443
444 assert_eq!(pk_bytes, pk1.to_bytes());
445 assert_eq!(pk_bytes, pk2.to_bytes());
446
447 let msg = "hello world".as_bytes();
448 let sig = kp.sign(msg);
449
450 assert!(pk.verify(msg, &sig));
451 assert!(pk1.verify(msg, &sig));
452 assert!(pk2.verify(msg, &sig));
453 assert!(pk3.verify(msg, &sig));
454 assert!(pk4.verify(msg, &sig));
455 }
456
457 #[test]
458 fn litep2p_pk_to_substrate_pk() {
459 let kp = litep2p_ed25519::Keypair::generate();
460 let pk = kp.public();
461 let pk_bytes = pk.clone().to_bytes();
462 let pk1: PublicKey = pk.clone().into();
463 let pk2 = PublicKey::try_from_bytes(&pk_bytes).unwrap();
464
465 assert_eq!(pk_bytes, pk1.to_bytes());
466
467 let msg = "hello world".as_bytes();
468 let sig = kp.sign(msg);
469
470 assert!(pk.verify(msg, &sig));
471 assert!(pk1.verify(msg, &sig));
472 assert!(pk2.verify(msg, &sig));
473 }
474
475 #[test]
476 fn libp2p_pk_to_substrate_pk() {
477 let kp = libp2p_ed25519::Keypair::generate();
478 let pk = kp.public();
479 let pk_bytes = pk.clone().to_bytes();
480 let pk1: PublicKey = pk.clone().into();
481 let pk2 = PublicKey::try_from_bytes(&pk_bytes).unwrap();
482
483 assert_eq!(pk_bytes, pk1.to_bytes());
484
485 let msg = "hello world".as_bytes();
486 let sig = kp.sign(msg);
487
488 assert!(pk.verify(msg, &sig));
489 assert!(pk1.verify(msg, &sig));
490 assert!(pk2.verify(msg, &sig));
491 }
492
493 #[test]
494 fn substrate_sk_to_libs() {
495 let sk = SecretKey::generate();
496 let sk_bytes = sk.to_bytes();
497 let sk1: libp2p_ed25519::SecretKey = sk.clone().into();
498 let sk2: litep2p_ed25519::SecretKey = sk.clone().into();
499 let sk3 = libp2p_ed25519::SecretKey::try_from_bytes(&mut sk_bytes.clone()).unwrap();
500 let sk4 = litep2p_ed25519::SecretKey::try_from_bytes(&mut sk_bytes.clone()).unwrap();
501
502 let kp: Keypair = sk.into();
503 let kp1: libp2p_ed25519::Keypair = sk1.into();
504 let kp2: litep2p_ed25519::Keypair = sk2.into();
505 let kp3: libp2p_ed25519::Keypair = sk3.into();
506 let kp4: litep2p_ed25519::Keypair = sk4.into();
507
508 let msg = "hello world".as_bytes();
509 let sig = kp.sign(msg);
510
511 assert_eq!(sig, kp1.sign(msg));
512 assert_eq!(sig, kp2.sign(msg));
513 assert_eq!(sig, kp3.sign(msg));
514 assert_eq!(sig, kp4.sign(msg));
515 }
516
517 #[test]
518 fn litep2p_sk_to_substrate_sk() {
519 let sk = litep2p_ed25519::SecretKey::generate();
520 let sk1: SecretKey = sk.clone().into();
521 let sk2 = SecretKey::try_from_bytes(&mut sk.to_bytes()).unwrap();
522
523 let kp: litep2p_ed25519::Keypair = sk.into();
524 let kp1: Keypair = sk1.into();
525 let kp2: Keypair = sk2.into();
526
527 let msg = "hello world".as_bytes();
528 let sig = kp.sign(msg);
529
530 assert_eq!(sig, kp1.sign(msg));
531 assert_eq!(sig, kp2.sign(msg));
532 }
533
534 #[test]
535 fn libp2p_sk_to_substrate_sk() {
536 let sk = libp2p_ed25519::SecretKey::generate();
537 let sk_bytes = sk.as_ref().to_owned();
538 let sk1: SecretKey = sk.clone().into();
539 let sk2 = SecretKey::try_from_bytes(sk_bytes).unwrap();
540
541 let kp: libp2p_ed25519::Keypair = sk.into();
542 let kp1: Keypair = sk1.into();
543 let kp2: Keypair = sk2.into();
544
545 let msg = "hello world".as_bytes();
546 let sig = kp.sign(msg);
547
548 assert_eq!(sig, kp1.sign(msg));
549 assert_eq!(sig, kp2.sign(msg));
550 }
551}