1use alloc::format;
4use core::{
5 array, fmt,
6 hash::{Hash, Hasher},
7 iter::{Product, Sum},
8 ops::{Add, AddAssign, Deref, DerefMut, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign},
9};
10
11use miden_serde_utils::{
12 ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable,
13};
14use num_bigint::BigUint;
15use p3_challenger::UniformSamplingField;
16use p3_field::{
17 Field, InjectiveMonomial, Packable, PermutationMonomial, PrimeCharacteristicRing, PrimeField,
18 PrimeField64, RawDataSerializable, TwoAdicField,
19 extension::{BinomiallyExtendable, BinomiallyExtendableAlgebra, HasTwoAdicBinomialExtension},
20 impl_raw_serializable_primefield64,
21 integers::QuotientMap,
22 quotient_map_large_iint, quotient_map_large_uint, quotient_map_small_int,
23};
24use p3_goldilocks::Goldilocks;
25use rand::{
26 Rng,
27 distr::{Distribution, StandardUniform},
28};
29use subtle::{ConditionallySelectable, ConstantTimeLess};
30
31#[cfg(test)]
32mod tests;
33
34#[derive(Copy, Clone, Default, serde::Serialize, serde::Deserialize)]
39#[repr(transparent)]
40pub struct Felt(Goldilocks);
41
42impl Felt {
43 pub const ORDER: u64 = <Goldilocks as PrimeField64>::ORDER_U64;
45
46 pub const ZERO: Self = Self(Goldilocks::ZERO);
47 pub const ONE: Self = Self(Goldilocks::ONE);
48
49 pub const NUM_BYTES: usize = Goldilocks::NUM_BYTES;
51
52 #[inline]
57 pub const fn new(value: u64) -> Self {
58 Self(Goldilocks::new(value))
59 }
60
61 #[inline]
62 pub fn from_u8(value: u8) -> Self {
63 <Self as PrimeCharacteristicRing>::from_u8(value)
64 }
65
66 #[inline]
67 pub fn from_u16(value: u16) -> Self {
68 <Self as PrimeCharacteristicRing>::from_u16(value)
69 }
70
71 #[inline]
72 pub fn from_u32(value: u32) -> Self {
73 <Self as PrimeCharacteristicRing>::from_u32(value)
74 }
75
76 #[inline]
78 pub fn double(&self) -> Self {
79 <Self as PrimeCharacteristicRing>::double(self)
80 }
81
82 #[inline]
84 pub fn square(&self) -> Self {
85 <Self as PrimeCharacteristicRing>::square(self)
86 }
87
88 #[inline]
90 pub fn exp_u64(&self, power: u64) -> Self {
91 <Self as PrimeCharacteristicRing>::exp_u64(self, power)
92 }
93
94 #[inline]
96 pub fn exp_const_u64<const POWER: u64>(&self) -> Self {
97 <Self as PrimeCharacteristicRing>::exp_const_u64::<POWER>(self)
98 }
99
100 #[inline]
103 pub fn as_canonical_u64(&self) -> u64 {
104 <Self as PrimeField64>::as_canonical_u64(self)
105 }
106
107 #[inline]
110 pub fn as_canonical_u64_ct(&self) -> u64 {
111 let raw = raw_felt_u64(self);
112 let reduced = raw.wrapping_sub(Self::ORDER);
115 let reduce = !raw.ct_lt(&Self::ORDER);
116 u64::conditional_select(&raw, &reduced, reduce)
117 }
118}
119
120#[inline]
121fn raw_felt_u64(value: &Felt) -> u64 {
122 const _: () = {
123 assert!(core::mem::size_of::<Felt>() == core::mem::size_of::<u64>());
124 assert!(core::mem::align_of::<Felt>() == core::mem::align_of::<u64>());
125 assert!(2u128 * (Felt::ORDER as u128) > u64::MAX as u128);
126 };
127 unsafe { core::mem::transmute_copy(value) }
129}
130
131impl fmt::Display for Felt {
132 #[inline]
133 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
134 fmt::Display::fmt(&self.0, f)
135 }
136}
137
138impl fmt::Debug for Felt {
139 #[inline]
140 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
141 fmt::Debug::fmt(&self.0, f)
142 }
143}
144
145impl Hash for Felt {
146 #[inline]
147 fn hash<H: Hasher>(&self, state: &mut H) {
148 state.write_u64(self.as_canonical_u64());
149 }
150}
151
152impl Field for Felt {
156 type Packing = Self;
157
158 const GENERATOR: Self = Self(Goldilocks::GENERATOR);
159
160 #[inline]
161 fn is_zero(&self) -> bool {
162 self.0.is_zero()
163 }
164
165 #[inline]
166 fn try_inverse(&self) -> Option<Self> {
167 self.0.try_inverse().map(Self)
168 }
169
170 #[inline]
171 fn order() -> BigUint {
172 <Goldilocks as Field>::order()
173 }
174}
175
176impl Packable for Felt {}
177
178impl PrimeCharacteristicRing for Felt {
179 type PrimeSubfield = Goldilocks;
180
181 const ZERO: Self = Self(Goldilocks::ZERO);
182 const ONE: Self = Self(Goldilocks::ONE);
183 const TWO: Self = Self(Goldilocks::TWO);
184 const NEG_ONE: Self = Self(Goldilocks::NEG_ONE);
185
186 #[inline]
187 fn from_prime_subfield(f: Self::PrimeSubfield) -> Self {
188 Self(f)
189 }
190
191 #[inline]
192 fn from_bool(value: bool) -> Self {
193 Self::new(value.into())
194 }
195
196 #[inline]
197 fn halve(&self) -> Self {
198 Self(self.0.halve())
199 }
200
201 #[inline]
202 fn mul_2exp_u64(&self, exp: u64) -> Self {
203 Self(self.0.mul_2exp_u64(exp))
204 }
205
206 #[inline]
207 fn div_2exp_u64(&self, exp: u64) -> Self {
208 Self(self.0.div_2exp_u64(exp))
209 }
210
211 #[inline]
212 fn exp_u64(&self, power: u64) -> Self {
213 self.0.exp_u64(power).into()
214 }
215}
216
217quotient_map_small_int!(Felt, u64, [u8, u16, u32]);
218quotient_map_small_int!(Felt, i64, [i8, i16, i32]);
219
220quotient_map_large_uint!(
221 Felt,
222 u64,
223 Felt::ORDER_U64,
224 "`[0, 2^64 - 2^32]`",
225 "`[0, 2^64 - 1]`",
226 [u128]
227);
228quotient_map_large_iint!(
229 Felt,
230 i64,
231 "`[-(2^63 - 2^31), 2^63 - 2^31]`",
232 "`[1 + 2^32 - 2^64, 2^64 - 1]`",
233 [(i128, u128)]
234);
235
236impl QuotientMap<u64> for Felt {
237 #[inline]
238 fn from_int(int: u64) -> Self {
239 Goldilocks::from_int(int).into()
240 }
241
242 #[inline]
243 fn from_canonical_checked(int: u64) -> Option<Self> {
244 Goldilocks::from_canonical_checked(int).map(From::from)
245 }
246
247 #[inline(always)]
248 unsafe fn from_canonical_unchecked(int: u64) -> Self {
249 Goldilocks::new(int).into()
250 }
251}
252
253impl QuotientMap<i64> for Felt {
254 #[inline]
255 fn from_int(int: i64) -> Self {
256 Goldilocks::from_int(int).into()
257 }
258
259 #[inline]
260 fn from_canonical_checked(int: i64) -> Option<Self> {
261 Goldilocks::from_canonical_checked(int).map(From::from)
262 }
263
264 #[inline(always)]
265 unsafe fn from_canonical_unchecked(int: i64) -> Self {
266 unsafe { Goldilocks::from_canonical_unchecked(int).into() }
267 }
268}
269
270impl PrimeField for Felt {
271 #[inline]
272 fn as_canonical_biguint(&self) -> BigUint {
273 <Goldilocks as PrimeField>::as_canonical_biguint(&self.0)
274 }
275}
276
277impl PrimeField64 for Felt {
278 const ORDER_U64: u64 = <Goldilocks as PrimeField64>::ORDER_U64;
279
280 #[inline]
281 fn as_canonical_u64(&self) -> u64 {
282 self.0.as_canonical_u64()
283 }
284}
285
286impl TwoAdicField for Felt {
287 const TWO_ADICITY: usize = <Goldilocks as TwoAdicField>::TWO_ADICITY;
288
289 #[inline]
290 fn two_adic_generator(bits: usize) -> Self {
291 Self(<Goldilocks as TwoAdicField>::two_adic_generator(bits))
292 }
293}
294
295impl BinomiallyExtendableAlgebra<Self, 2> for Felt {}
299
300impl BinomiallyExtendable<2> for Felt {
301 const W: Self = Self(<Goldilocks as BinomiallyExtendable<2>>::W);
302
303 const DTH_ROOT: Self = Self(<Goldilocks as BinomiallyExtendable<2>>::DTH_ROOT);
304
305 const EXT_GENERATOR: [Self; 2] = [
306 Self(<Goldilocks as BinomiallyExtendable<2>>::EXT_GENERATOR[0]),
307 Self(<Goldilocks as BinomiallyExtendable<2>>::EXT_GENERATOR[1]),
308 ];
309}
310
311impl HasTwoAdicBinomialExtension<2> for Felt {
312 const EXT_TWO_ADICITY: usize = <Goldilocks as HasTwoAdicBinomialExtension<2>>::EXT_TWO_ADICITY;
313
314 #[inline]
315 fn ext_two_adic_generator(bits: usize) -> [Self; 2] {
316 let [a, b] = <Goldilocks as HasTwoAdicBinomialExtension<2>>::ext_two_adic_generator(bits);
317 [Self(a), Self(b)]
318 }
319}
320
321impl BinomiallyExtendableAlgebra<Self, 5> for Felt {}
322
323impl BinomiallyExtendable<5> for Felt {
324 const W: Self = Self(<Goldilocks as BinomiallyExtendable<5>>::W);
325
326 const DTH_ROOT: Self = Self(<Goldilocks as BinomiallyExtendable<5>>::DTH_ROOT);
327
328 const EXT_GENERATOR: [Self; 5] = [
329 Self(<Goldilocks as BinomiallyExtendable<5>>::EXT_GENERATOR[0]),
330 Self(<Goldilocks as BinomiallyExtendable<5>>::EXT_GENERATOR[1]),
331 Self(<Goldilocks as BinomiallyExtendable<5>>::EXT_GENERATOR[2]),
332 Self(<Goldilocks as BinomiallyExtendable<5>>::EXT_GENERATOR[3]),
333 Self(<Goldilocks as BinomiallyExtendable<5>>::EXT_GENERATOR[4]),
334 ];
335}
336
337impl HasTwoAdicBinomialExtension<5> for Felt {
338 const EXT_TWO_ADICITY: usize = <Goldilocks as HasTwoAdicBinomialExtension<5>>::EXT_TWO_ADICITY;
339
340 #[inline]
341 fn ext_two_adic_generator(bits: usize) -> [Self; 5] {
342 let ext_generator =
343 <Goldilocks as HasTwoAdicBinomialExtension<5>>::ext_two_adic_generator(bits);
344 [
345 Self(ext_generator[0]),
346 Self(ext_generator[1]),
347 Self(ext_generator[2]),
348 Self(ext_generator[3]),
349 Self(ext_generator[4]),
350 ]
351 }
352}
353
354impl RawDataSerializable for Felt {
355 impl_raw_serializable_primefield64!();
356}
357
358impl Distribution<Felt> for StandardUniform {
359 #[inline]
360 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Felt {
361 let inner = <StandardUniform as Distribution<Goldilocks>>::sample(self, rng);
362 Felt(inner)
363 }
364}
365
366impl UniformSamplingField for Felt {
367 const MAX_SINGLE_SAMPLE_BITS: usize =
368 <Goldilocks as UniformSamplingField>::MAX_SINGLE_SAMPLE_BITS;
369 const SAMPLING_BITS_M: [u64; 64] = <Goldilocks as UniformSamplingField>::SAMPLING_BITS_M;
370}
371
372impl InjectiveMonomial<7> for Felt {}
373
374impl PermutationMonomial<7> for Felt {
375 #[inline]
376 fn injective_exp_root_n(&self) -> Self {
377 Self(self.0.injective_exp_root_n())
378 }
379}
380
381impl From<u8> for Felt {
385 fn from(int: u8) -> Self {
386 Self::from_u8(int)
387 }
388}
389
390impl From<u16> for Felt {
391 fn from(int: u16) -> Self {
392 Self::from_u16(int)
393 }
394}
395
396impl From<u32> for Felt {
397 fn from(int: u32) -> Self {
398 Self::from_u32(int)
399 }
400}
401
402impl TryFrom<u64> for Felt {
403 type Error = FeltFromIntError;
404
405 fn try_from(int: u64) -> Result<Felt, Self::Error> {
406 Felt::from_canonical_checked(int).ok_or(FeltFromIntError(int))
407 }
408}
409
410#[derive(Debug, thiserror::Error)]
411#[error("integer {0} is equal to or exceeds the felt modulus {modulus}", modulus = Felt::ORDER)]
412pub struct FeltFromIntError(u64);
413
414impl FeltFromIntError {
415 pub fn as_u64(&self) -> u64 {
417 self.0
418 }
419}
420
421impl Deref for Felt {
422 type Target = Goldilocks;
423
424 #[inline]
425 fn deref(&self) -> &Self::Target {
426 &self.0
427 }
428}
429
430impl DerefMut for Felt {
431 #[inline]
432 fn deref_mut(&mut self) -> &mut Self::Target {
433 &mut self.0
434 }
435}
436
437impl From<Goldilocks> for Felt {
438 #[inline]
439 fn from(value: Goldilocks) -> Self {
440 Self(value)
441 }
442}
443
444impl From<Felt> for Goldilocks {
445 #[inline]
446 fn from(value: Felt) -> Self {
447 value.0
448 }
449}
450
451impl Add for Felt {
455 type Output = Self;
456
457 #[inline]
458 fn add(self, other: Self) -> Self {
459 Self(self.0 + other.0)
460 }
461}
462
463impl AddAssign for Felt {
464 #[inline]
465 fn add_assign(&mut self, other: Self) {
466 *self = *self + other;
467 }
468}
469
470impl Sub for Felt {
471 type Output = Self;
472
473 #[inline]
474 fn sub(self, other: Self) -> Self {
475 Self(self.0 - other.0)
476 }
477}
478
479impl SubAssign for Felt {
480 #[inline]
481 fn sub_assign(&mut self, other: Self) {
482 *self = *self - other;
483 }
484}
485
486impl Mul for Felt {
487 type Output = Self;
488
489 #[inline]
490 fn mul(self, other: Self) -> Self {
491 Self(self.0 * other.0)
492 }
493}
494
495impl MulAssign for Felt {
496 #[inline]
497 fn mul_assign(&mut self, other: Self) {
498 *self = *self * other;
499 }
500}
501
502impl Div for Felt {
503 type Output = Self;
504
505 #[inline]
506 fn div(self, other: Self) -> Self {
507 Self(self.0 / other.0)
508 }
509}
510
511impl DivAssign for Felt {
512 #[inline]
513 fn div_assign(&mut self, other: Self) {
514 *self = *self / other;
515 }
516}
517
518impl Neg for Felt {
519 type Output = Self;
520
521 #[inline]
522 fn neg(self) -> Self {
523 Self(-self.0)
524 }
525}
526
527impl Sum for Felt {
528 #[inline]
529 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
530 Self(iter.map(|x| x.0).sum())
531 }
532}
533
534impl<'a> Sum<&'a Felt> for Felt {
535 #[inline]
536 fn sum<I: Iterator<Item = &'a Felt>>(iter: I) -> Self {
537 Self(iter.map(|x| x.0).sum())
538 }
539}
540
541impl Product for Felt {
542 #[inline]
543 fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
544 Self(iter.map(|x| x.0).product())
545 }
546}
547
548impl<'a> Product<&'a Felt> for Felt {
549 #[inline]
550 fn product<I: Iterator<Item = &'a Felt>>(iter: I) -> Self {
551 Self(iter.map(|x| x.0).product())
552 }
553}
554
555impl PartialEq for Felt {
559 #[inline]
560 fn eq(&self, other: &Self) -> bool {
561 self.0 == other.0
562 }
563}
564
565impl PartialEq<Goldilocks> for Felt {
566 #[inline]
567 fn eq(&self, other: &Goldilocks) -> bool {
568 self.0 == *other
569 }
570}
571
572impl Eq for Felt {}
573
574impl PartialOrd for Felt {
575 #[inline]
576 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
577 Some(self.cmp(other))
578 }
579}
580
581impl Ord for Felt {
582 #[inline]
583 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
584 self.0.cmp(&other.0)
585 }
586}
587
588impl Serializable for Felt {
592 fn write_into<W: ByteWriter>(&self, target: &mut W) {
593 target.write_u64(self.as_canonical_u64());
594 }
595
596 fn get_size_hint(&self) -> usize {
597 core::mem::size_of::<u64>()
598 }
599}
600
601impl Deserializable for Felt {
602 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
603 let value = source.read_u64()?;
604 Self::from_canonical_checked(value).ok_or_else(|| {
605 DeserializationError::InvalidValue(format!("value {value} is not a valid felt"))
606 })
607 }
608}
609
610#[cfg(all(any(test, feature = "testing"), not(all(target_family = "wasm", miden))))]
614mod arbitrary {
615 use proptest::prelude::*;
616
617 use super::Felt;
618
619 impl Arbitrary for Felt {
620 type Parameters = ();
621 type Strategy = BoxedStrategy<Self>;
622
623 fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
624 let canonical = (0u64..Felt::ORDER).prop_map(Felt::new).boxed();
625 let non_canonical = (Felt::ORDER..=u64::MAX).prop_map(Felt::new).boxed();
629 prop_oneof![4 => canonical, 1 => non_canonical].no_shrink().boxed()
630 }
631 }
632}