cita_tool/
crypto.rs

1mod cita_secp256k1;
2mod cita_sm2;
3mod crypto_trait;
4
5pub use self::cita_secp256k1::{secp256k1_sign, Secp256k1KeyPair, Secp256k1Signature};
6pub use self::cita_sm2::{sm2_sign, Sm2KeyPair, Sm2Signature};
7pub use self::crypto_trait::{CreateKey, Error, Hashable};
8use crate::LowerHex;
9use hex::encode;
10use std::fmt;
11use std::str::FromStr;
12use types::{Address, H256, H512};
13
14/// Secp256k1 Private key
15pub type Secp256k1PrivKey = H256;
16/// Secp256k1 Public key
17pub type Secp256k1PubKey = H512;
18/// Sign Message
19pub type Message = H256;
20/// Sm2 Private key
21pub type Sm2Privkey = H256;
22/// Sm2 Public key
23pub type Sm2Pubkey = H512;
24
25/// Generate Address from public key
26pub fn pubkey_to_address(pubkey: &PubKey) -> Address {
27    match pubkey {
28        PubKey::Secp256k1(pubkey) => Address::from(pubkey.crypt_hash(Encryption::Secp256k1)),
29        PubKey::Sm2(pubkey) => Address::from(pubkey.crypt_hash(Encryption::Sm2)),
30        PubKey::Null => Address::default(),
31    }
32}
33
34/// Sign data
35pub fn sign(privkey: &PrivateKey, message: &Message) -> Signature {
36    match privkey {
37        PrivateKey::Secp256k1(pk) => Signature::Secp256k1(secp256k1_sign(pk, message).unwrap()),
38        PrivateKey::Sm2(pk) => Signature::Sm2(sm2_sign(pk, message).unwrap()),
39        PrivateKey::Null => Signature::Null,
40    }
41}
42
43/// Encryption enum
44#[derive(Clone, Copy)]
45pub enum Encryption {
46    /// Secp256k1
47    Secp256k1,
48    /// Sm2
49    Sm2,
50}
51
52impl FromStr for Encryption {
53    type Err = String;
54
55    fn from_str(s: &str) -> Result<Self, Self::Err> {
56        match s.to_lowercase().as_str() {
57            "secp256k1" => Ok(Encryption::Secp256k1),
58            "sm2" => Ok(Encryption::Sm2),
59            _ => Err("Unsupported algorithm".to_string()),
60        }
61    }
62}
63
64impl fmt::Debug for Encryption {
65    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
66        let msg = match self {
67            Encryption::Secp256k1 => "secp256k1",
68            Encryption::Sm2 => "sm2",
69        };
70        write!(f, "{msg}")
71    }
72}
73
74impl fmt::Display for Encryption {
75    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
76        let msg = match self {
77            Encryption::Secp256k1 => "secp256k1",
78            Encryption::Sm2 => "sm2",
79        };
80        write!(f, "{msg}")
81    }
82}
83
84/// Private key of Secp256k1/Sm2
85#[derive(Clone, Copy)]
86pub enum PrivateKey {
87    /// Secp256k1
88    Secp256k1(Secp256k1PrivKey),
89    /// Sm2
90    Sm2(Sm2Privkey),
91    /// null
92    Null,
93}
94
95impl PrivateKey {
96    /// Create private key
97    pub fn from_str(hex: &str, encryption: Encryption) -> Result<Self, String> {
98        match encryption {
99            Encryption::Secp256k1 => Ok(PrivateKey::Secp256k1(
100                Secp256k1PrivKey::from_str(hex).map_err(|err| format!("{err}"))?,
101            )),
102            Encryption::Sm2 => Ok(PrivateKey::Sm2(
103                Sm2Privkey::from_str(hex).map_err(|err| format!("{err}"))?,
104            )),
105        }
106    }
107}
108
109impl fmt::Debug for PrivateKey {
110    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
111        let msg = match *self {
112            PrivateKey::Secp256k1(private_key) => encode(private_key.0),
113            PrivateKey::Sm2(private_key) => encode(private_key.0),
114            PrivateKey::Null => "".to_string(),
115        };
116        write!(f, "{msg}")
117    }
118}
119
120impl fmt::Display for PrivateKey {
121    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
122        let msg = match *self {
123            PrivateKey::Secp256k1(private_key) => encode(private_key.0),
124            PrivateKey::Sm2(private_key) => encode(private_key.0),
125            PrivateKey::Null => "".to_string(),
126        };
127        write!(f, "{msg}")
128    }
129}
130
131/// Pubkey of Secp256k1/Sm2
132pub enum PubKey {
133    /// sha3
134    Secp256k1(Secp256k1PubKey),
135    /// Sm2
136    Sm2(Sm2Pubkey),
137    /// null
138    Null,
139}
140
141impl PubKey {
142    /// Create pubkey key
143    pub fn from_str(hex: &str, encryption: Encryption) -> Result<Self, String> {
144        match encryption {
145            Encryption::Secp256k1 => Ok(PubKey::Secp256k1(
146                Secp256k1PubKey::from_str(hex).map_err(|err| format!("{err}"))?,
147            )),
148            Encryption::Sm2 => Ok(PubKey::Sm2(
149                Sm2Pubkey::from_str(hex).map_err(|err| format!("{err}"))?,
150            )),
151        }
152    }
153
154    /// Convert to vec
155    pub fn to_vec(&self) -> Vec<u8> {
156        match self {
157            PubKey::Secp256k1(pk) | PubKey::Sm2(pk) => pk.0.to_vec(),
158            PubKey::Null => Vec::new(),
159        }
160    }
161}
162
163impl fmt::Display for PubKey {
164    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
165        let msg = match *self {
166            PubKey::Secp256k1(pubkey) => encode(pubkey.0),
167            PubKey::Sm2(pubkey) => encode(pubkey.0),
168            PubKey::Null => "".to_string(),
169        };
170        write!(f, "{msg}")
171    }
172}
173
174/// key pair of Secp256k1/Sm2
175#[derive(Clone)]
176pub enum KeyPair {
177    /// Secp256k1
178    Secp256k1(Secp256k1KeyPair),
179    /// Sm2
180    Sm2(Sm2KeyPair),
181    /// null
182    Null,
183}
184
185impl KeyPair {
186    /// Create new key pair
187    pub fn new(encryption: Encryption) -> Self {
188        match encryption {
189            Encryption::Secp256k1 => KeyPair::Secp256k1(Secp256k1KeyPair::gen_keypair()),
190            Encryption::Sm2 => KeyPair::Sm2(Sm2KeyPair::gen_keypair()),
191        }
192    }
193
194    /// New with private key
195    pub fn from_privkey(private_key: PrivateKey) -> Self {
196        match private_key {
197            PrivateKey::Secp256k1(pk) => {
198                KeyPair::Secp256k1(Secp256k1KeyPair::from_privkey(pk).unwrap())
199            }
200            PrivateKey::Sm2(pk) => KeyPair::Sm2(Sm2KeyPair::from_privkey(pk).unwrap()),
201            PrivateKey::Null => KeyPair::Null,
202        }
203    }
204
205    /// Get private key
206    pub fn privkey(&self) -> PrivateKey {
207        match self {
208            KeyPair::Secp256k1(key_pair) => PrivateKey::Secp256k1(*key_pair.privkey()),
209            KeyPair::Sm2(key_pair) => PrivateKey::Sm2(*key_pair.privkey()),
210            KeyPair::Null => PrivateKey::Null,
211        }
212    }
213
214    /// Get pubkey
215    pub fn pubkey(&self) -> PubKey {
216        match self {
217            KeyPair::Secp256k1(key_pair) => PubKey::Secp256k1(*key_pair.pubkey()),
218            KeyPair::Sm2(key_pair) => PubKey::Sm2(*key_pair.pubkey()),
219            KeyPair::Null => PubKey::Null,
220        }
221    }
222
223    /// Get Address
224    pub fn address(&self) -> Address {
225        match self {
226            KeyPair::Secp256k1(private_key) => private_key.address(),
227            KeyPair::Sm2(private_key) => private_key.address(),
228            KeyPair::Null => Address::default(),
229        }
230    }
231
232    /// New from private key
233    pub fn from_str(private_key: &str, encryption: Encryption) -> Result<Self, String> {
234        match PrivateKey::from_str(private_key, encryption)? {
235            PrivateKey::Secp256k1(private) => Ok(KeyPair::Secp256k1(
236                Secp256k1KeyPair::from_privkey(private).map_err(|err| format!("{err}"))?,
237            )),
238            PrivateKey::Sm2(private) => Ok(KeyPair::Sm2(
239                Sm2KeyPair::from_privkey(private).map_err(|err| format!("{err}"))?,
240            )),
241            PrivateKey::Null => Ok(KeyPair::Null),
242        }
243    }
244
245    /// sign raw data
246    pub fn sign_raw(&self, data: &[u8]) -> Result<Signature, Error> {
247        match self {
248            KeyPair::Secp256k1(key_pair) => key_pair.sign_raw(data),
249            KeyPair::Sm2(key_pair) => key_pair.sign_raw(data),
250            KeyPair::Null => Err(Error::Null),
251        }
252    }
253}
254
255/// Signature
256pub enum Signature {
257    /// Secp256k1
258    Secp256k1(Secp256k1Signature),
259    /// Sm2
260    Sm2(Sm2Signature),
261    /// null
262    Null,
263}
264
265impl Signature {
266    /// New from slice
267    pub fn from(slice: &[u8]) -> Self {
268        if slice.len() == 65 {
269            Signature::Secp256k1(Secp256k1Signature::from(slice))
270        } else if slice.len() == 128 {
271            Signature::Sm2(Sm2Signature::from(slice))
272        } else {
273            Signature::Null
274        }
275    }
276
277    /// Convert to vec
278    pub fn to_vec(&self) -> Vec<u8> {
279        match self {
280            Signature::Sm2(sig) => sig.to_vec(),
281            Signature::Secp256k1(sig) => sig.to_vec(),
282            Signature::Null => Vec::new(),
283        }
284    }
285
286    /// Recover public key
287    pub fn recover(&self, message: &Message) -> Result<PubKey, String> {
288        match self {
289            Signature::Secp256k1(sig) => Ok(sig
290                .recover(message)
291                .map(|pubkey| PubKey::from_str(&pubkey.lower_hex(), Encryption::Secp256k1).unwrap())
292                .map_err(|_| "Can't recover to public key".to_string())?),
293            Signature::Sm2(sig) => Ok(sig
294                .recover(message)
295                .map(|pubkey| PubKey::from_str(&pubkey.lower_hex(), Encryption::Sm2).unwrap())
296                .map_err(|_| "Can't recover to public key".to_string())?),
297            Signature::Null => Err("Mismatched encryption algorithm".to_string()),
298        }
299    }
300
301    /// Verify public key
302    pub fn verify_public(&self, pubkey: PubKey, message: &Message) -> Result<bool, String> {
303        match (self, pubkey) {
304            (Signature::Secp256k1(sig), PubKey::Secp256k1(pubkey)) => sig
305                .verify_public(&pubkey, message)
306                .map_err(|e| e.to_string()),
307            (Signature::Sm2(sig), PubKey::Sm2(pubkey)) => sig
308                .verify_public(&pubkey, message)
309                .map_err(|e| e.to_string()),
310            (_, _) => Ok(false),
311        }
312    }
313}
314
315impl fmt::Display for Signature {
316    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
317        match self {
318            Signature::Secp256k1(sig) => write!(f, "{}", encode(&sig.0[..])),
319            Signature::Sm2(sig) => write!(f, "{}", encode(&sig.0[..])),
320            Signature::Null => write!(f, "null"),
321        }
322    }
323}
324
325#[cfg(test)]
326mod test {
327    use super::{Encryption, KeyPair};
328
329    #[test]
330    fn secp256k1_generate_from_private_key() {
331        let key_pair = KeyPair::from_str(
332            "8ee6aa885d9598f9c4e010b659aeecfc3f113beb646166414756568ab656f0f9",
333            Encryption::Secp256k1,
334        )
335        .unwrap();
336
337        assert_eq!(
338            format!("{}", key_pair.pubkey()).as_str(),
339            "e407bef7ef0a0e21395c46cc2e1ed324119783d0f4f47b676d95b23991f9065db1aa7a9099e2193160243a02168feb70c62eb8442e45c4b3542a4b3c8c8ac5bd"
340        );
341
342        assert_eq!(
343            format!("{:x}", key_pair.address()).as_str(),
344            "eea5c3cbb32fec85bc9b9bffa65fc027e4b1c6d5"
345        );
346    }
347
348    #[test]
349    fn sm2_generate_from_private_key() {
350        let key_pair = KeyPair::from_str(
351            "c3cf5004e9b025427cb07df7592ebbcc64bbf7285bbf50099f072fc0d06a2b20",
352            Encryption::Sm2,
353        )
354        .unwrap();
355        assert_eq!(
356            format!("{}", key_pair.pubkey()).as_str(),
357            "c82d3230f65335a4d07f81d5ab014c1bb606c90b2d098dadbe0bf1d9cf4618654b3a1310627703859ecf493055ea8389fcb78d9c3cf372780927e076278603ed"
358        );
359
360        assert_eq!(
361            format!("{:x}", key_pair.address()).as_str(),
362            "f73076eed94014142153a9556a810826ba9ae857"
363        );
364    }
365}