1use crate::{
18 math::{pubkey_to_public, public_to_pubkey},
19 public_to_address, Address, Error, Message, Public, Secret,
20};
21use cfx_types::{H256, H520};
22use rustc_hex::{FromHex, ToHex};
23use secp256k1::{
24 ecdsa::{RecoverableSignature, RecoveryId},
25 Error as SecpError, Message as SecpMessage, SecretKey, SECP256K1,
26};
27use std::{
28 cmp::PartialEq,
29 fmt,
30 hash::{Hash, Hasher},
31 ops::{Deref, DerefMut},
32 str::FromStr,
33};
34
35#[repr(C)]
37pub struct Signature([u8; 65]);
38
39impl Signature {
40 pub fn r(&self) -> &[u8] { &self.0[0..32] }
42
43 pub fn s(&self) -> &[u8] { &self.0[32..64] }
45
46 pub fn v(&self) -> u8 { self.0[64] }
48
49 pub fn into_electrum(mut self) -> [u8; 65] {
52 self.0[64] += 27;
53 self.0
54 }
55
56 pub fn from_electrum(data: &[u8]) -> Self {
59 if data.len() != 65 || data[64] < 27 {
60 return Signature::default();
62 }
63
64 let mut sig = [0u8; 65];
65 sig.copy_from_slice(data);
66 sig[64] -= 27;
67 Signature(sig)
68 }
69
70 pub fn from_rsv(r: &H256, s: &H256, v: u8) -> Self {
72 let mut sig = [0u8; 65];
73 sig[0..32].copy_from_slice(r.as_ref());
74 sig[32..64].copy_from_slice(s.as_ref());
75 sig[64] = v;
76 Signature(sig)
77 }
78
79 pub fn is_low_s(&self) -> bool {
81 const MASK: H256 = H256([
83 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
84 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x5D, 0x57, 0x6E, 0x73, 0x57, 0xA4,
85 0x50, 0x1D, 0xDF, 0xE9, 0x2F, 0x46, 0x68, 0x1B, 0x20, 0xA0,
86 ]);
87 H256::from_slice(self.s()) <= MASK
88 }
89
90 pub fn is_valid(&self) -> bool {
92 const MASK: H256 = H256([
94 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
95 0xff, 0xff, 0xff, 0xff, 0xfe, 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48,
96 0xa0, 0x3b, 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41,
97 ]);
98 const ONE: H256 = H256([
99 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
100 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
101 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
102 ]);
103 let r = H256::from_slice(self.r());
104 let s = H256::from_slice(self.s());
105 self.v() <= 1 && r < MASK && r >= ONE && s < MASK && s >= ONE
106 }
107}
108
109impl PartialEq for Signature {
112 fn eq(&self, other: &Self) -> bool { &self.0[..] == &other.0[..] }
113}
114
115impl Eq for Signature {}
118
119impl fmt::Debug for Signature {
121 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
122 f.debug_struct("Signature")
123 .field("r", &self.0[0..32].to_hex::<String>())
124 .field("s", &self.0[32..64].to_hex::<String>())
125 .field("v", &self.0[64..65].to_hex::<String>())
126 .finish()
127 }
128}
129
130impl fmt::Display for Signature {
131 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
132 write!(f, "{}", self.to_hex::<String>())
133 }
134}
135
136impl FromStr for Signature {
137 type Err = Error;
138
139 fn from_str(s: &str) -> Result<Self, Self::Err> {
140 match s.from_hex::<Vec<u8>>() {
141 Ok(ref hex) if hex.len() == 65 => {
142 let mut data = [0; 65];
143 data.copy_from_slice(&hex[0..65]);
144 Ok(Signature(data))
145 }
146 _ => Err(Error::InvalidSignature),
147 }
148 }
149}
150
151impl Default for Signature {
152 fn default() -> Self { Signature([0; 65]) }
153}
154
155impl Hash for Signature {
156 fn hash<H: Hasher>(&self, state: &mut H) { H520::from(self.0).hash(state); }
157}
158
159impl Clone for Signature {
160 fn clone(&self) -> Self { Signature(self.0) }
161}
162
163impl From<[u8; 65]> for Signature {
164 fn from(s: [u8; 65]) -> Self { Signature(s) }
165}
166
167impl Into<[u8; 65]> for Signature {
168 fn into(self) -> [u8; 65] { self.0 }
169}
170
171impl From<Signature> for H520 {
172 fn from(s: Signature) -> Self { H520::from(s.0) }
173}
174
175impl From<H520> for Signature {
176 fn from(bytes: H520) -> Self { Signature(bytes.into()) }
177}
178
179impl Deref for Signature {
180 type Target = [u8; 65];
181
182 fn deref(&self) -> &Self::Target { &self.0 }
183}
184
185impl DerefMut for Signature {
186 fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 }
187}
188
189pub fn sign(secret: &Secret, message: &Message) -> Result<Signature, Error> {
190 let sec = SecretKey::from_slice(secret.as_ref())?;
191 let s = SECP256K1.sign_ecdsa_recoverable(
192 &SecpMessage::from_digest(message.to_fixed_bytes()),
193 &sec,
194 );
195 let (rec_id, data) = s.serialize_compact();
196 let mut data_arr = [0; 65];
197
198 data_arr[0..64].copy_from_slice(&data[0..64]);
200 data_arr[64] = i32::from(rec_id) as u8;
201 Ok(Signature(data_arr))
202}
203
204pub fn verify_public(
205 public: &Public, signature: &Signature, message: &Message,
206) -> Result<bool, Error> {
207 let rsig = RecoverableSignature::from_compact(
208 &signature[0..64],
209 RecoveryId::try_from(signature[64] as i32)?,
210 )?;
211 let sig = rsig.to_standard();
212 let publ = public_to_pubkey(public)?;
213 match SECP256K1.verify_ecdsa(
214 &SecpMessage::from_digest(message.to_fixed_bytes()),
215 &sig,
216 &publ,
217 ) {
218 Ok(_) => Ok(true),
219 Err(SecpError::IncorrectSignature) => Ok(false),
220 Err(x) => Err(Error::from(x)),
221 }
222}
223
224pub fn verify_address(
225 address: &Address, signature: &Signature, message: &Message,
226) -> Result<bool, Error> {
227 let public = recover(signature, message)?;
228 let recovered_address = public_to_address(&public, true);
229 Ok(address == &recovered_address)
230}
231
232pub fn recover(
233 signature: &Signature, message: &Message,
234) -> Result<Public, Error> {
235 let rsig = RecoverableSignature::from_compact(
236 &signature[0..64],
237 RecoveryId::try_from(signature[64] as i32)?,
238 )?;
239 let pubkey = SECP256K1.recover_ecdsa(
240 &SecpMessage::from_digest(message.to_fixed_bytes()),
241 &rsig,
242 )?;
243 Ok(pubkey_to_public(&pubkey))
244}
245
246#[cfg(test)]
247mod tests {
248 use super::{recover, sign, verify_address, verify_public, Signature};
249 use crate::{KeyPairGenerator, Message, Random};
250 use std::str::FromStr;
251
252 #[test]
253 fn vrs_conversion() {
254 let keypair = Random.generate().unwrap();
256 let message = Message::default();
257 let signature = sign(keypair.secret(), &message).unwrap();
258
259 let vrs = signature.clone().into_electrum();
261 let from_vrs = Signature::from_electrum(&vrs);
262
263 assert_eq!(signature, from_vrs);
265 }
266
267 #[test]
268 fn signature_to_and_from_str() {
269 let keypair = Random.generate().unwrap();
270 let message = Message::default();
271 let signature = sign(keypair.secret(), &message).unwrap();
272 let string = format!("{}", signature);
273 let deserialized = Signature::from_str(&string).unwrap();
274 assert_eq!(signature, deserialized);
275 }
276
277 #[test]
278 fn sign_and_recover_public() {
279 let keypair = Random.generate().unwrap();
280 let message = Message::default();
281 let signature = sign(keypair.secret(), &message).unwrap();
282 assert_eq!(keypair.public(), &recover(&signature, &message).unwrap());
283 }
284
285 #[test]
286 fn sign_and_verify_public() {
287 let keypair = Random.generate().unwrap();
288 let message = Message::default();
289 let signature = sign(keypair.secret(), &message).unwrap();
290 assert!(verify_public(keypair.public(), &signature, &message).unwrap());
291 }
292
293 #[test]
294 fn sign_and_verify_address() {
295 let keypair = Random.generate().unwrap();
296 let message = Message::default();
297 let signature = sign(keypair.secret(), &message).unwrap();
298 assert!(
299 verify_address(&keypair.address(), &signature, &message).unwrap()
300 );
301 }
302}