diff --git a/Cargo.toml b/Cargo.toml index be5161c..de20aaf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ exclude = [".gitignore", ".github/*"] [dependencies] subtle = "2.2.2" rand_core = { version = "0.6", optional = true } -fiat-crypto = { version = "0.1.4", optional = true } +fiat-crypto = { version = "0.2.0", optional = true } [dependencies.zeroize] version = "1" diff --git a/src/field/fiat_u64/constants.rs b/src/field/fiat_u64/constants.rs index f3f755d..12275a9 100644 --- a/src/field/fiat_u64/constants.rs +++ b/src/field/fiat_u64/constants.rs @@ -1,3 +1,5 @@ +use fiat_crypto::p448_solinas_64::fiat_p448_tight_field_element; + // Move all curve specific constants into this file // as they will have different representations depending on the backend use crate::curve::edwards::ExtendedPoint; @@ -5,19 +7,20 @@ use crate::curve::twedwards::extended::ExtendedPoint as TwExtendedPoint; use crate::field::fiat_u64::FieldElement56; /// -4 * Twisted_D = -4 * (EDWARDS_D-1) -pub const NEG_FOUR_TIMES_TWISTED_D: FieldElement56 = FieldElement56([ - 156327, - 0, - 0, - 0, - 72057594037927935, - 72057594037927935, - 72057594037927935, - 72057594037927935, -]); +pub const NEG_FOUR_TIMES_TWISTED_D: FieldElement56 = + FieldElement56(fiat_p448_tight_field_element([ + 156327, + 0, + 0, + 0, + 72057594037927935, + 72057594037927935, + 72057594037927935, + 72057594037927935, + ])); /// Edwards `d`, equals to -39081 -pub const EDWARDS_D: FieldElement56 = FieldElement56([ +pub const EDWARDS_D: FieldElement56 = FieldElement56(fiat_p448_tight_field_element([ 144115188075816789, 144115188075855870, 144115188075855870, @@ -26,13 +29,14 @@ pub const EDWARDS_D: FieldElement56 = FieldElement56([ 144115188075855870, 144115188075855870, 144115188075855870, -]); +])); /// Neg_Edwards `-d`, equals to 39081 -pub const NEG_EDWARDS_D: FieldElement56 = FieldElement56([39081, 0, 0, 0, 0, 0, 0, 0]); +pub const NEG_EDWARDS_D: FieldElement56 = + FieldElement56(fiat_p448_tight_field_element([39081, 0, 0, 0, 0, 0, 0, 0])); /// Twisted Edwards D equals `d-1`, equals to -39082 -pub const TWISTED_D: FieldElement56 = FieldElement56([ +pub const TWISTED_D: FieldElement56 = FieldElement56(fiat_p448_tight_field_element([ 144115188075816788, 144115188075855870, 144115188075855870, @@ -41,10 +45,10 @@ pub const TWISTED_D: FieldElement56 = FieldElement56([ 144115188075855870, 144115188075855870, 144115188075855870, -]); +])); /// Twice the Twisted Edwards d which equals to -78164 -pub const TWO_TIMES_TWISTED_D: FieldElement56 = FieldElement56([ +pub const TWO_TIMES_TWISTED_D: FieldElement56 = FieldElement56(fiat_p448_tight_field_element([ 144115188075777706, 144115188075855870, 144115188075855870, @@ -53,10 +57,10 @@ pub const TWO_TIMES_TWISTED_D: FieldElement56 = FieldElement56([ 144115188075855870, 144115188075855870, 144115188075855870, -]); +])); /// INVSQRT(a*d_2-1) where d_2 = 39082/39081 -pub const DECAF_FACTOR: FieldElement56 = FieldElement56([ +pub const DECAF_FACTOR: FieldElement56 = FieldElement56(fiat_p448_tight_field_element([ 0x42ef0f45572736, 0x7bf6aa20ce5296, 0xf4fd6eded26033, @@ -65,14 +69,15 @@ pub const DECAF_FACTOR: FieldElement56 = FieldElement56([ 0x6aa0a1f1a7b8a5, 0x683bf68d722fa2, 0x22d962fbeb24f7, -]); +])); /// 39082 used in the doubling procedure in montgomery ladder -pub const A_PLUS_TWO_OVER_FOUR: FieldElement56 = FieldElement56([39082, 0, 0, 0, 0, 0, 0, 0]); +pub const A_PLUS_TWO_OVER_FOUR: FieldElement56 = + FieldElement56(fiat_p448_tight_field_element([39082, 0, 0, 0, 0, 0, 0, 0])); /// The basepoint of Ed448-Goldilocks pub const GOLDILOCKS_BASE_POINT: ExtendedPoint = ExtendedPoint { - X: FieldElement56([ + X: FieldElement56(fiat_p448_tight_field_element([ 10880955091566686, 36276784145337894, 69571282115576635, @@ -81,8 +86,8 @@ pub const GOLDILOCKS_BASE_POINT: ExtendedPoint = ExtendedPoint { 15440021224255559, 66747077793030847, 22264495316135181, - ]), - Y: FieldElement56([ + ])), + Y: FieldElement56(fiat_p448_tight_field_element([ 2385235625966100, 5396741696826776, 8134720567442877, @@ -91,9 +96,9 @@ pub const GOLDILOCKS_BASE_POINT: ExtendedPoint = ExtendedPoint { 56121598560924524, 10283140089599689, 29624444337960636, - ]), - Z: FieldElement56([1, 0, 0, 0, 0, 0, 0, 0]), - T: FieldElement56([ + ])), + Z: FieldElement56(fiat_p448_tight_field_element([1, 0, 0, 0, 0, 0, 0, 0])), + T: FieldElement56(fiat_p448_tight_field_element([ 1796939199780339, 45174008172060139, 40732174862907279, @@ -102,12 +107,12 @@ pub const GOLDILOCKS_BASE_POINT: ExtendedPoint = ExtendedPoint { 41035719659624511, 30626637035688077, 56117654178374172, - ]), + ])), }; /// The basepoint of the Twisted Edwards curve which is 2-isogenous to Ed448-Goldilocks pub const TWISTED_EDWARDS_BASE_POINT: TwExtendedPoint = TwExtendedPoint { - X: FieldElement56([ + X: FieldElement56(fiat_p448_tight_field_element([ 0, 72057594037927936, 72057594037927935, @@ -116,8 +121,8 @@ pub const TWISTED_EDWARDS_BASE_POINT: TwExtendedPoint = TwExtendedPoint { 72057594037927935, 72057594037927935, 36028797018963967, - ]), - Y: FieldElement56([ + ])), + Y: FieldElement56(fiat_p448_tight_field_element([ 27155415521118820, 3410937204744648, 19376965222209947, @@ -126,9 +131,9 @@ pub const TWISTED_EDWARDS_BASE_POINT: TwExtendedPoint = TwExtendedPoint { 10141917371396176, 59827755213158602, 37445921829569158, - ]), - Z: FieldElement56([1, 0, 0, 0, 0, 0, 0, 0]), - T: FieldElement56([ + ])), + Z: FieldElement56(fiat_p448_tight_field_element([1, 0, 0, 0, 0, 0, 0, 0])), + T: FieldElement56(fiat_p448_tight_field_element([ 64114820220813573, 27592348249940115, 21918321435874307, @@ -137,5 +142,5 @@ pub const TWISTED_EDWARDS_BASE_POINT: TwExtendedPoint = TwExtendedPoint { 63575698147485199, 22766751209138687, 30740600843388580, - ]), + ])), }; diff --git a/src/field/fiat_u64/prime_field.rs b/src/field/fiat_u64/prime_field.rs index 9f178cb..b07389d 100644 --- a/src/field/fiat_u64/prime_field.rs +++ b/src/field/fiat_u64/prime_field.rs @@ -10,8 +10,14 @@ use subtle::{Choice, ConditionallyNegatable, ConditionallySelectable}; // XXX: Check if the Serialisation procedure in FieldElement56 is consistent with FieldElement28 -#[derive(Copy, Clone, Debug)] -pub struct FieldElement56(pub(crate) [u64; 8]); +#[derive(Copy, Clone)] +pub struct FieldElement56(pub(crate) fiat_p448_tight_field_element); + +impl std::fmt::Debug for FieldElement56 { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("FieldElement56").field(&self.0 .0).finish() + } +} //// /// Trait Implementations @@ -33,7 +39,11 @@ impl Mul<&FieldElement56> for &FieldElement56 { type Output = FieldElement56; fn mul(self, rhs: &FieldElement56) -> Self::Output { let mut result = FieldElement56::zero(); - fiat_p448_carry_mul(&mut result.0, &self.0, &rhs.0); + let mut self_loose = fiat_p448_loose_field_element([0; 8]); + fiat_p448_relax(&mut self_loose, &self.0); + let mut rhs_loose = fiat_p448_loose_field_element([0; 8]); + fiat_p448_relax(&mut rhs_loose, &rhs.0); + fiat_p448_carry_mul(&mut result.0, &self_loose, &rhs_loose); result } } @@ -53,17 +63,21 @@ impl Mul for FieldElement56 { impl Add for FieldElement56 { type Output = FieldElement56; fn add(self, rhs: FieldElement56) -> Self::Output { - let mut inter_res = self.add_no_reduce(&rhs); - inter_res.strong_reduce(); - inter_res + let mut result_loose = fiat_p448_loose_field_element([0; 8]); + fiat_p448_add(&mut result_loose, &self.0, &rhs.0); + let mut result = FieldElement56::zero(); + fiat_p448_carry(&mut result.0, &result_loose); + result } } impl Sub for FieldElement56 { type Output = FieldElement56; fn sub(self, rhs: FieldElement56) -> Self::Output { - let mut inter_res = self.sub_no_reduce(&rhs); - inter_res.strong_reduce(); - inter_res + let mut result_loose = fiat_p448_loose_field_element([0; 8]); + fiat_p448_sub(&mut result_loose, &self.0, &rhs.0); + let mut result = FieldElement56::zero(); + fiat_p448_carry(&mut result.0, &result_loose); + result } } @@ -81,7 +95,7 @@ impl ConditionallySelectable for FieldElement56 { choice: Choice, ) -> FieldElement56 { let mut result = FieldElement56::zero(); - fiat_p448_selectznz(&mut result.0, choice.unwrap_u8(), &a.0, &b.0); + fiat_p448_selectznz(&mut (result.0).0, choice.unwrap_u8(), &(a.0).0, &(b.0).0); result } } @@ -98,13 +112,13 @@ impl Default for FieldElement56 { impl FieldElement56 { pub const fn zero() -> FieldElement56 { - FieldElement56([0; 8]) + FieldElement56(fiat_p448_tight_field_element([0; 8])) } pub const fn one() -> FieldElement56 { - FieldElement56([1, 0, 0, 0, 0, 0, 0, 0]) + FieldElement56(fiat_p448_tight_field_element([1, 0, 0, 0, 0, 0, 0, 0])) } pub fn minus_one() -> FieldElement56 { - FieldElement56([ + FieldElement56(fiat_p448_tight_field_element([ 144115188075855869, 144115188075855870, 144115188075855870, @@ -113,7 +127,7 @@ impl FieldElement56 { 144115188075855870, 144115188075855870, 144115188075855870, - ]) + ])) } } @@ -133,7 +147,7 @@ impl FieldElement56 { impl FieldElement56 { /// Helper function for internally constructing a field element pub(crate) const fn from_raw_slice(slice: [u64; 8]) -> FieldElement56 { - FieldElement56(slice) + FieldElement56(fiat_p448_tight_field_element(slice)) } /// This does not check if the encoding is canonical (ie if the input is reduced) @@ -156,16 +170,18 @@ impl FieldElement56 { impl FieldElement56 { /// Squares a field element pub(crate) fn square(&self) -> FieldElement56 { + let mut self_loose = fiat_p448_loose_field_element([0; 8]); + fiat_p448_relax(&mut self_loose, &self.0); let mut result = FieldElement56::zero(); - fiat_p448_carry_square(&mut result.0, &self.0); + fiat_p448_carry_square(&mut result.0, &self_loose); result } /// Negates a field element pub(crate) fn negate(&self) -> FieldElement56 { + let mut result_loose = fiat_p448_loose_field_element([0; 8]); + fiat_p448_opp(&mut result_loose, &self.0); let mut result = FieldElement56::zero(); - fiat_p448_opp(&mut result.0, &self.0); - let cloned = result.clone(); - fiat_p448_carry(&mut result.0, &cloned.0); + fiat_p448_carry(&mut result.0, &result_loose); result } @@ -173,23 +189,9 @@ impl FieldElement56 { /// This is used when checking equality between two field elements and /// when encoding a field element pub(crate) fn strong_reduce(&mut self) { - let cloned = self.clone(); // XXX: Cannot borrow mutably and immutably - fiat_p448_carry(&mut self.0, &cloned.0); - } - - /// Adds two field elements together - /// Result is not reduced - pub(crate) fn add_no_reduce(&self, rhs: &FieldElement56) -> FieldElement56 { - let mut result = FieldElement56::zero(); - fiat_p448_add(&mut result.0, &self.0, &rhs.0); - result - } - /// Subtracts the two field elements from each other - /// Result is not reduced - pub(crate) fn sub_no_reduce(&self, rhs: &FieldElement56) -> FieldElement56 { - let mut result = FieldElement56::zero(); - fiat_p448_sub(&mut result.0, &self.0, &rhs.0); - result + let mut self_loose = fiat_p448_loose_field_element([0; 8]); + fiat_p448_relax(&mut self_loose, &self.0); + fiat_p448_carry(&mut self.0, &self_loose); } }