sc_network/service/
signature.rs

1// This file is part of Substrate.
2//
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
5//
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10//
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15//
16// You should have received a copy of the GNU General Public License
17// along with this program. If not, see <https://www.gnu.org/licenses/>.
18//
19// If you read this, you are very thorough, congratulations.
20
21//! Signature-related code
22
23pub use libp2p::identity::SigningError;
24
25/// Public key.
26pub enum PublicKey {
27	/// Litep2p public key.
28	Libp2p(libp2p::identity::PublicKey),
29
30	/// Libp2p public key.
31	Litep2p(litep2p::crypto::PublicKey),
32}
33
34impl PublicKey {
35	/// Protobuf-encode [`PublicKey`].
36	pub fn encode_protobuf(&self) -> Vec<u8> {
37		match self {
38			Self::Libp2p(public) => public.encode_protobuf(),
39			Self::Litep2p(public) => public.to_protobuf_encoding(),
40		}
41	}
42
43	/// Get `PeerId` of the [`PublicKey`].
44	pub fn to_peer_id(&self) -> sc_network_types::PeerId {
45		match self {
46			Self::Libp2p(public) => public.to_peer_id().into(),
47			Self::Litep2p(public) => public.to_peer_id().into(),
48		}
49	}
50}
51
52/// Keypair.
53pub enum Keypair {
54	/// Litep2p keypair.
55	Libp2p(libp2p::identity::Keypair),
56
57	/// Libp2p keypair.
58	Litep2p(litep2p::crypto::ed25519::Keypair),
59}
60
61impl Keypair {
62	/// Generate ed25519 keypair.
63	pub fn generate_ed25519() -> Self {
64		Keypair::Litep2p(litep2p::crypto::ed25519::Keypair::generate())
65	}
66
67	/// Get [`Keypair`]'s public key.
68	pub fn public(&self) -> PublicKey {
69		match self {
70			Keypair::Libp2p(keypair) => PublicKey::Libp2p(keypair.public()),
71			Keypair::Litep2p(keypair) => PublicKey::Litep2p(keypair.public().into()),
72		}
73	}
74}
75
76/// A result of signing a message with a network identity. Since `PeerId` is potentially a hash of a
77/// `PublicKey`, you need to reveal the `PublicKey` next to the signature, so the verifier can check
78/// if the signature was made by the entity that controls a given `PeerId`.
79pub struct Signature {
80	/// The public key derived from the network identity that signed the message.
81	pub public_key: PublicKey,
82
83	/// The actual signature made for the message signed.
84	pub bytes: Vec<u8>,
85}
86
87impl Signature {
88	/// Create new [`Signature`].
89	pub fn new(public_key: PublicKey, bytes: Vec<u8>) -> Self {
90		Self { public_key, bytes }
91	}
92
93	/// Create a signature for a message with a given network identity.
94	pub fn sign_message(
95		message: impl AsRef<[u8]>,
96		keypair: &Keypair,
97	) -> Result<Self, SigningError> {
98		match keypair {
99			Keypair::Libp2p(keypair) => {
100				let public_key = keypair.public();
101				let bytes = keypair.sign(message.as_ref())?;
102
103				Ok(Signature { public_key: PublicKey::Libp2p(public_key), bytes })
104			},
105			Keypair::Litep2p(keypair) => {
106				let public_key = keypair.public();
107				let bytes = keypair.sign(message.as_ref());
108
109				Ok(Signature { public_key: PublicKey::Litep2p(public_key.into()), bytes })
110			},
111		}
112	}
113}