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