gm_sm2/
lib.rs

1#![doc = include_str!("../README.md")]
2
3use pkcs8::ObjectIdentifier;
4use pkcs8::spki::AlgorithmIdentifier;
5
6pub mod error;
7pub mod exchange;
8pub mod key;
9pub mod p256_ecc;
10pub mod util;
11pub mod pkcs;
12pub mod u256;
13pub(crate) mod fields;
14pub(crate) mod sm2p256_table;
15
16/// Fp 的加法,减法,乘法并不是简单的四则运算。其运算结果的值必须在Fp的有限域中,这样保证椭圆曲线变成离散的点
17///
18/// 这里我们规定一个有限域Fp
19///
20/// * 取大质数p,则有限域中有p-1个有限元:0,1,2...p-1
21/// * Fp上的加法为模p加法`a+b≡c(mod p)`
22/// * Fp上的乘法为模p乘法`a×b≡c(mod p)`
23/// * Fp上的减法为模p减法`a-b≡c(mod p)`
24/// * Fp上的除法就是乘除数的乘法逆元`a÷b≡c(mod p)`,即 `a×b^(-1)≡c (mod p)`
25/// * Fp的乘法单位元为1,零元为0
26/// * Fp域上满足交换律,结合律,分配律
27pub trait FeOperation {
28    /// Returns `(self + other) % modulus`.
29    ///
30    /// Panics if the modulus is zero.
31    ///
32    fn mod_add(&self, other: &Self, modulus: &Self) -> Self;
33
34    /// Returns `(self - other) % modulus`.
35    ///
36    /// Panics if the modulus is zero.
37    ///
38    fn mod_sub(&self, other: &Self, modulus: &Self) -> Self;
39
40    /// Returns `(self * other) % modulus`.
41    ///
42    /// Panics if the modulus is zero.
43    ///
44    fn mod_mul(&self, other: &Self, modulus: &Self) -> Self;
45
46    /// Extended Eulidean Algorithm(EEA) to calculate x^(-1) mod p
47    fn inv(&self, modulus: &Self) -> Self;
48
49    /// Self >>= carry
50    fn right_shift(&self, carry: u32) -> Self;
51}
52
53/// oid to pkcs8
54pub const OID_SM2_PKCS8: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.156.10197.1.301");
55pub const ALGORITHM_OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.840.10045.2.1");
56
57const ALGORITHM_IDENTIFIER: AlgorithmIdentifier<ObjectIdentifier> = AlgorithmIdentifier {
58    oid: ALGORITHM_OID,
59    parameters: Some(OID_SM2_PKCS8),
60};
61
62/// oid refer to GM/T 0006
63pub const OID_SM2_CMS_1: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.156.10197.1.301.1");
64pub const OID_SM2_CMS_3: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.156.10197.1.301.3");
65
66/// oid refer to GM/T 0010  pkcs#7
67pub const OID_SM2_CMS_DATA: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.156.10197.6.1.4.2.1");
68pub const OID_SM2_CMS_SIGNED: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.156.10197.6.1.4.2.2");
69pub const OID_SM2_CMS_ENVELOPED: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.156.10197.6.1.4.2.3");
70pub const OID_SM2_CMS_SIGNED_AND_ENVELOPED: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.156.10197.6.1.4.2.4");
71pub const OID_SM2_CMS_ENCRYPTED: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.156.10197.6.1.4.2.5");
72pub const OID_SM2_CMS_KEY_AGREEMENT_INFO: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.156.10197.6.1.4.2.6");
73
74#[cfg(test)]
75mod test_sm2 {
76    use crate::exchange;
77    use crate::key::{gen_keypair, Sm2Model, Sm2PrivateKey, Sm2PublicKey};
78
79    #[test]
80    fn test_encrypt_decrypt_with_gen_key() {
81        let (pk, sk) = gen_keypair().unwrap();
82        let msg = vec![00, 0, 100, 0, 134];
83        // let msg = "你好 hello world".as_bytes();
84        let encrypt = pk.encrypt(&msg, false, Sm2Model::C1C2C3).unwrap();
85        let plain = sk.decrypt(&encrypt, false, Sm2Model::C1C2C3).unwrap();
86        println!("public key {}", pk.to_hex_string(false));
87        println!("private key {}", sk.to_hex_string());
88        assert_eq!(msg, plain)
89    }
90
91    #[test]
92    fn test_encrypt_decrypt_with_special_key() {
93        let public_key = "048626c62a8582c639cb3c87b59118713a519988c5f6497f91dd672abbdaaed0420ea7bc2cd03a7c938adc42b450549d312bec823b74cf22cf57c63cebd011c595";
94        let private_key = "eb20009ffbffc90aeeb288ca7d782c722332d1d16a206cafec7dd6c64e6fc525";
95        let pk = Sm2PublicKey::from_hex_string(public_key).unwrap();
96        let sk = Sm2PrivateKey::from_hex_string(private_key).unwrap();
97
98        let msg = "你好 world,asjdkajhdjadahkubbhj12893718927391873891,@@!! world,1231 wo12321321313asdadadahello world,hello world".as_bytes();
99        let encrypt = pk.encrypt(msg, false, Sm2Model::C1C3C2).unwrap();
100        let plain = sk.decrypt(&encrypt, false, Sm2Model::C1C3C2).unwrap();
101        assert_eq!(msg, plain);
102    }
103
104    #[test]
105    fn test_encrypt_decrypt_with_java_bouncycastle_gen_key() {
106        let public_key = "046a6ff781355cc1a9e538213f3a2074ceb32eae9e1caa090e74bbac9024cd58969619ec8dd797635773a9e8c3401135687a49381bb088d4f10c8feed899bf69c5";
107        let private_key = "ff88f12d6f28a852cc59ace674efb842163f1c5294890be9843fe5c20e26a011";
108        let pk = Sm2PublicKey::from_hex_string(public_key).unwrap();
109        let sk = Sm2PrivateKey::from_hex_string(private_key).unwrap();
110
111        let msg = "你好 world,asjdkajhdjadahkubbhj12893718927391873891,@@!! world,1231 wo12321321313asdadadahello world,hello world".as_bytes();
112        let encrypt = pk.encrypt(msg, false, Sm2Model::C1C3C2).unwrap();
113        let plain = sk.decrypt(&encrypt, false, Sm2Model::C1C3C2).unwrap();
114        assert_eq!(msg, plain);
115    }
116
117    #[test]
118    fn test_sign_verify() {
119        let msg = b"hello";
120        let (pk, sk) = gen_keypair().unwrap();
121        let signature = sk.sign(None, msg).unwrap();
122        pk.verify(None, msg, &signature).unwrap();
123    }
124
125    #[test]
126    fn test_sign_verify_with_special_key() {
127        let msg = b"hello world";
128        let public_key = "048626c62a8582c639cb3c87b59118713a519988c5f6497f91dd672abbdaaed0420ea7bc2cd03a7c938adc42b450549d312bec823b74cf22cf57c63cebd011c595";
129        let private_key = "eb20009ffbffc90aeeb288ca7d782c722332d1d16a206cafec7dd6c64e6fc525";
130        let pk = Sm2PublicKey::from_hex_string(public_key).unwrap();
131        let sk = Sm2PrivateKey::from_hex_string(private_key).unwrap();
132        let signature = sk.sign(None, msg).unwrap();
133        println!("r = {:?}", &signature[..32]); // [219, 173, 217, 137, 244, 217, 236, 248, 193, 32, 248, 249, 198, 224, 105, 110, 13, 27, 182, 83, 253, 160, 229, 228, 224, 131, 255, 153, 7, 8, 62, 125]
134        println!("s = {:?}", &signature[32..]); // [59, 88, 113, 171, 98, 2, 161, 21, 92, 251, 192, 204, 182, 109, 230, 12, 135, 138, 251, 163, 101, 45, 223, 117, 176, 11, 151, 210, 228, 140, 33, 16]
135        pk.verify(None, msg, &signature).unwrap();
136    }
137
138    #[test]
139    fn test_sign_verify_with_java_bouncycastle_gen_key() {
140        let msg = "hello,你好".as_bytes();
141        let public_key = "046a6ff781355cc1a9e538213f3a2074ceb32eae9e1caa090e74bbac9024cd58969619ec8dd797635773a9e8c3401135687a49381bb088d4f10c8feed899bf69c5";
142        let private_key = "ff88f12d6f28a852cc59ace674efb842163f1c5294890be9843fe5c20e26a011";
143        let pk = Sm2PublicKey::from_hex_string(public_key).unwrap();
144        let sk = Sm2PrivateKey::from_hex_string(private_key).unwrap();
145        let signature = sk.sign(None, msg).unwrap();
146        pk.verify(None, msg, &signature).unwrap();
147    }
148
149    #[test]
150    fn test_key_exchange() {
151        let id_a = "alice123@qq.com";
152        let id_b = "bob456@qq.com";
153
154        let (mut alice, mut bob) = exchange::build_ex_pair(8, id_a, id_b).unwrap();
155
156        let ra_point = alice.exchange_1().unwrap();
157        let (rb_point, sb) = bob.exchange_2(&ra_point).unwrap();
158        let sa = alice.exchange_3(&rb_point, sb).unwrap();
159        let succ = bob.exchange_4(sa, &ra_point).unwrap();
160        assert_eq!(succ, true);
161        assert_eq!(alice.k, bob.k);
162    }
163
164
165    #[test]
166    fn test_encrypt_decrypt_asn1_with_special_key() {
167        let public_key = "048626c62a8582c639cb3c87b59118713a519988c5f6497f91dd672abbdaaed0420ea7bc2cd03a7c938adc42b450549d312bec823b74cf22cf57c63cebd011c595";
168        let private_key = "eb20009ffbffc90aeeb288ca7d782c722332d1d16a206cafec7dd6c64e6fc525";
169        let pk = Sm2PublicKey::from_hex_string(public_key).unwrap();
170        let sk = Sm2PrivateKey::from_hex_string(private_key).unwrap();
171
172        let msg = "你好 world,asjdkajhdjadahkubbhj12893718927391873891,@@!! world,1231 wo12321321313asdadadahello world,hello world".as_bytes();
173        let encrypt = pk.encrypt_asn1(msg, false, Sm2Model::C1C3C2).unwrap();
174        let plain = sk.decrypt_asn1(&encrypt, false, Sm2Model::C1C3C2).unwrap();
175        assert_eq!(msg, plain);
176    }
177}