1use miden_core::{Felt as CoreFelt, FieldElement};
4
5use crate::FeltImpl;
6
7#[repr(transparent)]
8#[derive(Copy, Clone, Debug)]
9pub 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}