gmcrypto_core/sm2/
curve.rs1use crypto_bigint::{U256, const_monty_params};
8
9const_monty_params!(
11 PMod,
12 U256,
13 "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF"
14);
15
16const_monty_params!(
18 NMod,
19 U256,
20 "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123"
21);
22
23pub type Fp = crypto_bigint::modular::ConstMontyForm<PMod, { U256::LIMBS }>;
25
26pub type Fn = crypto_bigint::modular::ConstMontyForm<NMod, { U256::LIMBS }>;
29
30pub(crate) const B_HEX: &str = "28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93";
32
33#[allow(dead_code)]
35pub(crate) const GX_HEX: &str = "32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7";
36
37#[allow(dead_code)]
39pub(crate) const GY_HEX: &str = "BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0";
40
41#[must_use]
43pub const fn b() -> Fp {
44 Fp::new(&U256::from_be_hex(B_HEX))
45}
46
47#[must_use]
49pub fn b3() -> Fp {
50 let b = b();
51 b + b + b
52}
53
54#[cfg(test)]
55mod tests {
56 use super::*;
57 #[test]
58 fn moduli_are_correct_size() {
59 assert_eq!(Fp::MODULUS.as_ref().bits(), 256);
60 assert_eq!(Fn::MODULUS.as_ref().bits(), 256);
61 }
62
63 #[test]
64 fn b_is_not_zero() {
65 let b = b();
66 assert_ne!(b.retrieve(), U256::ZERO);
67 }
68
69 #[test]
70 fn b3_equals_3b() {
71 let b = b();
72 let b3 = b3();
73 assert_eq!(b3.retrieve(), (b + b + b).retrieve());
74 }
75
76 #[test]
78 fn fp_invert_round_trip() {
79 let a = Fp::new(&U256::from_u64(7));
80 let a_inv = a.invert().expect("7 is invertible mod p");
81 let one = Fp::new(&U256::ONE);
82 assert_eq!((a * a_inv).retrieve(), one.retrieve());
83 }
84
85 #[test]
87 fn fn_invert_round_trip() {
88 let a = Fn::new(&U256::from_u64(5));
89 let a_inv = a.invert().expect("5 is invertible mod n");
90 let one = Fn::new(&U256::ONE);
91 assert_eq!((a * a_inv).retrieve(), one.retrieve());
92 }
93
94 #[test]
96 fn invert_zero_is_none() {
97 let zero = Fp::new(&U256::ZERO);
98 assert!(bool::from(zero.invert().is_none()));
99 }
100}