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
14pub type Secp256k1PrivKey = H256;
16pub type Secp256k1PubKey = H512;
18pub type Message = H256;
20pub type Sm2Privkey = H256;
22pub type Sm2Pubkey = H512;
24
25pub 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
34pub 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#[derive(Clone, Copy)]
45pub enum Encryption {
46 Secp256k1,
48 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#[derive(Clone, Copy)]
86pub enum PrivateKey {
87 Secp256k1(Secp256k1PrivKey),
89 Sm2(Sm2Privkey),
91 Null,
93}
94
95impl PrivateKey {
96 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
131pub enum PubKey {
133 Secp256k1(Secp256k1PubKey),
135 Sm2(Sm2Pubkey),
137 Null,
139}
140
141impl PubKey {
142 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 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#[derive(Clone)]
176pub enum KeyPair {
177 Secp256k1(Secp256k1KeyPair),
179 Sm2(Sm2KeyPair),
181 Null,
183}
184
185impl KeyPair {
186 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 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 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 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 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 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 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
255pub enum Signature {
257 Secp256k1(Secp256k1Signature),
259 Sm2(Sm2Signature),
261 Null,
263}
264
265impl Signature {
266 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 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 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 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}