1use base64::Engine;
2use base64::engine::general_purpose::STANDARD;
3use sha2::Digest;
4use smcrypto::{sm2, sm3, sm4};
5use crate::error::Sm2Error;
6
7pub fn generate_keypair() -> (String, String) {
11 let (sk, pk) = sm2::gen_keypair();
12 (sk, format!("04{}", pk))
13}
14
15pub fn encrypt(data: &str, secret: &str) -> Result<String, Sm2Error> {
20 let key = hex::decode(md5_key(secret))?;
21 let sm4_ecb = sm4::CryptSM4ECB::new(&key);
22 let encrypted = sm4_ecb.encrypt_ecb(data.as_bytes());
23 Ok(STANDARD.encode(hex::encode(encrypted)))
24}
25
26pub fn decrypt(encrypted: &str, secret: &str) -> Result<String, Sm2Error> {
31 let key = hex::decode(md5_key(secret))?;
32 let encrypt_data = hex::decode(STANDARD.decode(encrypted)?)?;
33 let sm4_ecb = sm4::CryptSM4ECB::new(&key);
34 let decrypted = sm4_ecb.decrypt_ecb(&encrypt_data);
35 Ok(String::from_utf8(decrypted)?)
36}
37
38pub fn md5_key(secret: &str) -> String {
44 let mut sha2 = sha2::Sha256::new();
45 sha2.update(secret);
46 let hash = hex::encode(sha2.finalize());
47 let hash = sm3::sm3_hash(hash.as_bytes());
48 format!("{:x}", md5::compute(hash))
49}
50
51#[cfg(test)]
52mod tests {
53 use super::*;
54
55 #[test]
56 fn test_generate_keypair() {
57 let (sk, pk) = generate_keypair();
58 println!("sk: {}, pk: {}", sk, pk);
59 }
60
61 #[test]
62 fn test_encrypt() {
63 let msg = r#"hello world"#;
64 let secret = "ZTPkMS00ZNTP5NzPwNjAu";
65
66 let encrypt_data = encrypt(msg, secret).unwrap();
68 assert_eq!(encrypt_data, "M2YyZWFlOTU4MzBkZTUxMGQyOTNjNmUzYzA1ODg2NjM=");
69
70 let decrypt_data = decrypt(&encrypt_data, secret).unwrap();
72 assert_eq!(decrypt_data, msg);
73 }
74}