hop_core/modules/
field.rs1use core::fmt;
7use core::ops::{Add, Sub, Mul};
8
9#[derive(Clone, Copy, PartialEq, Eq)]
12pub struct Field {
13 pub v: u64,
14}
15
16impl fmt::Debug for Field {
17 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
18 write!(f, "Field({})", self.v)
19 }
20}
21
22impl Field {
23 pub const MOD: u64 = 65537;
25
26 pub fn new(x: u128) -> Self {
28 let m = Self::MOD as u128;
29 Field { v: (x % m) as u64 }
30 }
31
32 pub fn zero() -> Self {
33 Field { v: 0 }
34 }
35
36 pub fn one() -> Self {
37 Field { v: 1 % Self::MOD }
38 }
39
40 pub fn pow(self, mut exp: u128) -> Self {
42 let mut base = self;
43 let mut acc = Field::one();
44 while exp > 0 {
45 if exp & 1 != 0 {
46 acc = acc * base;
47 }
48 base = base * base;
49 exp >>= 1;
50 }
51 acc
52 }
53
54 pub fn inv(self) -> Option<Self> {
56 let (g, x, _y) = Self::egcd(self.v as i128, Self::MOD as i128);
57 if g != 1 && g != -1 {
58 return None;
59 }
60 let mut inv = x % (Self::MOD as i128);
61 if inv < 0 {
62 inv += Self::MOD as i128;
63 }
64 Some(Field { v: inv as u64 })
65 }
66
67 fn egcd(a: i128, b: i128) -> (i128, i128, i128) {
69 if b == 0 {
70 return (a.abs(), a.signum(), 0);
71 }
72 let (g, x1, y1) = Self::egcd(b, a % b);
73 (g, y1, x1 - (a / b) * y1)
74 }
75}
76
77impl Add for Field {
78 type Output = Self;
79 fn add(self, other: Self) -> Self {
80 let s = (self.v as u128 + other.v as u128) % (Self::MOD as u128);
81 Field::new(s)
82 }
83}
84
85impl Sub for Field {
86 type Output = Self;
87 fn sub(self, other: Self) -> Self {
88 let m = Self::MOD as u128;
89 let a = self.v as u128;
90 let b = other.v as u128;
91 Field::new((a + m - (b % m)) % m)
92 }
93}
94
95impl Mul for Field {
96 type Output = Self;
97 fn mul(self, other: Self) -> Self {
98 Field::new((self.v as u128) * (other.v as u128))
99 }
100}
101
102