1#![allow(
14    clippy::should_implement_trait,
15    clippy::suspicious_op_assign_impl,
16    clippy::unused_unit,
17    clippy::unnecessary_cast,
18    clippy::too_many_arguments,
19    clippy::identity_op,
20    rustdoc::bare_urls
21)]
22
23#[path = "field/p521_64.rs"]
25mod field_impl;
26mod loose;
27
28pub(crate) use self::loose::LooseFieldElement;
29
30use self::field_impl::*;
31use crate::{FieldBytes, NistP521, U576};
32use core::{
33    fmt::{self, Debug},
34    iter::{Product, Sum},
35    ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign},
36};
37use elliptic_curve::{
38    ff::{self, Field, PrimeField},
39    generic_array::GenericArray,
40    rand_core::RngCore,
41    subtle::{Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeLess, CtOption},
42    zeroize::DefaultIsZeroes,
43    Error, FieldBytesEncoding,
44};
45
46use super::util::u576_to_le_bytes;
47
48const MODULUS_HEX: &str = "00000000000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
51
52pub(crate) const MODULUS: U576 = U576::from_be_hex(MODULUS_HEX);
53
54#[derive(Clone, Copy)]
56pub struct FieldElement(pub(crate) fiat_p521_tight_field_element);
57
58impl FieldElement {
59    pub const ZERO: Self = Self::from_u64(0);
61
62    pub const ONE: Self = Self::from_u64(1);
64
65    const BYTES: usize = 66;
67
68    pub fn from_bytes(repr: &FieldBytes) -> CtOption<Self> {
70        let uint = <U576 as FieldBytesEncoding<NistP521>>::decode_field_bytes(repr);
71        Self::from_uint(uint)
72    }
73
74    pub fn from_slice(slice: &[u8]) -> elliptic_curve::Result<Self> {
76        if slice.len() != Self::BYTES {
77            return Err(Error);
78        }
79
80        Option::from(Self::from_bytes(GenericArray::from_slice(slice))).ok_or(Error)
81    }
82
83    pub fn from_uint(uint: U576) -> CtOption<Self> {
85        let is_some = uint.ct_lt(&MODULUS);
86        CtOption::new(Self::from_uint_unchecked(uint), is_some)
87    }
88
89    pub(crate) const fn from_hex(hex: &str) -> Self {
95        Self::from_uint_unchecked(U576::from_be_hex(hex))
96    }
97
98    pub const fn from_u64(w: u64) -> Self {
100        Self::from_uint_unchecked(U576::from_u64(w))
101    }
102
103    pub(crate) const fn from_uint_unchecked(w: U576) -> Self {
109        Self(fiat_p521_from_bytes(&u576_to_le_bytes(w)))
110    }
111
112    pub fn to_bytes(self) -> FieldBytes {
114        let mut ret = fiat_p521_to_bytes(&self.0);
115        ret.reverse();
116        GenericArray::clone_from_slice(&ret)
117    }
118
119    pub fn is_odd(&self) -> Choice {
125        Choice::from(self.0[0] as u8 & 1)
126    }
127
128    pub fn is_even(&self) -> Choice {
134        !self.is_odd()
135    }
136
137    pub fn is_zero(&self) -> Choice {
143        self.ct_eq(&Self::ZERO)
144    }
145
146    #[allow(dead_code)] pub(crate) const fn add_loose(&self, rhs: &Self) -> LooseFieldElement {
149        LooseFieldElement(fiat_p521_add(&self.0, &rhs.0))
150    }
151
152    #[allow(dead_code)] #[must_use]
155    pub(crate) const fn double_loose(&self) -> LooseFieldElement {
156        Self::add_loose(self, self)
157    }
158
159    #[allow(dead_code)] pub(crate) const fn sub_loose(&self, rhs: &Self) -> LooseFieldElement {
162        LooseFieldElement(fiat_p521_sub(&self.0, &rhs.0))
163    }
164
165    #[allow(dead_code)] pub(crate) const fn neg_loose(&self) -> LooseFieldElement {
168        LooseFieldElement(fiat_p521_opp(&self.0))
169    }
170
171    pub const fn add(&self, rhs: &Self) -> Self {
173        Self(fiat_p521_carry_add(&self.0, &rhs.0))
174    }
175
176    pub const fn sub(&self, rhs: &Self) -> Self {
178        Self(fiat_p521_carry_sub(&self.0, &rhs.0))
179    }
180
181    pub const fn neg(&self) -> Self {
183        Self(fiat_p521_carry_opp(&self.0))
184    }
185
186    #[must_use]
188    pub const fn double(&self) -> Self {
189        self.add(self)
190    }
191
192    pub const fn multiply(&self, rhs: &Self) -> Self {
194        LooseFieldElement::mul(&self.relax(), &rhs.relax())
195    }
196
197    pub const fn square(&self) -> Self {
199        self.relax().square()
200    }
201
202    const fn sqn(&self, n: usize) -> Self {
204        let mut x = self.square();
205        let mut i = 1;
206        while i < n {
207            x = x.square();
208            i += 1;
209        }
210        x
211    }
212
213    pub const fn pow_vartime(&self, exp: &[u64]) -> Self {
219        let mut res = Self::ONE;
220        let mut i = exp.len();
221
222        while i > 0 {
223            i -= 1;
224
225            let mut j = 64;
226            while j > 0 {
227                j -= 1;
228                res = res.square();
229
230                if ((exp[i] >> j) & 1) == 1 {
231                    res = Self::multiply(&res, self);
232                }
233            }
234        }
235
236        res
237    }
238
239    pub fn invert(&self) -> CtOption<Self> {
241        CtOption::new(self.invert_unchecked(), !self.is_zero())
242    }
243
244    const fn invert_unchecked(&self) -> Self {
248        let z = self.square();
250        let z = self.multiply(&z);
251        let t0 = z.sqn(2);
252        let z = z.multiply(&t0);
253        let t0 = z.sqn(4);
254        let z = z.multiply(&t0);
255        let t0 = z.sqn(8);
256        let z = z.multiply(&t0);
257        let t0 = z.sqn(16);
258        let z = z.multiply(&t0);
259        let t0 = z.sqn(32);
260        let z = z.multiply(&t0);
261        let t0 = z.square();
262        let t0 = self.multiply(&t0);
263        let t0 = t0.sqn(64);
264        let z = z.multiply(&t0);
265        let t0 = z.square();
266        let t0 = self.multiply(&t0);
267        let t0 = t0.sqn(129);
268        let z = z.multiply(&t0);
269        let t0 = z.square();
270        let t0 = self.multiply(&t0);
271        let t0 = t0.sqn(259);
272        let z = z.multiply(&t0);
273        let z = z.sqn(2);
274        self.multiply(&z)
275    }
276
277    pub fn sqrt(&self) -> CtOption<Self> {
289        let sqrt = self.sqn(519);
290        CtOption::new(sqrt, sqrt.square().ct_eq(self))
291    }
292
293    pub(crate) const fn relax(&self) -> LooseFieldElement {
295        LooseFieldElement(fiat_p521_relax(&self.0))
296    }
297}
298
299impl AsRef<fiat_p521_tight_field_element> for FieldElement {
300    fn as_ref(&self) -> &fiat_p521_tight_field_element {
301        &self.0
302    }
303}
304
305impl Default for FieldElement {
306    fn default() -> Self {
307        Self::ZERO
308    }
309}
310
311impl Debug for FieldElement {
312    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
336        let mut bytes = fiat_p521_to_bytes(&self.0);
337        bytes.reverse();
338
339        let formatter = base16ct::HexDisplay(&bytes);
340        f.debug_tuple("FieldElement")
341            .field(&format_args!("0x{formatter:X}"))
342            .finish()
343    }
344}
345
346impl Eq for FieldElement {}
347impl PartialEq for FieldElement {
348    fn eq(&self, rhs: &Self) -> bool {
349        self.ct_eq(rhs).into()
350    }
351}
352
353impl From<u32> for FieldElement {
354    fn from(n: u32) -> FieldElement {
355        Self::from_uint_unchecked(U576::from(n))
356    }
357}
358
359impl From<u64> for FieldElement {
360    fn from(n: u64) -> FieldElement {
361        Self::from_uint_unchecked(U576::from(n))
362    }
363}
364
365impl From<u128> for FieldElement {
366    fn from(n: u128) -> FieldElement {
367        Self::from_uint_unchecked(U576::from(n))
368    }
369}
370
371impl ConditionallySelectable for FieldElement {
372    fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
373        let mut ret = Self::ZERO;
374
375        for i in 0..ret.0.len() {
376            ret.0[i] = u64::conditional_select(&a.0[i], &b.0[i], choice);
377        }
378
379        ret
380    }
381}
382
383impl ConstantTimeEq for FieldElement {
384    fn ct_eq(&self, other: &Self) -> Choice {
385        let a = fiat_p521_to_bytes(&self.0);
386        let b = fiat_p521_to_bytes(&other.0);
387        a.ct_eq(&b)
388    }
389}
390
391impl DefaultIsZeroes for FieldElement {}
392
393impl Field for FieldElement {
394    const ZERO: Self = Self::ZERO;
395    const ONE: Self = Self::ONE;
396
397    fn random(mut rng: impl RngCore) -> Self {
398        let mut bytes = <FieldBytes>::default();
400
401        loop {
402            rng.fill_bytes(&mut bytes);
403            if let Some(fe) = Self::from_bytes(&bytes).into() {
404                return fe;
405            }
406        }
407    }
408
409    fn is_zero(&self) -> Choice {
410        Self::ZERO.ct_eq(self)
411    }
412
413    #[must_use]
414    fn square(&self) -> Self {
415        self.square()
416    }
417
418    #[must_use]
419    fn double(&self) -> Self {
420        self.double()
421    }
422
423    fn invert(&self) -> CtOption<Self> {
424        self.invert()
425    }
426
427    fn sqrt(&self) -> CtOption<Self> {
428        self.sqrt()
429    }
430
431    fn sqrt_ratio(num: &Self, div: &Self) -> (Choice, Self) {
432        ff::helpers::sqrt_ratio_generic(num, div)
433    }
434}
435
436impl PrimeField for FieldElement {
437    type Repr = FieldBytes;
438
439    const MODULUS: &'static str = MODULUS_HEX;
440    const NUM_BITS: u32 = 521;
441    const CAPACITY: u32 = 520;
442    const TWO_INV: Self = Self::from_u64(2).invert_unchecked();
443    const MULTIPLICATIVE_GENERATOR: Self = Self::from_u64(3);
444    const S: u32 = 1;
445    const ROOT_OF_UNITY: Self = Self::from_hex("00000000000001fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe");
446    const ROOT_OF_UNITY_INV: Self = Self::ROOT_OF_UNITY.invert_unchecked();
447    const DELTA: Self = Self::from_u64(9);
448
449    #[inline]
450    fn from_repr(bytes: FieldBytes) -> CtOption<Self> {
451        Self::from_bytes(&bytes)
452    }
453
454    #[inline]
455    fn to_repr(&self) -> FieldBytes {
456        self.to_bytes()
457    }
458
459    #[inline]
460    fn is_odd(&self) -> Choice {
461        self.is_odd()
462    }
463}
464
465impl Add for FieldElement {
470    type Output = FieldElement;
471
472    #[inline]
473    fn add(self, rhs: FieldElement) -> FieldElement {
474        Self::add(&self, &rhs)
475    }
476}
477
478impl Add<&FieldElement> for FieldElement {
479    type Output = FieldElement;
480
481    #[inline]
482    fn add(self, rhs: &FieldElement) -> FieldElement {
483        Self::add(&self, rhs)
484    }
485}
486
487impl Add<&FieldElement> for &FieldElement {
488    type Output = FieldElement;
489
490    #[inline]
491    fn add(self, rhs: &FieldElement) -> FieldElement {
492        FieldElement::add(self, rhs)
493    }
494}
495
496impl AddAssign<FieldElement> for FieldElement {
497    #[inline]
498    fn add_assign(&mut self, other: FieldElement) {
499        *self = *self + other;
500    }
501}
502
503impl AddAssign<&FieldElement> for FieldElement {
504    #[inline]
505    fn add_assign(&mut self, other: &FieldElement) {
506        *self = *self + other;
507    }
508}
509
510impl Sub for FieldElement {
511    type Output = FieldElement;
512
513    #[inline]
514    fn sub(self, rhs: FieldElement) -> FieldElement {
515        Self::sub(&self, &rhs)
516    }
517}
518
519impl Sub<&FieldElement> for FieldElement {
520    type Output = FieldElement;
521
522    #[inline]
523    fn sub(self, rhs: &FieldElement) -> FieldElement {
524        Self::sub(&self, rhs)
525    }
526}
527
528impl Sub<&FieldElement> for &FieldElement {
529    type Output = FieldElement;
530
531    #[inline]
532    fn sub(self, rhs: &FieldElement) -> FieldElement {
533        FieldElement::sub(self, rhs)
534    }
535}
536
537impl SubAssign<FieldElement> for FieldElement {
538    #[inline]
539    fn sub_assign(&mut self, other: FieldElement) {
540        *self = *self - other;
541    }
542}
543
544impl SubAssign<&FieldElement> for FieldElement {
545    #[inline]
546    fn sub_assign(&mut self, other: &FieldElement) {
547        *self = *self - other;
548    }
549}
550
551impl Mul for FieldElement {
552    type Output = FieldElement;
553
554    #[inline]
555    fn mul(self, rhs: FieldElement) -> FieldElement {
556        self.relax().mul(&rhs.relax())
557    }
558}
559
560impl Mul<&FieldElement> for FieldElement {
561    type Output = FieldElement;
562
563    #[inline]
564    fn mul(self, rhs: &FieldElement) -> FieldElement {
565        self.relax().mul(&rhs.relax())
566    }
567}
568
569impl Mul<&FieldElement> for &FieldElement {
570    type Output = FieldElement;
571
572    #[inline]
573    fn mul(self, rhs: &FieldElement) -> FieldElement {
574        self.relax().mul(&rhs.relax())
575    }
576}
577
578impl MulAssign<&FieldElement> for FieldElement {
579    #[inline]
580    fn mul_assign(&mut self, other: &FieldElement) {
581        *self = *self * other;
582    }
583}
584
585impl MulAssign for FieldElement {
586    #[inline]
587    fn mul_assign(&mut self, other: FieldElement) {
588        *self = *self * other;
589    }
590}
591
592impl Neg for FieldElement {
593    type Output = FieldElement;
594
595    #[inline]
596    fn neg(self) -> FieldElement {
597        Self::neg(&self)
598    }
599}
600
601impl Sum for FieldElement {
606    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
607        iter.reduce(core::ops::Add::add).unwrap_or(Self::ZERO)
608    }
609}
610
611impl<'a> Sum<&'a FieldElement> for FieldElement {
612    fn sum<I: Iterator<Item = &'a FieldElement>>(iter: I) -> Self {
613        iter.copied().sum()
614    }
615}
616
617impl Product for FieldElement {
618    fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
619        iter.reduce(core::ops::Mul::mul).unwrap_or(Self::ONE)
620    }
621}
622
623impl<'a> Product<&'a FieldElement> for FieldElement {
624    fn product<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
625        iter.copied().product()
626    }
627}
628
629#[cfg(test)]
630mod tests {
631    use super::FieldElement;
632    use elliptic_curve::ff::PrimeField;
633    use hex_literal::hex;
634    use primeorder::{
635        impl_field_identity_tests, impl_field_invert_tests, impl_field_sqrt_tests,
636        impl_primefield_tests,
637    };
638
639    const T: [u64; 9] = [
641        0xffffffffffffffff,
642        0xffffffffffffffff,
643        0xffffffffffffffff,
644        0xffffffffffffffff,
645        0xffffffffffffffff,
646        0xffffffffffffffff,
647        0xffffffffffffffff,
648        0xffffffffffffffff,
649        0x00000000000000ff,
650    ];
651
652    impl_field_identity_tests!(FieldElement);
653    impl_field_invert_tests!(FieldElement);
654    impl_field_sqrt_tests!(FieldElement);
655    impl_primefield_tests!(FieldElement, T);
656
657    #[test]
659    fn decode_invalid_field_element_returns_err() {
660        let overflowing_bytes = hex!("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
661        let ct_option = FieldElement::from_bytes(overflowing_bytes.as_ref().into());
662        assert!(bool::from(ct_option.is_none()));
663    }
664}