hop_core/modules/
field.rs

1// Copyright (c) 2025 Lex Luger. All Rights Reserved.
2// This software (HOP-CORE) is proprietary and confidential.
3// Unauthorized copying, distribution, or use is strictly prohibited
4// without explicit written permission from the author.
5// Commercial licenses are available. Contact: lexluger.dev@proton.me
6use core::fmt;
7use core::ops::{Add, Sub, Mul};
8
9/// Simple finite field arithmetic modulo a prime p (u64).
10/// Uses u128 intermediates to avoid overflow on multiplication.
11#[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    /// Set the prime modulus here. For prototype/testing you can change it.
24    pub const MOD: u64 = 65537;
25
26    /// Create element with reduction
27    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    /// fast exponentiation
41    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    /// Multiplicative inverse using Extended Euclidean algorithm (since modulus is prime)
55    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    /// extended gcd for signed integers
68    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