cardano_serialization_lib/chain_crypto/
sign.rs1use crate::chain_crypto::{
2 bech32::{self, Bech32},
3 key,
4};
5use crate::typed_bytes::{ByteArray, ByteSlice};
6use hex::FromHexError;
7use std::{fmt, marker::PhantomData, str::FromStr};
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub enum Verification {
11 Failed,
12 Success,
13}
14
15impl From<bool> for Verification {
16 fn from(b: bool) -> Self {
17 if b {
18 Verification::Success
19 } else {
20 Verification::Failed
21 }
22 }
23}
24
25#[derive(Debug, Copy, Clone, PartialEq, Eq)]
26pub enum SignatureError {
27 SizeInvalid { expected: usize, got: usize }, StructureInvalid,
29}
30
31#[derive(Debug, Clone, PartialEq)]
32pub enum SignatureFromStrError {
33 HexMalformed(FromHexError),
34 Invalid(SignatureError),
35}
36
37pub trait VerificationAlgorithm: key::AsymmetricPublicKey {
38 type Signature: AsRef<[u8]> + Clone;
39
40 const SIGNATURE_SIZE: usize;
41 const SIGNATURE_BECH32_HRP: &'static str;
42
43 fn verify_bytes(pubkey: &Self::Public, signature: &Self::Signature, msg: &[u8])
44 -> Verification;
45
46 fn signature_from_bytes(data: &[u8]) -> Result<Self::Signature, SignatureError>;
47}
48
49pub trait SigningAlgorithm: key::AsymmetricKey
50where
51 Self::PubAlg: VerificationAlgorithm,
52{
53 fn sign(key: &Self::Secret, msg: &[u8]) -> <Self::PubAlg as VerificationAlgorithm>::Signature;
54}
55
56#[derive(Hash)]
57pub struct Signature<T: ?Sized, A: VerificationAlgorithm> {
58 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 } => write!(
85 f,
86 "Invalid Signature size expecting {} got {}",
87 expected, got
88 ),
89 SignatureError::StructureInvalid => write!(f, "Invalid Signature structure"),
90 }
91 }
92}
93impl fmt::Display for SignatureFromStrError {
94 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
95 match self {
96 SignatureFromStrError::HexMalformed(_) => "hex encoding malformed",
97 SignatureFromStrError::Invalid(_) => "invalid signature data",
98 }
99 .fmt(f)
100 }
101}
102
103impl std::error::Error for SignatureError {}
104impl std::error::Error for SignatureFromStrError {
105 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
106 match self {
107 SignatureFromStrError::HexMalformed(e) => Some(e),
108 SignatureFromStrError::Invalid(e) => Some(e),
109 }
110 }
111}
112
113impl<A: VerificationAlgorithm, T> Signature<T, A> {
114 pub fn from_binary(sig: &[u8]) -> Result<Self, SignatureError> {
115 Ok(Signature {
116 signdata: A::signature_from_bytes(sig)?,
117 phantom: PhantomData,
118 })
119 }
120 pub fn coerce<U>(self) -> Signature<U, A> {
121 Signature {
122 signdata: self.signdata,
123 phantom: PhantomData,
124 }
125 }
126
127 pub fn safe_coerce<U: SafeSignatureCoerce<T>>(self) -> Signature<U, A> {
128 Signature {
129 signdata: self.signdata,
130 phantom: PhantomData,
131 }
132 }
133}
134
135pub trait SafeSignatureCoerce<T> {}
136
137impl<'a, T> SafeSignatureCoerce<ByteArray<T>> for ByteSlice<'a, T> {}
138
139impl<A: VerificationAlgorithm, T: AsRef<[u8]>> Signature<T, A> {
140 #[must_use]
141 pub fn verify(&self, publickey: &key::PublicKey<A>, object: &T) -> Verification {
142 <A as VerificationAlgorithm>::verify_bytes(&publickey.0, &self.signdata, object.as_ref())
143 }
144}
145
146impl<A: VerificationAlgorithm, T: ?Sized> Signature<T, A> {
147 #[must_use]
148 pub fn verify_slice(&self, publickey: &key::PublicKey<A>, slice: &[u8]) -> Verification {
149 <A as VerificationAlgorithm>::verify_bytes(&publickey.0, &self.signdata, slice)
150 }
151}
152
153impl<A: SigningAlgorithm> key::SecretKey<A>
166where
167 <A as key::AsymmetricKey>::PubAlg: VerificationAlgorithm,
168{
169 pub fn sign<T: AsRef<[u8]>>(&self, object: &T) -> Signature<T, A::PubAlg> {
170 Signature {
171 signdata: <A as SigningAlgorithm>::sign(&self.0, object.as_ref()),
172 phantom: PhantomData,
173 }
174 }
175
176 pub fn sign_slice<T: ?Sized>(&self, slice: &[u8]) -> Signature<T, A::PubAlg> {
177 Signature {
178 signdata: <A as SigningAlgorithm>::sign(&self.0, slice),
179 phantom: PhantomData,
180 }
181 }
182}
183
184impl<T, A: VerificationAlgorithm> Clone for Signature<T, A> {
185 fn clone(&self) -> Self {
186 Signature {
187 signdata: self.signdata.clone(),
188 phantom: std::marker::PhantomData,
189 }
190 }
191}
192
193impl<T, A: VerificationAlgorithm> PartialEq<Self> for Signature<T, A> {
194 fn eq(&self, other: &Self) -> bool {
195 self.signdata.as_ref() == other.signdata.as_ref() && self.phantom == other.phantom
196 }
197}
198
199impl<T, A: VerificationAlgorithm> Eq for Signature<T, A> {}
200
201impl<T: ?Sized, A: VerificationAlgorithm> AsRef<[u8]> for Signature<T, A> {
202 fn as_ref(&self) -> &[u8] {
203 self.signdata.as_ref()
204 }
205}
206
207impl<T, A: VerificationAlgorithm> Bech32 for Signature<T, A> {
208 const BECH32_HRP: &'static str = A::SIGNATURE_BECH32_HRP;
209
210 fn try_from_bech32_str(bech32_str: &str) -> Result<Self, bech32::Error> {
211 let bytes = bech32::try_from_bech32_to_bytes::<Self>(bech32_str)?;
212 Self::from_binary(&bytes).map_err(bech32::Error::data_invalid)
213 }
214
215 fn to_bech32_str(&self) -> String {
216 bech32::to_bech32_from_bytes::<Self>(self.as_ref())
217 }
218}
219
220#[cfg(test)]
221pub(crate) mod test {
222 use super::*;
223 use crate::chain_crypto::key::{AsymmetricKey, KeyPair};
224
225 pub(crate) fn keypair_signing_ok<A: AsymmetricKey + SigningAlgorithm>(
226 input: (KeyPair<A>, Vec<u8>),
227 ) -> bool
228 where
229 <A as AsymmetricKey>::PubAlg: VerificationAlgorithm,
230 {
231 let (sk, pk) = input.0.into_keys();
232 let data = input.1;
233
234 let signature = sk.sign(&data);
235 signature.verify(&pk, &data) == Verification::Success
236 }
237
238 pub(crate) fn keypair_signing_ko<A: AsymmetricKey + SigningAlgorithm>(
239 input: (KeyPair<A>, KeyPair<A>, Vec<u8>),
240 ) -> bool
241 where
242 <A as AsymmetricKey>::PubAlg: VerificationAlgorithm,
243 {
244 let (sk, pk) = input.0.into_keys();
245 let pk_random = input.1.public_key();
246 let data = input.2;
247
248 if &pk == pk_random {
249 return true;
250 }
251
252 let signature = sk.sign(&data);
253 signature.verify(&pk_random, &data) == Verification::Failed
254 }
255}