cita_tool/crypto/
cita_sm2.rs1use crate::crypto::{pubkey_to_address, CreateKey, Error, Message, PubKey, Sm2Privkey, Sm2Pubkey};
2use crate::{Signature, H256, H512};
3use efficient_sm2::{create_key_slice, KeyPair, PublicKey};
4use hex::encode;
5use std::fmt;
6use std::ops::{Deref, DerefMut};
7use types::Address;
8
9const SIGNATURE_BYTES_LEN: usize = 128;
10
11#[derive(Default, Clone)]
13pub struct Sm2KeyPair {
14 privkey: Sm2Privkey,
15 pubkey: Sm2Pubkey,
16}
17
18impl fmt::Display for Sm2KeyPair {
19 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
20 writeln!(f, "privkey: {}", encode(self.privkey.0))?;
21 writeln!(f, "pubkey: {}", encode(self.pubkey.0))?;
22 write!(f, "address: {}", encode(self.address().0))
23 }
24}
25
26impl CreateKey for Sm2KeyPair {
27 type PrivKey = Sm2Privkey;
28 type PubKey = Sm2Pubkey;
29 type Error = Error;
30
31 fn from_privkey(privkey: Self::PrivKey) -> Result<Self, Self::Error> {
32 let key_pair = KeyPair::new(privkey.as_bytes()).map_err(|_| Error::InvalidPrivKey)?;
33 Ok(Sm2KeyPair {
34 privkey,
35 pubkey: H512::from_slice(&key_pair.public_key().bytes_less_safe()[1..]),
36 })
37 }
38
39 fn gen_keypair() -> Self {
40 let private = H256(create_key_slice());
41 Self::from_privkey(private).unwrap()
42 }
43
44 fn privkey(&self) -> &Self::PrivKey {
45 &self.privkey
46 }
47
48 fn pubkey(&self) -> &Self::PubKey {
49 &self.pubkey
50 }
51
52 fn address(&self) -> Address {
53 pubkey_to_address(&PubKey::Sm2(self.pubkey))
54 }
55
56 fn sign_raw(&self, data: &[u8]) -> Result<Signature, Error> {
57 let keypair = KeyPair::new(self.privkey.as_bytes()).map_err(|_| Error::InvalidPrivKey)?;
58 let sig = keypair.sign(data).map_err(|_| Error::InvalidMessage)?;
59
60 let mut sig_bytes = [0u8; SIGNATURE_BYTES_LEN];
61 sig_bytes[..32].copy_from_slice(&sig.r());
62 sig_bytes[32..64].copy_from_slice(&sig.s());
63 sig_bytes[64..].copy_from_slice(&keypair.public_key().bytes_less_safe()[1..]);
64 Ok(Signature::Sm2(Sm2Signature(sig_bytes)))
65 }
66}
67
68pub struct Sm2Signature(pub [u8; 128]);
70
71impl Sm2Signature {
72 #[inline]
74 pub fn r(&self) -> &[u8] {
75 &self.0[0..32]
76 }
77 #[inline]
79 pub fn s(&self) -> &[u8] {
80 &self.0[32..64]
81 }
82 #[inline]
84 pub fn pk(&self) -> &[u8] {
85 &self.0[64..]
86 }
87
88 pub fn recover(&self, message: &Message) -> Result<Sm2Pubkey, Error> {
90 let pub_key = Sm2Pubkey::from_slice(self.pk());
91 self.verify_public(&pub_key, message)?;
92
93 Ok(pub_key)
94 }
95
96 pub fn verify_public(&self, pubkey: &Sm2Pubkey, message: &Message) -> Result<bool, Error> {
98 let pub_key = PublicKey::from_slice(pubkey.as_bytes());
99 let sig = efficient_sm2::Signature::new(self.r(), self.s())
100 .map_err(|_| Error::InvalidSignature)?;
101 sig.verify(&pub_key, message.as_bytes())
102 .map_err(|_| Error::RecoverError)
103 .map(|_| true)
104 }
105}
106
107pub fn sm2_sign(privkey: &Sm2Privkey, message: &Message) -> Result<Sm2Signature, Error> {
109 let keypair = KeyPair::new(privkey.as_bytes()).map_err(|_| Error::InvalidPrivKey)?;
110 let sig = keypair
111 .sign(message.as_bytes())
112 .map_err(|_| Error::InvalidMessage)?;
113
114 let mut sig_bytes = [0u8; SIGNATURE_BYTES_LEN];
115 sig_bytes[..32].copy_from_slice(&sig.r());
116 sig_bytes[32..64].copy_from_slice(&sig.s());
117 sig_bytes[64..].copy_from_slice(&keypair.public_key().bytes_less_safe()[1..]);
118 Ok(Sm2Signature(sig_bytes))
119}
120
121impl fmt::Debug for Sm2Signature {
122 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
123 f.debug_struct("Signature")
124 .field("r", &encode(self.r()))
125 .field("s", &encode(self.s()))
126 .field("pk", &encode(self.pk()))
127 .finish()
128 }
129}
130
131impl fmt::Display for Sm2Signature {
132 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
133 write!(f, "{}", encode(&self.0[..]))
134 }
135}
136
137impl Default for Sm2Signature {
138 fn default() -> Self {
139 Sm2Signature([0; 128])
140 }
141}
142
143impl From<[u8; 128]> for Sm2Signature {
144 fn from(s: [u8; 128]) -> Self {
145 Sm2Signature(s)
146 }
147}
148
149impl<'a> From<&'a [u8]> for Sm2Signature {
150 fn from(slice: &'a [u8]) -> Sm2Signature {
151 assert_eq!(slice.len(), SIGNATURE_BYTES_LEN);
152 let mut bytes = [0u8; SIGNATURE_BYTES_LEN];
153 bytes.copy_from_slice(slice);
154 Sm2Signature(bytes)
155 }
156}
157
158impl fmt::LowerHex for Sm2Signature {
159 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
160 for i in &self.0[..] {
161 write!(f, "{i:02x}")?;
162 }
163 Ok(())
164 }
165}
166
167impl Deref for Sm2Signature {
168 type Target = [u8; 128];
169
170 fn deref(&self) -> &Self::Target {
171 &self.0
172 }
173}
174
175impl DerefMut for Sm2Signature {
176 fn deref_mut(&mut self) -> &mut Self::Target {
177 &mut self.0
178 }
179}
180
181#[cfg(test)]
182mod tests {
183 use super::*;
184
185 #[test]
186 fn test_recover() {
187 let keypair = Sm2KeyPair::gen_keypair();
188 let msg = Message::default();
189 let sig = sm2_sign(keypair.privkey(), &msg).unwrap();
190 assert_eq!(keypair.pubkey(), &sig.recover(&msg).unwrap());
191 }
192}