tendermint/
signature.rs

1//! Cryptographic (a.k.a. digital) signatures
2
3pub use ed25519::Signature as Ed25519Signature;
4#[cfg(feature = "secp256k1")]
5pub use k256::ecdsa::Signature as Secp256k1Signature;
6
7use bytes::Bytes;
8
9use tendermint_proto::Protobuf;
10
11use crate::{error::Error, prelude::*};
12
13/// The expected length of all currently supported signatures, in bytes.
14pub const SIGNATURE_LENGTH: usize = 64;
15
16/// Signatures
17#[derive(Clone, Debug, PartialEq, Eq)]
18pub struct Signature(Vec<u8>);
19
20impl Protobuf<Vec<u8>> for Signature {}
21
22impl TryFrom<Vec<u8>> for Signature {
23    type Error = Error;
24
25    fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> {
26        Self::new_non_empty(bytes)
27    }
28}
29
30impl TryFrom<&[u8]> for Signature {
31    type Error = Error;
32
33    fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
34        Self::new_non_empty(bytes)
35    }
36}
37
38impl From<Signature> for Vec<u8> {
39    fn from(value: Signature) -> Self {
40        value.0
41    }
42}
43
44impl TryFrom<Bytes> for Signature {
45    type Error = Error;
46
47    fn try_from(bytes: Bytes) -> Result<Self, Self::Error> {
48        Self::new_non_empty(bytes)
49    }
50}
51
52impl From<Signature> for Bytes {
53    fn from(value: Signature) -> Self {
54        value.0.into()
55    }
56}
57
58impl Signature {
59    /// Create a new signature from the given byte array, if non-empty.
60    ///
61    /// If the given byte array is empty, returns `Ok(None)`.
62    pub fn new<B: AsRef<[u8]>>(bytes: B) -> Result<Option<Self>, Error> {
63        let bytes = bytes.as_ref();
64        if bytes.is_empty() {
65            return Ok(None);
66        }
67        if bytes.len() != SIGNATURE_LENGTH {
68            return Err(Error::signature_invalid(format!(
69                "expected signature to be {} bytes long, but was {} bytes",
70                SIGNATURE_LENGTH,
71                bytes.len()
72            )));
73        }
74
75        Ok(Some(Self(bytes.to_vec())))
76    }
77
78    fn new_non_empty<B: AsRef<[u8]>>(bytes: B) -> Result<Self, Error> {
79        Self::new(bytes)?.ok_or_else(Error::empty_signature)
80    }
81
82    /// Return a reference to the underlying byte array
83    pub fn as_bytes(&self) -> &[u8] {
84        self.0.as_ref()
85    }
86
87    /// Return the underlying byte array
88    pub fn into_bytes(self) -> Vec<u8> {
89        self.0
90    }
91}
92
93impl AsRef<[u8]> for Signature {
94    fn as_ref(&self) -> &[u8] {
95        self.as_bytes()
96    }
97}
98
99impl From<Ed25519Signature> for Signature {
100    fn from(sig: Ed25519Signature) -> Signature {
101        Self(sig.to_vec())
102    }
103}
104
105#[cfg(feature = "rust-crypto")]
106impl From<ed25519_consensus::Signature> for Signature {
107    fn from(sig: ed25519_consensus::Signature) -> Signature {
108        Self(sig.to_bytes().to_vec())
109    }
110}
111
112#[cfg(feature = "secp256k1")]
113impl From<Secp256k1Signature> for Signature {
114    fn from(sig: Secp256k1Signature) -> Signature {
115        Self(sig.to_vec())
116    }
117}