Skip to main content

p521/arithmetic/field/
loose.rs

1use super::{FieldElement, field_impl::*};
2use core::ops::Mul;
3use elliptic_curve::bigint::cpubits;
4
5/// "Loose" field element: unreduced and intended to be followed by an
6/// additional operation which will perform a reduction.
7pub struct LooseFieldElement(pub(super) fiat_p521_loose_field_element);
8
9impl LooseFieldElement {
10    cpubits! {
11        32 => { const LIMBS: usize = 19; }
12        64 => { const LIMBS: usize = 9; }
13    }
14
15    /// Reduce field element.
16    #[inline]
17    pub const fn carry(&self) -> FieldElement {
18        let mut out = fiat_p521_tight_field_element([0; Self::LIMBS]);
19        fiat_p521_carry(&mut out, &self.0);
20        FieldElement(out)
21    }
22
23    /// Multiplies two field elements and reduces the result.
24    #[inline]
25    pub const fn multiply(&self, rhs: &Self) -> FieldElement {
26        let mut out = fiat_p521_tight_field_element([0; Self::LIMBS]);
27        fiat_p521_carry_mul(&mut out, &self.0, &rhs.0);
28        FieldElement(out)
29    }
30
31    /// Squares a field element and reduces the result.
32    #[inline]
33    pub const fn square(&self) -> FieldElement {
34        let mut out = fiat_p521_tight_field_element([0; Self::LIMBS]);
35        fiat_p521_carry_square(&mut out, &self.0);
36        FieldElement(out)
37    }
38}
39
40impl From<FieldElement> for LooseFieldElement {
41    #[inline]
42    fn from(tight: FieldElement) -> LooseFieldElement {
43        LooseFieldElement::from(&tight)
44    }
45}
46
47impl From<&FieldElement> for LooseFieldElement {
48    #[inline]
49    fn from(tight: &FieldElement) -> LooseFieldElement {
50        tight.relax()
51    }
52}
53
54impl From<LooseFieldElement> for FieldElement {
55    #[inline]
56    fn from(loose: LooseFieldElement) -> FieldElement {
57        FieldElement::from(&loose)
58    }
59}
60
61impl From<&LooseFieldElement> for FieldElement {
62    #[inline]
63    fn from(loose: &LooseFieldElement) -> FieldElement {
64        loose.carry()
65    }
66}
67
68impl Mul for LooseFieldElement {
69    type Output = FieldElement;
70
71    #[inline]
72    fn mul(self, rhs: LooseFieldElement) -> FieldElement {
73        Self::multiply(&self, &rhs)
74    }
75}
76
77impl Mul<&LooseFieldElement> for LooseFieldElement {
78    type Output = FieldElement;
79
80    #[inline]
81    fn mul(self, rhs: &LooseFieldElement) -> FieldElement {
82        Self::multiply(&self, rhs)
83    }
84}
85
86impl Mul<&LooseFieldElement> for &LooseFieldElement {
87    type Output = FieldElement;
88
89    #[inline]
90    fn mul(self, rhs: &LooseFieldElement) -> FieldElement {
91        LooseFieldElement::multiply(self, rhs)
92    }
93}