ckb_crypto/secp/
signature.rs1use super::error::Error;
2use super::pubkey::Pubkey;
3use super::Message;
4use super::SECP256K1;
5use ckb_fixed_hash::{h256, H256, H520};
6use faster_hex::hex_string;
7use secp256k1::ecdsa::{RecoverableSignature, RecoveryId};
8use secp256k1::Message as SecpMessage;
9use std::fmt;
10use std::str::FromStr;
11
12#[derive(Clone)]
14pub struct Signature([u8; 65]);
15
16const N: H256 = h256!("0xffffffff_ffffffff_ffffffff_fffffffe_baaedce6_af48a03b_bfd25e8c_d0364141");
17const ONE: H256 = h256!("0x1");
18
19impl Signature {
20 pub fn r(&self) -> &[u8] {
22 &self.0[0..32]
23 }
24
25 pub fn s(&self) -> &[u8] {
27 &self.0[32..64]
28 }
29
30 pub fn v(&self) -> u8 {
32 self.0[64]
33 }
34
35 pub fn from_compact(rec_id: RecoveryId, ret: [u8; 64]) -> Self {
37 let mut data = [0; 65];
38 data[0..64].copy_from_slice(&ret[0..64]);
39 data[64] = Into::<i32>::into(rec_id) as u8;
40 Signature(data)
41 }
42
43 pub fn from_rsv(r: &H256, s: &H256, v: u8) -> Self {
45 let mut sig = [0u8; 65];
46 sig[0..32].copy_from_slice(r.as_bytes());
47 sig[32..64].copy_from_slice(s.as_bytes());
48 sig[64] = v;
49 Signature(sig)
50 }
51
52 pub fn from_slice(data: &[u8]) -> Result<Self, Error> {
54 if data.len() != 65 {
55 return Err(Error::InvalidSignature);
56 }
57 let mut sig = [0u8; 65];
58 sig[..].copy_from_slice(data);
59 Ok(Signature(sig))
60 }
61
62 pub fn is_valid(&self) -> bool {
64 let h_r = match H256::from_slice(self.r()) {
65 Ok(h_r) => h_r,
66 Err(_) => {
67 return false;
68 }
69 };
70
71 let h_s = match H256::from_slice(self.s()) {
72 Ok(h_s) => h_s,
73 Err(_) => {
74 return false;
75 }
76 };
77 self.v() <= 1 && h_r < N && h_r >= ONE && h_s < N && h_s >= ONE
78 }
79
80 pub fn to_recoverable(&self) -> Result<RecoverableSignature, Error> {
82 let recovery_id = RecoveryId::try_from(i32::from(self.0[64]))?;
83 Ok(RecoverableSignature::from_compact(
84 &self.0[0..64],
85 recovery_id,
86 )?)
87 }
88
89 pub fn recover(&self, message: &Message) -> Result<Pubkey, Error> {
91 let context = &SECP256K1;
92 let recoverable_signature = self.to_recoverable()?;
93 let message = SecpMessage::from_digest_slice(message.as_bytes())?;
94 let pubkey = context.recover_ecdsa(&message, &recoverable_signature)?;
95 let serialized = pubkey.serialize_uncompressed();
96
97 let mut pubkey = [0u8; 64];
98 pubkey.copy_from_slice(&serialized[1..65]);
99 Ok(pubkey.into())
100 }
101
102 pub fn serialize(&self) -> Vec<u8> {
104 Vec::from(&self.0[..])
105 }
106
107 pub fn serialize_der(&self) -> Vec<u8> {
109 self.to_recoverable()
110 .unwrap()
111 .to_standard()
112 .serialize_der()
113 .to_vec()
114 }
115}
116
117impl fmt::Debug for Signature {
118 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
119 f.debug_struct("Signature")
120 .field("r", &hex_string(&self.0[0..32]))
121 .field("s", &hex_string(&self.0[32..64]))
122 .field("v", &hex_string(&self.0[64..65]))
123 .finish()
124 }
125}
126
127impl From<H520> for Signature {
128 fn from(sig: H520) -> Self {
129 Signature(sig.0)
130 }
131}
132
133impl From<Signature> for H520 {
134 fn from(s: Signature) -> Self {
135 H520(s.0)
136 }
137}
138
139impl From<Vec<u8>> for Signature {
140 fn from(sig: Vec<u8>) -> Self {
141 let mut data = [0; 65];
142 data[0..65].copy_from_slice(sig.as_slice());
143 Signature(data)
144 }
145}
146
147impl FromStr for Signature {
148 type Err = Error;
149
150 fn from_str(s: &str) -> Result<Self, Self::Err> {
151 H520::from_str(s)
152 .map(Into::into)
153 .map_err(|_| Error::InvalidSignature)
154 }
155}