1pub 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
13pub const SIGNATURE_LENGTH: usize = 64;
15
16#[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 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 pub fn as_bytes(&self) -> &[u8] {
84 self.0.as_ref()
85 }
86
87 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}