gm_sm9/
lib.rs

1#![doc = include_str!("../README.md")]
2use crate::fields::fp2::Fp2;
3use crate::points::{Point, TwistPoint};
4use crate::u256::U256;
5
6pub mod error;
7pub mod fields;
8pub mod key;
9pub mod points;
10mod sm9_p256_table;
11pub mod u256;
12
13/// Example:
14///
15/// ### encrypt & decrypt
16/// ```rust
17/// use gm_sm9::key::Sm9EncMasterKey;
18/// use gm_sm9::points::{Point, TwistPoint};
19/// use gm_sm9::u256::u256_from_be_bytes;
20///
21/// fn main() {
22///     let data: [u8; 21] = [
23///         0x43, 0x68, 0x69, 0x6E, 0x65, 0x73, 0x65, 0x20, 0x49, 0x42, 0x53, 0x20, 0x73, 0x74,
24///         0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x64,
25///     ];
26///     println!("Message =    {:?}", &data);
27///     let id = [0x42, 0x6F, 0x62u8];
28///     let ke = u256_from_be_bytes(
29///         &hex::decode("0001EDEE3778F441F8DEA3D9FA0ACC4E07EE36C93F9A08618AF4AD85CEDE1C22")
30///             .unwrap(),
31///     );
32///
33///     let msk = Sm9EncMasterKey {
34///         ke,
35///         ppube: Point::g_mul(&ke),
36///     };
37///
38///     let r = msk.extract_key(&id);
39///     let r_de = TwistPoint::from_hex(
40///         [
41///             "115BAE85F5D8BC6C3DBD9E5342979ACCCF3C2F4F28420B1CB4F8C0B59A19B158",
42///             "94736ACD2C8C8796CC4785E938301A139A059D3537B6414140B2D31EECF41683",
43///         ],
44///         [
45///             "27538A62E7F7BFB51DCE08704796D94C9D56734F119EA44732B50E31CDEB75C1",
46///             "7AA5E47570DA7600CD760A0CF7BEAF71C447F3844753FE74FA7BA92CA7D3B55F",
47///         ],
48///     );
49///     assert_eq!(true, r.unwrap().de.point_equals(&r_de));
50///
51///     let ret = msk.encrypt(&id, &data);
52///     println!("Ciphertext = {:?}", ret);
53///
54///     let m = r.unwrap().decrypt(&id, &ret).expect("Decryption failed");
55///     println!("Plaintext =  {:?}", &m);
56///     assert_eq!(true, data == m.as_slice());
57/// }
58///
59/// ```
60///
61///
62/// ### sign & verify
63/// ```rust
64///     use gm_sm9::key::{Sm9SignMasterKey, Sm9SignKey};
65///     use gm_sm9::points::{Point, TwistPoint};
66///     use gm_sm9::u256::u256_from_be_bytes;
67///     fn main() {
68///         let data: [u8; 20] = [
69///             0x43, 0x68, 0x69, 0x6E, 0x65, 0x73, 0x65, 0x20, 0x49, 0x42, 0x53, 0x20, 0x73, 0x74,
70///             0x61, 0x6E, 0x64, 0x61, 0x72, 0x64,
71///         ];
72///
73///         let ida = [0x41, 0x6C, 0x69, 0x63, 0x65u8];
74///
75///         let ks = u256_from_be_bytes(
76///             &hex::decode("000130E78459D78545CB54C587E02CF480CE0B66340F319F348A1D5B1F2DC5F4")
77///                 .unwrap(),
78///         );
79///         let msk = Sm9SignMasterKey {
80///             ks,
81///             ppubs: TwistPoint::g_mul(&ks),
82///         };
83///
84///         let r_ds = Point::from_hex([
85///             "A5702F05CF1315305E2D6EB64B0DEB923DB1A0BCF0CAFF90523AC8754AA69820",
86///             "78559A844411F9825C109F5EE3F52D720DD01785392A727BB1556952B2B013D3",
87///         ]);
88///         let r = msk.extract_key(&ida);
89///         let ps = r.unwrap();
90///         assert_eq!(true, ps.ds.point_equals(&r_ds));
91///
92///         println!("Message =    {:?}", &data);
93///         let (h, s) = ps.sign(&data).unwrap();
94///         println!("Sign H =     {:?}", &h);
95///         println!("Sign S =     {:?}", &s);
96///
97///         let r = msk.verify_sign(&ida, &data, &h, &s);
98///         println!("VersionSign ={:?}", &r);
99///     }
100///
101/// ```
102///
103///
104/// ### key exchange
105/// ```rust
106///     use gm_sm9::key::{Sm9EncMasterKey,Sm9EncKey};
107///     use gm_sm9::points::{Point, TwistPoint};
108///     use gm_sm9::key::{exch_step_1a, exch_step_1b, exch_step_2a};
109///     fn main() {
110///         let msk: Sm9EncMasterKey = Sm9EncMasterKey::master_key_generate();
111///         let klen = 20usize;
112///         let ida = [0x41, 0x6C, 0x69, 0x63, 0x65u8];
113///         let idb = [0x42, 0x6F, 0x62u8];
114///         let key_a: Sm9EncKey = msk.extract_exch_key(&ida).unwrap();
115///         let key_b: Sm9EncKey = msk.extract_exch_key(&idb).unwrap();
116///
117///         let (ra, ra_) = exch_step_1a(&msk, &idb);
118///         let (rb, skb) = exch_step_1b(&msk, &ida, &idb, &key_b, &ra, klen).unwrap();
119///         let ska = exch_step_2a(&msk, &ida, &idb, &key_a, ra_, &ra, &rb, klen).unwrap();
120///         println!("SKB = {:?}", &skb);
121///         println!("SKA = {:?}", &ska);
122///         for i in 0..klen {
123///             if ska[i] != skb[i] {
124///                 println!("Exchange key different at byte index: {}", i)
125///             }
126///         }
127///     }
128///
129/// ```
130///
131///
132///
133
134
135
136
137/// 本文使用256位的BN曲线。
138///
139/// 椭圆曲线方程:y2 = x3 + b
140///
141/// 参数 t: 60000000 0058F98A
142///
143/// 基域特征 q(t) = 36t^4 + 36t^3 + 24t^2 + 6t + 1
144///
145/// p =  B6400000 02A3A6F1 D603AB4F F58EC745 21F2934B 1A7AEEDB E56F9B27 E351457D
146pub(crate) const SM9_P: U256 = [
147    0xe56f9b27e351457d,
148    0x21f2934b1a7aeedb,
149    0xd603ab4ff58ec745,
150    0xb640000002a3a6f1,
151];
152
153pub(crate) const SM9_P_MINUS_ONE: U256 = [
154    0xe56f9b27e351457c,
155    0x21f2934b1a7aeedb,
156    0xd603ab4ff58ec745,
157    0xb640000002a3a6f1,
158];
159
160/// e = p - 2 = b640000002a3a6f1d603ab4ff58ec74521f2934b1a7aeedbe56f9b27e351457b
161///
162/// p - 2, used in a^(p-2) = a^-1
163pub(crate) const SM9_P_MINUS_TWO: U256 = [
164    0xe56f9b27e351457b,
165    0x21f2934b1a7aeedb,
166    0xd603ab4ff58ec745,
167    0xb640000002a3a6f1,
168];
169
170/// p = b640000002a3a6f1d603ab4ff58ec74521f2934b1a7aeedbe56f9b27e351457d
171///
172/// p' = -p^(-1) mod 2^256 = afd2bac5558a13b3966a4b291522b137181ae39613c8dbaf892bc42c2f2ee42b
173///
174/// sage: -(IntegerModRing(2^256)(p))^-1
175pub(crate) const SM9_P_PRIME: U256 = [
176    0x892bc42c2f2ee42b,
177    0x181ae39613c8dbaf,
178    0x966a4b291522b137,
179    0xafd2bac5558a13b3,
180];
181
182// mont params (mod p)
183// mu = p^-1 mod 2^64 = 0x76d43bd3d0d11bd5
184// 2^512 mod p = 0x2ea795a656f62fbde479b522d6706e7b88f8105fae1a5d3f27dea312b417e2d2
185// mont(1) mod p = 2^256 mod p = 0x49bffffffd5c590e29fc54b00a7138bade0d6cb4e58511241a9064d81caeba83
186pub(crate) const SM9_MODP_MU: u64 = 0x76d43bd3d0d11bd5_u64;
187pub(crate) const SM9_MODP_2E512: U256 = [
188    0x27dea312b417e2d2,
189    0x88f8105fae1a5d3f,
190    0xe479b522d6706e7b,
191    0x2ea795a656f62fbd,
192];
193pub(crate) const SM9_MODP_MONT_ONE: U256 = [
194    0x1a9064d81caeba83,
195    0xde0d6cb4e5851124,
196    0x29fc54b00a7138ba,
197    0x49bffffffd5c590e,
198];
199pub(crate) const SM9_MODP_MONT_FIVE: U256 = [
200    0xb9f2c1e8c8c71995,
201    0x125df8f246a377fc,
202    0x25e650d049188d1c,
203    0x43fffffed866f63,
204];
205
206pub(crate) const SM9_MONT_ALPHA1: U256 = [
207    0x1a98dfbd4575299f,
208    0x9ec8547b245c54fd,
209    0xf51f5eac13df846c,
210    0x9ef74015d5a16393,
211];
212
213pub(crate) const SM9_MONT_ALPHA2: U256 = [
214    0xb626197dce4736ca,
215    0x08296b3557ed0186,
216    0x9c705db2fd91512a,
217    0x1c753e748601c992,
218];
219
220pub(crate) const SM9_MONT_ALPHA3: U256 = [
221    0x39b4ef0f3ee72529,
222    0xdb043bf508582782,
223    0xb8554ab054ac91e3,
224    0x9848eec25498cab5,
225];
226
227pub(crate) const SM9_MONT_ALPHA4: U256 = [
228    0x81054fcd94e9c1c4,
229    0x4c0e91cb8ce2df3e,
230    0x4877b452e8aedfb4,
231    0x88f53e748b491776,
232];
233
234pub(crate) const SM9_MONT_ALPHA5: U256 = [
235    0x048baa79dcc34107,
236    0x5e2e7ac4fe76c161,
237    0x99399754365bd4bc,
238    0xaf91aeac819b0e13,
239];
240
241pub(crate) const SM9_MONT_BETA: Fp2 = Fp2 {
242    c0: [
243        0x39b4ef0f3ee72529,
244        0xdb043bf508582782,
245        0xb8554ab054ac91e3,
246        0x9848eec25498cab5,
247    ],
248    c1: [0, 0, 0, 0],
249};
250
251pub(crate) const SM9_FP2_ZERO: [U256; 2] = [[0, 0, 0, 0], [0, 0, 0, 0]];
252pub(crate) const SM9_FP2_ONE: [U256; 2] = [[1, 0, 0, 0], [0, 0, 0, 0]];
253pub(crate) const SM9_FP2_U: [U256; 2] = [[0, 0, 0, 0], [1, 0, 0, 0]];
254pub(crate) const SM9_FP2_5U: [U256; 2] = [[0, 0, 0, 0], [5, 0, 0, 0]];
255pub(crate) const SM9_FP2_MONT_5U: [U256; 2] = [
256    [0, 0, 0, 0],
257    [
258        0xb9f2c1e8c8c71995,
259        0x125df8f246a377fc,
260        0x25e650d049188d1c,
261        0x43fffffed866f63,
262    ],
263];
264
265pub(crate) const SM9_FP4_ZERO: [[U256; 2]; 2] =
266    [[[0, 0, 0, 0], [0, 0, 0, 0]], [[0, 0, 0, 0], [0, 0, 0, 0]]];
267pub(crate) const SM9_FP4_MONT_ONE: [[U256; 2]; 2] = [
268    [
269        [
270            0x1a9064d81caeba83,
271            0xde0d6cb4e5851124,
272            0x29fc54b00a7138ba,
273            0x49bffffffd5c590e,
274        ],
275        [0, 0, 0, 0],
276    ],
277    [[0, 0, 0, 0], [0, 0, 0, 0]],
278];
279
280/// 群的阶 N(t) = 36t^4 + 36t^3 + 18t^2 + 6t + 1
281///
282/// n =  B6400000 02A3A6F1 D603AB4F F58EC744 49F2934B 18EA8BEE E56EE19C D69ECF25
283pub(crate) const SM9_N: U256 = [
284    0xe56ee19cd69ecf25,
285    0x49f2934b18ea8bee,
286    0xd603ab4ff58ec744,
287    0xb640000002a3a6f1,
288];
289
290/// 2^256 - n
291pub(crate) const SM9_N_NEG: U256 = [
292    0x1a911e63296130db,
293    0xb60d6cb4e7157411,
294    0x29fc54b00a7138bb,
295    0x49bffffffd5c590e,
296];
297
298/// N - 1
299pub(crate) const SM9_N_MINUS_ONE: U256 = [
300    0xe56ee19cd69ecf24,
301    0x49f2934b18ea8bee,
302    0xd603ab4ff58ec744,
303    0xb640000002a3a6f1,
304];
305
306/// N - 2
307pub(crate) const SM9_N_MINUS_TWO: U256 = [
308    0xe56ee19cd69ecf23,
309    0x49f2934b18ea8bee,
310    0xd603ab4ff58ec744,
311    0xb640000002a3a6f1,
312];
313
314pub(crate) const SM9_N_BARRETT_MU: [u64; 5] = [
315    0x74df4fd4dfc97c2f,
316    0x9c95d85ec9c073b0,
317    0x55f73aebdcd1312c,
318    0x67980e0beb5759a6,
319    0x1,
320];
321
322pub(crate) const SM9_U256_N_MINUS_ONE_BARRETT_MU: [u64; 4] = [
323    0x74df4fd4dfc97c31,
324    0x9c95d85ec9c073b0,
325    0x55f73aebdcd1312c,
326    0x67980e0beb5759a6,
327];
328
329pub(crate) const SM9_HID_ENC: u8 = 0x03;
330pub(crate) const SM9_HID_EXCH: u8 = 0x02;
331pub(crate) const SM9_HID_SIGN: u8 = 0x01;
332
333pub(crate) const SM9_HASH1_PREFIX: u8 = 0x01;
334pub(crate) const SM9_HASH2_PREFIX: u8 = 0x02;
335
336pub(crate) const SM9_POINT_MONT_P1: Point = Point {
337    x: [
338        0x22e935e29860501b,
339        0xa946fd5e0073282c,
340        0xefd0cec817a649be,
341        0x5129787c869140b5,
342    ],
343    y: [
344        0xee779649eb87f7c7,
345        0x15563cbdec30a576,
346        0x326353912824efbf,
347        0x7215717763c39828,
348    ],
349    z: [
350        0x1a9064d81caeba83,
351        0xde0d6cb4e5851124,
352        0x29fc54b00a7138ba,
353        0x49bffffffd5c590e,
354    ],
355};
356
357pub(crate) const SM9_TWIST_POINT_MONT_P2: TwistPoint = TwistPoint {
358    x: Fp2 {
359        c0: [
360            0x260226a68ce2da8f,
361            0x7ee5645edbf6c06b,
362            0xf8f57c82b1495444,
363            0x61fcf018bc47c4d1,
364        ],
365        c1: [
366            0xdb6db4822750a8a6,
367            0x84c6135a5121f134,
368            0x1874032f88791d41,
369            0x905112f2b85f3a37,
370        ],
371    },
372    y: Fp2 {
373        c0: [
374            0xc03f138f9171c24a,
375            0x92fbab45a15a3ca7,
376            0x2445561e2ff77cdb,
377            0x108495e0c0f62ece,
378        ],
379        c1: [
380            0xf7b82dac4c89bfbb,
381            0x3706f3f6a49dc12f,
382            0x1e29de93d3eef769,
383            0x81e448c3c76a5d53,
384        ],
385    },
386    z: Fp2 {
387        c0: [
388            0x1a9064d81caeba83,
389            0xde0d6cb4e5851124,
390            0x29fc54b00a7138ba,
391            0x49bffffffd5c590e,
392        ],
393        c1: [0, 0, 0, 0],
394    },
395};
396