1use std::{
2 fmt::{Debug, Display, Formatter},
3 hash::{Hash, Hasher},
4 io::{Error, ErrorKind, Read, Write},
5 str::FromStr,
6};
7
8use borsh::{BorshDeserialize, BorshSerialize};
9use ed25519_dalek::Verifier;
10use primitive_types::U256;
11use secp256k1::Message;
12
13use crate::{
14 PublicKey,
15 crypto::{
16 KeyType, SECP256K1_SIGNATURE_LENGTH, public_key::Secp256K1PublicKey, secret_key::SECP256K1,
17 split_key_type_data,
18 },
19 errors::{DataConversionError, SignatureErrors},
20};
21
22#[derive(Clone, PartialEq, Eq)]
24pub enum Signature {
25 ED25519(ed25519_dalek::Signature),
26 SECP256K1(Secp256K1Signature),
27}
28
29impl Hash for Signature {
32 fn hash<H: Hasher>(&self, state: &mut H) {
33 match self {
34 Self::ED25519(sig) => sig.to_bytes().hash(state),
35 Self::SECP256K1(sig) => sig.hash(state),
36 };
37 }
38}
39
40impl Signature {
41 pub fn from_parts(
43 signature_type: KeyType,
44 signature_data: &[u8],
45 ) -> Result<Self, DataConversionError> {
46 match signature_type {
47 KeyType::ED25519 => Ok(Self::ED25519(ed25519_dalek::Signature::from_bytes(
48 <&[u8; ed25519_dalek::SIGNATURE_LENGTH]>::try_from(signature_data)?,
49 ))),
50 KeyType::SECP256K1 => Ok(Self::SECP256K1(Secp256K1Signature::try_from(
51 signature_data,
52 )?)),
53 }
54 }
55
56 pub fn verify(&self, data: &[u8], public_key: &PublicKey) -> bool {
59 match (&self, public_key) {
60 (Self::ED25519(signature), PublicKey::ED25519(public_key)) => {
61 ed25519_dalek::VerifyingKey::from_bytes(&public_key.0)
62 .is_ok_and(|public_key| public_key.verify(data, signature).is_ok())
63 }
64 (Self::SECP256K1(signature), PublicKey::SECP256K1(public_key)) => {
65 let rec_id =
67 match secp256k1::ecdsa::RecoveryId::from_i32(i32::from(signature.0[64])) {
68 Ok(r) => r,
69 Err(_) => return false,
70 };
71 let rsig = match secp256k1::ecdsa::RecoverableSignature::from_compact(
72 &signature.0[0..64],
73 rec_id,
74 ) {
75 Ok(r) => r,
76 Err(_) => return false,
77 };
78 let sig = rsig.to_standard();
79 let pdata: [u8; 65] = {
80 let mut temp = [4u8; 65];
82 temp[1..65].copy_from_slice(&public_key.0);
83 temp
84 };
85 let message = match secp256k1::Message::from_slice(data) {
86 Ok(m) => m,
87 Err(_) => return false,
88 };
89 let pub_key = match secp256k1::PublicKey::from_slice(&pdata) {
90 Ok(p) => p,
91 Err(_) => return false,
92 };
93 SECP256K1.verify_ecdsa(&message, &sig, &pub_key).is_ok()
94 }
95 _ => false,
96 }
97 }
98
99 pub const fn key_type(&self) -> KeyType {
100 match self {
101 Self::ED25519(_) => KeyType::ED25519,
102 Self::SECP256K1(_) => KeyType::SECP256K1,
103 }
104 }
105}
106
107impl BorshSerialize for Signature {
108 fn serialize<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
109 match self {
110 Self::ED25519(signature) => {
111 BorshSerialize::serialize(&0u8, writer)?;
112 writer.write_all(&signature.to_bytes())?;
113 }
114 Self::SECP256K1(signature) => {
115 BorshSerialize::serialize(&1u8, writer)?;
116 writer.write_all(&signature.0)?;
117 }
118 }
119 Ok(())
120 }
121}
122
123impl BorshDeserialize for Signature {
124 fn deserialize_reader<R: Read>(rd: &mut R) -> std::io::Result<Self> {
125 let key_type = KeyType::try_from(u8::deserialize_reader(rd)?)
126 .map_err(|err| Error::new(ErrorKind::InvalidData, err.to_string()))?;
127 match key_type {
128 KeyType::ED25519 => {
129 let array: [u8; ed25519_dalek::SIGNATURE_LENGTH] =
130 BorshDeserialize::deserialize_reader(rd)?;
131 if array[ed25519_dalek::SIGNATURE_LENGTH - 1] & 0b1110_0000 != 0 {
136 return Err(Error::new(ErrorKind::InvalidData, "signature error"));
137 }
138 Ok(Self::ED25519(ed25519_dalek::Signature::from_bytes(&array)))
139 }
140 KeyType::SECP256K1 => {
141 let array: [u8; 65] = BorshDeserialize::deserialize_reader(rd)?;
142 Ok(Self::SECP256K1(Secp256K1Signature(array)))
143 }
144 }
145 }
146}
147
148impl Display for Signature {
149 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
150 let buf;
151 let (key_type, key_data) = match self {
152 Self::ED25519(signature) => {
153 buf = signature.to_bytes();
154 (KeyType::ED25519, &buf[..])
155 }
156 Self::SECP256K1(signature) => (KeyType::SECP256K1, &signature.0[..]),
157 };
158 write!(f, "{}:{}", key_type, bs58::encode(key_data).into_string())
159 }
160}
161
162impl Debug for Signature {
163 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
164 Display::fmt(self, f)
165 }
166}
167
168impl serde::Serialize for Signature {
169 fn serialize<S>(
170 &self,
171 serializer: S,
172 ) -> Result<<S as serde::Serializer>::Ok, <S as serde::Serializer>::Error>
173 where
174 S: serde::Serializer,
175 {
176 serializer.serialize_str(&self.to_string())
177 }
178}
179
180impl FromStr for Signature {
181 type Err = DataConversionError;
182
183 fn from_str(value: &str) -> Result<Self, Self::Err> {
184 let (sig_type, sig_data) = split_key_type_data(value)?;
185 Ok(match sig_type {
186 KeyType::ED25519 => {
187 let data = bs58::decode(sig_data)
188 .into_vec()
189 .map_err(DataConversionError::from)?
190 .try_into()?;
191 let sig = ed25519_dalek::Signature::from_bytes(&data);
192 Self::ED25519(sig)
193 }
194 KeyType::SECP256K1 => Self::SECP256K1(Secp256K1Signature(
195 bs58::decode(sig_data)
196 .into_vec()
197 .map_err(DataConversionError::from)?
198 .try_into()?,
199 )),
200 })
201 }
202}
203
204impl<'de> serde::Deserialize<'de> for Signature {
205 fn deserialize<D>(deserializer: D) -> Result<Self, <D as serde::Deserializer<'de>>::Error>
206 where
207 D: serde::Deserializer<'de>,
208 {
209 let s = <String as serde::Deserialize>::deserialize(deserializer)?;
210 s.parse()
211 .map_err(|err: DataConversionError| serde::de::Error::custom(err.to_string()))
212 }
213}
214
215const SECP256K1_N: U256 = U256([
216 0xbfd25e8cd0364141,
217 0xbaaedce6af48a03b,
218 0xfffffffffffffffe,
219 0xffffffffffffffff,
220]);
221
222const SECP256K1_N_HALF_ONE: U256 = U256([
224 0xdfe92f46681b20a1,
225 0x5d576e7357a4501d,
226 0xffffffffffffffff,
227 0x7fffffffffffffff,
228]);
229
230#[derive(Clone, Eq, PartialEq, Hash)]
231pub struct Secp256K1Signature(pub [u8; SECP256K1_SIGNATURE_LENGTH]);
232
233impl Secp256K1Signature {
234 pub fn check_signature_values(&self, reject_upper: bool) -> bool {
235 let mut r_bytes = [0u8; 32];
236 r_bytes.copy_from_slice(&self.0[0..32]);
237 let r = U256::from(r_bytes);
238
239 let mut s_bytes = [0u8; 32];
240 s_bytes.copy_from_slice(&self.0[32..64]);
241 let s = U256::from(s_bytes);
242
243 let s_check = if reject_upper {
244 SECP256K1_N_HALF_ONE
246 } else {
247 SECP256K1_N
248 };
249
250 r < SECP256K1_N && s < s_check
251 }
252
253 pub fn recover(&self, msg: [u8; 32]) -> Result<Secp256K1PublicKey, SignatureErrors> {
254 let recoverable_sig = secp256k1::ecdsa::RecoverableSignature::from_compact(
255 &self.0[0..64],
256 secp256k1::ecdsa::RecoveryId::from_i32(i32::from(self.0[64])).unwrap(),
257 )?;
258 let msg = Message::from_slice(&msg).unwrap();
259
260 let res = SECP256K1
261 .recover_ecdsa(&msg, &recoverable_sig)?
262 .serialize_uncompressed();
263
264 let pk = Secp256K1PublicKey::try_from(&res[1..65]).expect("cannot fail");
265
266 Ok(pk)
267 }
268}
269
270impl TryFrom<&[u8]> for Secp256K1Signature {
271 type Error = DataConversionError;
272
273 fn try_from(data: &[u8]) -> Result<Self, Self::Error> {
274 Ok(Self(
275 data.try_into()
276 .map_err(|_| Self::Error::IncorrectLength(data.len()))?,
277 ))
278 }
279}
280
281impl Debug for Secp256K1Signature {
282 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
283 Display::fmt(&bs58::encode(&self.0).into_string(), f)
284 }
285}