1use core::ops::Add;
2use std::io::Cursor;
3use std::ops::{Mul, Sub};
4
5use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
6use num_bigint::BigUint;
7use num_traits::Num;
8
9use crate::sm2::error::{Sm2Error, Sm2Result};
10use crate::sm2::p256_ecc::P256C_PARAMS;
11use crate::sm2::{FeOperation};
12use crate::{forward_ref_ref_binop, forward_ref_val_binop, forward_val_val_binop};
13
14pub type Fe = [u32; 8];
15
16pub trait Conversion {
17 fn fe_to_bigunit(&self) -> BigUint;
18
19 fn bigunit_fe(&self) -> Fe;
20}
21
22pub const ECC_P: Fe = [
25 0xffff_fffe,
26 0xffff_ffff,
27 0xffff_ffff,
28 0xffff_ffff,
29 0xffff_ffff,
30 0x0000_0000,
31 0xffff_ffff,
32 0xffff_ffff,
33];
34
35#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
48pub struct FieldElement {
49 pub(crate) inner: Fe,
50}
51
52impl FieldElement {
53 pub fn new(x: Fe) -> FieldElement {
54 FieldElement { inner: x }
55 }
56
57 #[inline]
58 pub fn from_slice(x: &[u32]) -> FieldElement {
59 let mut arr: Fe = [0; 8];
60 arr.copy_from_slice(&x[..]);
61 FieldElement::new(arr)
62 }
63
64 #[inline]
65 pub fn from_number(x: u64) -> FieldElement {
66 let mut arr: Fe = [0; 8];
67 arr[7] = (x & 0xffff_ffff) as u32;
68 arr[6] = (x >> 32) as u32;
69 FieldElement { inner: arr }
70 }
71
72 #[inline]
73 pub fn to_bytes_be(&self) -> Vec<u8> {
74 let mut ret: Vec<u8> = Vec::new();
75 for i in 0..8 {
76 ret.write_u32::<BigEndian>(self.inner[i]).unwrap();
77 }
78 ret
79 }
80
81 #[inline]
82 pub fn from_bytes_be(bytes: &[u8]) -> Sm2Result<FieldElement> {
83 if bytes.len() != 32 {
84 return Err(Sm2Error::InvalidFieldLen);
85 }
86 let mut elem = FieldElement::zero();
87 let mut c = Cursor::new(bytes);
88 for i in 0..8 {
89 elem.inner[i] = c.read_u32::<BigEndian>().unwrap();
90 }
91 Ok(elem)
92 }
93
94 #[inline]
95 pub fn to_biguint(&self) -> BigUint {
96 let v = self.to_bytes_be();
97 BigUint::from_bytes_be(&v[..])
98 }
99
100 #[inline]
101 pub fn from_biguint(bi: &BigUint) -> Sm2Result<FieldElement> {
102 let v = bi.to_bytes_be();
103 let mut num_v = [0; 32];
104 num_v[32 - v.len()..32].copy_from_slice(&v[..]);
105 FieldElement::from_bytes_be(&num_v[..])
106 }
107
108 pub fn sqrt(&self) -> Sm2Result<FieldElement> {
109 let u = BigUint::from_str_radix(
112 "28948022302589062189105086303505223191562588497981047863605298483322421248000",
113 10,
114 )
115 .unwrap();
116 let y = self.modpow(&u);
117 let z = &y.square();
118 if z == self {
119 Ok(y)
120 } else {
121 Err(Sm2Error::FieldSqrtError)
122 }
123 }
124
125 #[inline]
126 pub fn to_str_radix(&self, radix: u32) -> String {
127 self.to_biguint().to_str_radix(radix)
128 }
129
130 pub fn zero() -> FieldElement {
131 FieldElement::new([0; 8])
132 }
133
134 pub fn one() -> FieldElement {
135 FieldElement::from_number(1)
136 }
137
138 pub fn is_even(&self) -> bool {
139 self.inner[7] & 0x01 == 0
140 }
141
142 pub fn is_zero(&self) -> bool {
143 self.inner == [0; 8]
144 }
145
146 pub fn is_one(&self) -> bool {
147 self.inner[7] == 1
148 }
149
150 #[inline]
151 pub fn square(&self) -> FieldElement {
152 self * self
153 }
154
155 #[inline]
156 pub fn double(&self) -> FieldElement {
157 self + self
158 }
159
160 #[inline]
161 pub fn modpow(&self, exponent: &BigUint) -> Self {
162 let u = FieldElement::from_biguint(exponent).unwrap();
163 let mut q0 = FieldElement::from_number(1);
164 let mut q1 = *self;
165 let mut i = 0;
166 while i < 256 {
167 let index = i as usize / 32;
168 let bit = 31 - i as usize % 32;
169
170 let sum = &q0 * &q1;
171 if (u.inner[index] >> bit) & 0x01 == 0 {
172 q1 = sum;
173 q0 = q0.square();
174 } else {
175 q0 = sum;
176 q1 = q1.square();
177 }
178 i += 1;
179 }
180 q0
181 }
182
183 #[inline]
185 pub fn modinv(&self) -> FieldElement {
186 let ecc_p = &P256C_PARAMS.p;
187 let ret = self.inner.inv(&ecc_p.inner);
188 FieldElement::new(ret)
189 }
190}
191
192forward_val_val_binop!(impl Add for FieldElement, add);
193forward_ref_ref_binop!(impl Add for FieldElement, add);
194forward_ref_val_binop!(impl Add for FieldElement, add);
195impl<'a> Add<&'a FieldElement> for FieldElement {
196 type Output = FieldElement;
197
198 fn add(mut self, rhs: &FieldElement) -> Self::Output {
199 self.inner = self.inner.mod_add(&rhs.inner, &ECC_P);
200 self
201 }
202}
203
204forward_val_val_binop!(impl Sub for FieldElement, sub);
205forward_ref_ref_binop!(impl Sub for FieldElement, sub);
206forward_ref_val_binop!(impl Sub for FieldElement, sub);
207impl<'a> Sub<&'a FieldElement> for FieldElement {
208 type Output = FieldElement;
209
210 fn sub(mut self, rhs: &'a FieldElement) -> Self::Output {
211 self.inner = self.inner.mod_sub(&rhs.inner, &ECC_P);
212 self
213 }
214}
215
216forward_val_val_binop!(impl Mul for FieldElement, mul);
217forward_ref_ref_binop!(impl Mul for FieldElement, mul);
218forward_ref_val_binop!(impl Mul for FieldElement, mul);
219impl<'a> Mul<&'a FieldElement> for FieldElement {
220 type Output = FieldElement;
221
222 fn mul(mut self, rhs: &'a FieldElement) -> Self::Output {
223 self.inner = self.inner.mod_mul(&rhs.inner, &ECC_P);
224 self
225 }
226}
227
228impl Default for FieldElement {
229 #[inline]
230 fn default() -> FieldElement {
231 FieldElement {
232 inner: [0; 8],
233 }
234 }
235}
236
237
238#[cfg(test)]
239mod test_fe{
240 use crate::sm2::p256_field::FieldElement;
241
242 #[test]
243 fn test_mod_mul(){
244 let a = FieldElement::new([
245 764497930, 2477372445, 473039778, 1327312203, 3110691882, 1307193102, 2665428562, 967816337,
246 ]);
247 let b = FieldElement::new([
248 2873589426, 3315627933, 3055686524, 325110103, 3264434653, 2512214348, 3018997295,
249 3617546169,
250 ]);
251
252 let ret = a * b;
253 println!("{:?}", ret)
254 }
255
256}