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 crypto::{
15 public_key::Secp256K1PublicKey, secret_key::SECP256K1, split_key_type_data, KeyType,
16 SECP256K1_SIGNATURE_LENGTH,
17 },
18 errors::{DataConversionError, SignatureErrors},
19 CryptoHash, PublicKey,
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: CryptoHash, 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.0.as_ref(), 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 = secp256k1::Message::from(data);
86 let pub_key = match secp256k1::PublicKey::from_slice(&pdata) {
87 Ok(p) => p,
88 Err(_) => return false,
89 };
90 SECP256K1.verify_ecdsa(&message, &sig, &pub_key).is_ok()
91 }
92 _ => false,
93 }
94 }
95
96 pub const fn key_type(&self) -> KeyType {
97 match self {
98 Self::ED25519(_) => KeyType::ED25519,
99 Self::SECP256K1(_) => KeyType::SECP256K1,
100 }
101 }
102}
103
104impl BorshSerialize for Signature {
105 fn serialize<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
106 match self {
107 Self::ED25519(signature) => {
108 BorshSerialize::serialize(&0u8, writer)?;
109 writer.write_all(&signature.to_bytes())?;
110 }
111 Self::SECP256K1(signature) => {
112 BorshSerialize::serialize(&1u8, writer)?;
113 writer.write_all(&signature.0)?;
114 }
115 }
116 Ok(())
117 }
118}
119
120impl BorshDeserialize for Signature {
121 fn deserialize_reader<R: Read>(rd: &mut R) -> std::io::Result<Self> {
122 let key_type = KeyType::try_from(u8::deserialize_reader(rd)?)
123 .map_err(|err| Error::new(ErrorKind::InvalidData, err.to_string()))?;
124 match key_type {
125 KeyType::ED25519 => {
126 let array: [u8; ed25519_dalek::SIGNATURE_LENGTH] =
127 BorshDeserialize::deserialize_reader(rd)?;
128 if array[ed25519_dalek::SIGNATURE_LENGTH - 1] & 0b1110_0000 != 0 {
133 return Err(Error::new(ErrorKind::InvalidData, "signature error"));
134 }
135 Ok(Self::ED25519(ed25519_dalek::Signature::from_bytes(&array)))
136 }
137 KeyType::SECP256K1 => {
138 let array: [u8; 65] = BorshDeserialize::deserialize_reader(rd)?;
139 Ok(Self::SECP256K1(Secp256K1Signature(array)))
140 }
141 }
142 }
143}
144
145impl Display for Signature {
146 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
147 let buf;
148 let (key_type, key_data) = match self {
149 Self::ED25519(signature) => {
150 buf = signature.to_bytes();
151 (KeyType::ED25519, &buf[..])
152 }
153 Self::SECP256K1(signature) => (KeyType::SECP256K1, &signature.0[..]),
154 };
155 write!(f, "{}:{}", key_type, bs58::encode(key_data).into_string())
156 }
157}
158
159impl Debug for Signature {
160 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
161 Display::fmt(self, f)
162 }
163}
164
165impl serde::Serialize for Signature {
166 fn serialize<S>(
167 &self,
168 serializer: S,
169 ) -> Result<<S as serde::Serializer>::Ok, <S as serde::Serializer>::Error>
170 where
171 S: serde::Serializer,
172 {
173 serializer.serialize_str(&self.to_string())
174 }
175}
176
177impl FromStr for Signature {
178 type Err = DataConversionError;
179
180 fn from_str(value: &str) -> Result<Self, Self::Err> {
181 let (sig_type, sig_data) = split_key_type_data(value)?;
182 Ok(match sig_type {
183 KeyType::ED25519 => {
184 let data = bs58::decode(sig_data)
185 .into_vec()
186 .map_err(DataConversionError::from)?
187 .try_into()?;
188 let sig = ed25519_dalek::Signature::from_bytes(&data);
189 Self::ED25519(sig)
190 }
191 KeyType::SECP256K1 => Self::SECP256K1(Secp256K1Signature(
192 bs58::decode(sig_data)
193 .into_vec()
194 .map_err(DataConversionError::from)?
195 .try_into()?,
196 )),
197 })
198 }
199}
200
201impl<'de> serde::Deserialize<'de> for Signature {
202 fn deserialize<D>(deserializer: D) -> Result<Self, <D as serde::Deserializer<'de>>::Error>
203 where
204 D: serde::Deserializer<'de>,
205 {
206 let s = <String as serde::Deserialize>::deserialize(deserializer)?;
207 s.parse()
208 .map_err(|err: DataConversionError| serde::de::Error::custom(err.to_string()))
209 }
210}
211
212const SECP256K1_N: U256 = U256([
213 0xbfd25e8cd0364141,
214 0xbaaedce6af48a03b,
215 0xfffffffffffffffe,
216 0xffffffffffffffff,
217]);
218
219const SECP256K1_N_HALF_ONE: U256 = U256([
221 0xdfe92f46681b20a1,
222 0x5d576e7357a4501d,
223 0xffffffffffffffff,
224 0x7fffffffffffffff,
225]);
226
227#[derive(Clone, Eq, PartialEq, Hash)]
228pub struct Secp256K1Signature(pub [u8; SECP256K1_SIGNATURE_LENGTH]);
229
230impl Secp256K1Signature {
231 pub fn check_signature_values(&self, reject_upper: bool) -> bool {
232 let mut r_bytes = [0u8; 32];
233 r_bytes.copy_from_slice(&self.0[0..32]);
234 let r = U256::from(r_bytes);
235
236 let mut s_bytes = [0u8; 32];
237 s_bytes.copy_from_slice(&self.0[32..64]);
238 let s = U256::from(s_bytes);
239
240 let s_check = if reject_upper {
241 SECP256K1_N_HALF_ONE
243 } else {
244 SECP256K1_N
245 };
246
247 r < SECP256K1_N && s < s_check
248 }
249
250 pub fn recover(&self, msg: CryptoHash) -> Result<Secp256K1PublicKey, SignatureErrors> {
251 let recovery_id = secp256k1::ecdsa::RecoveryId::from_i32(i32::from(self.0[64]))?;
252
253 let recoverable_sig =
254 secp256k1::ecdsa::RecoverableSignature::from_compact(&self.0[0..64], recovery_id)?;
255 let msg = Message::from_slice(&msg.0)?;
256
257 let res = SECP256K1
258 .recover_ecdsa(&msg, &recoverable_sig)?
259 .serialize_uncompressed();
260 let mut pk = [0u8; 64];
261 pk.copy_from_slice(&res[1..65]);
262
263 Ok(Secp256K1PublicKey(pk))
264 }
265}
266
267impl TryFrom<&[u8]> for Secp256K1Signature {
268 type Error = DataConversionError;
269
270 fn try_from(data: &[u8]) -> Result<Self, Self::Error> {
271 Ok(Self(
272 data.try_into()
273 .map_err(|_| Self::Error::IncorrectLength(data.len()))?,
274 ))
275 }
276}
277
278impl Debug for Secp256K1Signature {
279 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
280 Display::fmt(&bs58::encode(&self.0).into_string(), f)
281 }
282}