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