1use crate::chain_crypto::{
2 bech32::{self, Bech32},
3 key,
4};
5use crate::typed_bytes::{ByteArray, ByteSlice};
6use cbor_event::{de::Deserializer, se::Serializer};
7use hex::FromHexError;
8use std::{fmt, marker::PhantomData, str::FromStr};
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub enum Verification {
12 Failed,
13 Success,
14}
15
16impl From<bool> for Verification {
17 fn from(b: bool) -> Self {
18 if b {
19 Verification::Success
20 } else {
21 Verification::Failed
22 }
23 }
24}
25
26#[derive(Debug, Copy, Clone, PartialEq, Eq)]
27pub enum SignatureError {
28 SizeInvalid { expected: usize, got: usize }, StructureInvalid,
30}
31
32#[derive(Debug, Clone, PartialEq)]
33pub enum SignatureFromStrError {
34 HexMalformed(FromHexError),
35 Invalid(SignatureError),
36}
37
38pub trait VerificationAlgorithm: key::AsymmetricPublicKey {
39 type Signature: AsRef<[u8]> + Clone;
40
41 const SIGNATURE_SIZE: usize;
42 const SIGNATURE_BECH32_HRP: &'static str;
43
44 fn verify_bytes(pubkey: &Self::Public, signature: &Self::Signature, msg: &[u8])
45 -> Verification;
46
47 fn signature_from_bytes(data: &[u8]) -> Result<Self::Signature, SignatureError>;
48}
49
50pub trait SigningAlgorithm: key::AsymmetricKey
51where
52 Self::PubAlg: VerificationAlgorithm,
53{
54 fn sign(key: &Self::Secret, msg: &[u8]) -> <Self::PubAlg as VerificationAlgorithm>::Signature;
55}
56
57pub struct Signature<T: ?Sized, A: VerificationAlgorithm> {
58 pub signdata: A::Signature,
59 phantom: PhantomData<T>,
60}
61
62impl<A: VerificationAlgorithm, T> fmt::Debug for Signature<T, A> {
63 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
64 write!(f, "{}", hex::encode(self.signdata.as_ref()))
65 }
66}
67impl<A: VerificationAlgorithm, T> fmt::Display for Signature<T, A> {
68 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
69 write!(f, "{}", hex::encode(self.signdata.as_ref()))
70 }
71}
72impl<T, A: VerificationAlgorithm> FromStr for Signature<T, A> {
73 type Err = SignatureFromStrError;
74
75 fn from_str(hex: &str) -> Result<Self, Self::Err> {
76 let bytes = hex::decode(hex).map_err(SignatureFromStrError::HexMalformed)?;
77 Self::from_binary(&bytes).map_err(SignatureFromStrError::Invalid)
78 }
79}
80
81impl fmt::Display for SignatureError {
82 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
83 match self {
84 SignatureError::SizeInvalid { expected, got } => {
85 write!(f, "Invalid Signature size expecting {expected} got {got}")
86 }
87 SignatureError::StructureInvalid => write!(f, "Invalid Signature structure"),
88 }
89 }
90}
91impl fmt::Display for SignatureFromStrError {
92 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
93 match self {
94 SignatureFromStrError::HexMalformed(_) => "hex encoding malformed",
95 SignatureFromStrError::Invalid(_) => "invalid signature data",
96 }
97 .fmt(f)
98 }
99}
100
101impl std::error::Error for SignatureError {}
102impl std::error::Error for SignatureFromStrError {
103 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
104 match self {
105 SignatureFromStrError::HexMalformed(e) => Some(e),
106 SignatureFromStrError::Invalid(e) => Some(e),
107 }
108 }
109}
110
111impl<A: VerificationAlgorithm, T> Signature<T, A> {
112 pub fn from_binary(sig: &[u8]) -> Result<Self, SignatureError> {
113 Ok(Signature {
114 signdata: A::signature_from_bytes(sig)?,
115 phantom: PhantomData,
116 })
117 }
118 pub fn coerce<U>(self) -> Signature<U, A> {
119 Signature {
120 signdata: self.signdata,
121 phantom: PhantomData,
122 }
123 }
124
125 pub fn safe_coerce<U: SafeSignatureCoerce<T>>(self) -> Signature<U, A> {
126 Signature {
127 signdata: self.signdata,
128 phantom: PhantomData,
129 }
130 }
131}
132
133pub trait SafeSignatureCoerce<T> {}
134
135impl<'a, T> SafeSignatureCoerce<ByteArray<T>> for ByteSlice<'a, T> {}
136
137impl<A: VerificationAlgorithm, T: AsRef<[u8]>> Signature<T, A> {
138 #[must_use]
139 pub fn verify(&self, publickey: &key::PublicKey<A>, object: &T) -> Verification {
140 <A as VerificationAlgorithm>::verify_bytes(&publickey.0, &self.signdata, object.as_ref())
141 }
142}
143
144impl<A: VerificationAlgorithm, T: ?Sized> Signature<T, A> {
145 #[must_use]
146 pub fn verify_slice(&self, publickey: &key::PublicKey<A>, slice: &[u8]) -> Verification {
147 <A as VerificationAlgorithm>::verify_bytes(&publickey.0, &self.signdata, slice)
148 }
149}
150
151impl<A: SigningAlgorithm> key::SecretKey<A>
164where
165 <A as key::AsymmetricKey>::PubAlg: VerificationAlgorithm,
166{
167 pub fn sign<T: AsRef<[u8]>>(&self, object: &T) -> Signature<T, A::PubAlg> {
168 Signature {
169 signdata: <A as SigningAlgorithm>::sign(&self.0, object.as_ref()),
170 phantom: PhantomData,
171 }
172 }
173
174 pub fn sign_slice<T: ?Sized>(&self, slice: &[u8]) -> Signature<T, A::PubAlg> {
175 Signature {
176 signdata: <A as SigningAlgorithm>::sign(&self.0, slice),
177 phantom: PhantomData,
178 }
179 }
180}
181
182impl<T, A: VerificationAlgorithm> Clone for Signature<T, A> {
183 fn clone(&self) -> Self {
184 Signature {
185 signdata: self.signdata.clone(),
186 phantom: std::marker::PhantomData,
187 }
188 }
189}
190
191impl<T: ?Sized, A: VerificationAlgorithm> AsRef<[u8]> for Signature<T, A> {
192 fn as_ref(&self) -> &[u8] {
193 self.signdata.as_ref()
194 }
195}
196
197impl<T, A: VerificationAlgorithm> Bech32 for Signature<T, A> {
198 const BECH32_HRP: &'static str = A::SIGNATURE_BECH32_HRP;
199
200 fn try_from_bech32_str(bech32_str: &str) -> Result<Self, bech32::Error> {
201 let bytes = bech32::try_from_bech32_to_bytes::<Self>(bech32_str)?;
202 Self::from_binary(&bytes).map_err(bech32::Error::data_invalid)
203 }
204
205 fn to_bech32_str(&self) -> String {
206 bech32::to_bech32_from_bytes::<Self>(self.as_ref())
207 }
208}
209
210impl<T, A: VerificationAlgorithm> std::cmp::PartialEq<Self> for Signature<T, A> {
211 fn eq(&self, other: &Self) -> bool {
212 self.as_ref().eq(other.as_ref())
213 }
214}
215
216impl<T, A: VerificationAlgorithm> std::cmp::Eq for Signature<T, A> {}
217
218impl<U, A: VerificationAlgorithm> cbor_event::se::Serialize for Signature<U, A> {
219 fn serialize<'se, W: std::io::Write>(
220 &self,
221 serializer: &'se mut Serializer<W>,
222 ) -> cbor_event::Result<&'se mut Serializer<W>> {
223 serializer.write_bytes(self.as_ref())
224 }
225}
226
227impl<U, A: VerificationAlgorithm> cbor_event::de::Deserialize for Signature<U, A> {
228 fn deserialize<R: std::io::BufRead>(raw: &mut Deserializer<R>) -> cbor_event::Result<Self> {
229 let result = Signature::<U, A>::from_binary(raw.bytes()?.as_ref())
230 .map_err(|err| cbor_event::Error::CustomError(format!("{err}")))?;
231 Ok(result)
232 }
233}
234
235impl<U, A: VerificationAlgorithm> serde::Serialize for Signature<U, A> {
236 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
237 where
238 S: serde::Serializer,
239 {
240 serializer.serialize_str(&hex::encode(self.as_ref()))
241 }
242}
243
244impl<'de, U, A: VerificationAlgorithm> serde::de::Deserialize<'de> for Signature<U, A> {
245 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
246 where
247 D: serde::de::Deserializer<'de>,
248 {
249 let s = <String as serde::de::Deserialize>::deserialize(deserializer)?;
250 Signature::<U, A>::from_str(&s).map_err(|_e| {
251 serde::de::Error::invalid_value(
252 serde::de::Unexpected::Str(&s),
253 &"hex bytes for signature",
254 )
255 })
256 }
257}
258
259#[cfg(test)]
260pub(crate) mod test {
261 use super::*;
262 use crate::chain_crypto::key::{AsymmetricKey, KeyPair};
263
264 pub(crate) fn keypair_signing_ok<A: AsymmetricKey + SigningAlgorithm>(
265 input: (KeyPair<A>, Vec<u8>),
266 ) -> bool
267 where
268 <A as AsymmetricKey>::PubAlg: VerificationAlgorithm,
269 {
270 let (sk, pk) = input.0.into_keys();
271 let data = input.1;
272
273 let signature = sk.sign(&data);
274 signature.verify(&pk, &data) == Verification::Success
275 }
276
277 pub(crate) fn keypair_signing_ko<A: AsymmetricKey + SigningAlgorithm>(
278 input: (KeyPair<A>, KeyPair<A>, Vec<u8>),
279 ) -> bool
280 where
281 <A as AsymmetricKey>::PubAlg: VerificationAlgorithm,
282 {
283 let (sk, pk) = input.0.into_keys();
284 let pk_random = input.1.public_key();
285 let data = input.2;
286
287 if &pk == pk_random {
288 return true;
289 }
290
291 let signature = sk.sign(&data);
292 signature.verify(pk_random, &data) == Verification::Failed
293 }
294}