Skip to main content

miden_field/
native.rs

1//! Off-chain implementation of [`crate::Felt`].
2
3use miden_core::{Felt as CoreFelt, FieldElement};
4
5use crate::FeltImpl;
6
7#[repr(transparent)]
8#[derive(Copy, Clone, Debug)]
9/// A `Felt` represented as a felt (`miden_core::Felt`).
10pub struct Felt(pub miden_core::Felt);
11
12impl FeltImpl for Felt {
13    #[inline(always)]
14    fn from_u64_unchecked(value: u64) -> Self {
15        assert!(value <= Felt::M, "value {value} is larger than field modulus {}", Felt::M);
16        Self(CoreFelt::new(value))
17    }
18
19    #[inline(always)]
20    fn from_u32(value: u32) -> Self {
21        Self::from_u64_unchecked(value as u64)
22    }
23
24    #[inline(always)]
25    fn as_u64(self) -> u64 {
26        self.0.as_int()
27    }
28
29    #[inline(always)]
30    fn is_odd(self) -> bool {
31        self.as_u64() & 1 == 1
32    }
33
34    #[inline(always)]
35    fn inv(self) -> Self {
36        Self(self.0.inv())
37    }
38
39    #[inline(always)]
40    fn pow2(self) -> Self {
41        let n = self.as_u64();
42        assert!(n <= 63, "pow2: exponent out of range");
43        Self(CoreFelt::new(1u64 << (n as u32)))
44    }
45
46    #[inline(always)]
47    fn exp(self, other: Self) -> Self {
48        Self(self.0.exp(other.as_u64()))
49    }
50}
51
52impl From<CoreFelt> for Felt {
53    fn from(value: CoreFelt) -> Self {
54        Self(value)
55    }
56}
57
58impl From<Felt> for CoreFelt {
59    fn from(value: Felt) -> Self {
60        value.0
61    }
62}
63
64impl From<Felt> for u64 {
65    fn from(felt: Felt) -> u64 {
66        felt.as_u64()
67    }
68}
69
70impl From<u32> for Felt {
71    fn from(value: u32) -> Self {
72        Self::from_u32(value)
73    }
74}
75
76impl From<u16> for Felt {
77    fn from(value: u16) -> Self {
78        Self::from_u64_unchecked(value as u64)
79    }
80}
81
82impl From<u8> for Felt {
83    fn from(value: u8) -> Self {
84        Self::from_u64_unchecked(value as u64)
85    }
86}
87
88#[cfg(target_pointer_width = "32")]
89impl From<usize> for Felt {
90    fn from(value: usize) -> Self {
91        Self::from_u64_unchecked(value as u64)
92    }
93}
94
95impl core::ops::Add for Felt {
96    type Output = Self;
97
98    #[inline(always)]
99    fn add(self, other: Self) -> Self {
100        Self(self.0 + other.0)
101    }
102}
103
104impl core::ops::AddAssign for Felt {
105    #[inline(always)]
106    fn add_assign(&mut self, other: Self) {
107        *self = *self + other;
108    }
109}
110
111impl core::ops::Sub for Felt {
112    type Output = Self;
113
114    #[inline(always)]
115    fn sub(self, other: Self) -> Self {
116        Self(self.0 - other.0)
117    }
118}
119
120impl core::ops::SubAssign for Felt {
121    #[inline(always)]
122    fn sub_assign(&mut self, other: Self) {
123        *self = *self - other;
124    }
125}
126
127impl core::ops::Mul for Felt {
128    type Output = Self;
129
130    #[inline(always)]
131    fn mul(self, other: Self) -> Self {
132        Self(self.0 * other.0)
133    }
134}
135
136impl core::ops::MulAssign for Felt {
137    #[inline(always)]
138    fn mul_assign(&mut self, other: Self) {
139        *self = *self * other;
140    }
141}
142
143impl core::ops::Div for Felt {
144    type Output = Self;
145
146    #[inline(always)]
147    fn div(self, other: Self) -> Self {
148        Self(self.0 / other.0)
149    }
150}
151
152impl core::ops::DivAssign for Felt {
153    #[inline(always)]
154    fn div_assign(&mut self, other: Self) {
155        *self = *self / other;
156    }
157}
158
159impl core::ops::Neg for Felt {
160    type Output = Self;
161
162    #[inline(always)]
163    fn neg(self) -> Self {
164        Self(-self.0)
165    }
166}
167
168impl PartialEq for Felt {
169    #[inline(always)]
170    fn eq(&self, other: &Self) -> bool {
171        self.as_u64() == other.as_u64()
172    }
173}
174
175impl Eq for Felt {}
176
177impl PartialOrd for Felt {
178    #[inline(always)]
179    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
180        Some(self.cmp(other))
181    }
182}
183
184impl Ord for Felt {
185    #[inline(always)]
186    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
187        self.as_u64().cmp(&other.as_u64())
188    }
189}
190
191impl core::fmt::Display for Felt {
192    #[inline]
193    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
194        core::fmt::Display::fmt(&self.as_u64(), f)
195    }
196}
197
198impl core::hash::Hash for Felt {
199    #[inline]
200    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
201        core::hash::Hash::hash(&self.as_u64(), state);
202    }
203}