From 00d8b6ea4f177a7dcf9ba06c8c08cc0e303e6fdf Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Wed, 13 Jun 2018 12:32:42 -0700 Subject: [PATCH] Change `negate_D`, `negate_D_lazy` to `impl Neg`, `negate_lazy` --- src/backend/avx2/edwards.rs | 9 ++-- src/backend/avx2/field.rs | 101 +++++++++++++----------------------- 2 files changed, 40 insertions(+), 70 deletions(-) diff --git a/src/backend/avx2/edwards.rs b/src/backend/avx2/edwards.rs index be154dd..73db3db 100644 --- a/src/backend/avx2/edwards.rs +++ b/src/backend/avx2/edwards.rs @@ -176,7 +176,7 @@ impl From for CachedPoint { x.scale_by_curve_constants(); // x = (121666*S2 121666*S3 2*121666*Z2 -2*121665*T2) - x.negate_D(); + x = x.blend(-x, Lanes::D); CachedPoint(x) } @@ -210,10 +210,9 @@ impl<'a> Neg for &'a CachedPoint { type Output = CachedPoint; fn neg(self) -> CachedPoint { - let mut neg = *self; - neg.0.swap_AB(); - neg.0.negate_D_lazy(); - neg + let mut coords = self.0; + coords.swap_AB(); + CachedPoint(coords.blend(coords.negate_lazy(), Lanes::D)) } } diff --git a/src/backend/avx2/field.rs b/src/backend/avx2/field.rs index d5ac6a8..c7ee80b 100644 --- a/src/backend/avx2/field.rs +++ b/src/backend/avx2/field.rs @@ -24,7 +24,7 @@ pub const D_LANES64: u8 = 0b11_00_00_00; pub const ALL_LANES: u8 = A_LANES | B_LANES | C_LANES | D_LANES; -use core::ops::{Add, Mul}; +use core::ops::{Add, Mul, Neg}; use core::simd::{i32x8, u32x8, u64x4, IntoBits}; use backend::avx2::constants::{P_TIMES_16_HI, P_TIMES_16_LO, P_TIMES_2_HI, P_TIMES_2_LO}; @@ -195,73 +195,20 @@ impl FieldElement32x4 { return out; } - /// Negate the \\(D\\) variable of \\((A,B,C,D)\\). + /// Given \\((A,B,C,D)\\), compute \\((-A,-B,-C,-D)\\), without + /// performing a reduction. /// /// Input limbs must be less than the limbs of \\(2p\\), i.e., freshly reduced. - pub fn negate_D_lazy(&mut self) { - unsafe { - use core::arch::x86_64::_mm256_blend_epi32; - self.0[0] = _mm256_blend_epi32( - self.0[0].into_bits(), - (P_TIMES_2_LO - self.0[0]).into_bits(), - D_LANES as i32, - ).into_bits(); - self.0[1] = _mm256_blend_epi32( - self.0[1].into_bits(), - (P_TIMES_2_HI - self.0[1]).into_bits(), - D_LANES as i32, - ).into_bits(); - self.0[2] = _mm256_blend_epi32( - self.0[2].into_bits(), - (P_TIMES_2_HI - self.0[2]).into_bits(), - D_LANES as i32, - ).into_bits(); - self.0[3] = _mm256_blend_epi32( - self.0[3].into_bits(), - (P_TIMES_2_HI - self.0[3]).into_bits(), - D_LANES as i32, - ).into_bits(); - self.0[4] = _mm256_blend_epi32( - self.0[4].into_bits(), - (P_TIMES_2_HI - self.0[4]).into_bits(), - D_LANES as i32, - ).into_bits(); - } - } - - /// Negate the \\(D\\) variable of \\((A,B,C,D)\\). /// - /// Input limbs must be less than the limbs of \\(2p\\), i.e., freshly reduced. - pub fn negate_D(&mut self) { - unsafe { - use core::arch::x86_64::_mm256_blend_epi32; - self.0[0] = _mm256_blend_epi32( - self.0[0].into_bits(), - (P_TIMES_16_LO - self.0[0]).into_bits(), - D_LANES as i32, - ).into_bits(); - self.0[1] = _mm256_blend_epi32( - self.0[1].into_bits(), - (P_TIMES_16_HI - self.0[1]).into_bits(), - D_LANES as i32, - ).into_bits(); - self.0[2] = _mm256_blend_epi32( - self.0[2].into_bits(), - (P_TIMES_16_HI - self.0[2]).into_bits(), - D_LANES as i32, - ).into_bits(); - self.0[3] = _mm256_blend_epi32( - self.0[3].into_bits(), - (P_TIMES_16_HI - self.0[3]).into_bits(), - D_LANES as i32, - ).into_bits(); - self.0[4] = _mm256_blend_epi32( - self.0[4].into_bits(), - (P_TIMES_16_HI - self.0[4]).into_bits(), - D_LANES as i32, - ).into_bits(); - } - self.reduce32(); + /// The output limbs are bounded by \\(2p\\). + pub fn negate_lazy(&self) -> FieldElement32x4 { + FieldElement32x4([ + P_TIMES_2_LO - self.0[0], + P_TIMES_2_HI - self.0[1], + P_TIMES_2_HI - self.0[2], + P_TIMES_2_HI - self.0[3], + P_TIMES_2_HI - self.0[4], + ]) } /// Given `self = (A,B,C,D)`, set `self = (B,A,C,D)` @@ -639,6 +586,30 @@ impl FieldElement32x4 { } } +impl Neg for FieldElement32x4 { + type Output = FieldElement32x4; + + /// Given \\((A,B,C,D)\\), compute \\((-A,-B,-C,-D)\\), and + /// perform a reduction. + /// + /// The input limbs can be any size. + /// + /// The output limbs are freshly reduced. + #[inline] + fn neg(self) -> FieldElement32x4 { + let mut neg = FieldElement32x4([ + P_TIMES_16_LO - self.0[0], + P_TIMES_16_HI - self.0[1], + P_TIMES_16_HI - self.0[2], + P_TIMES_16_HI - self.0[3], + P_TIMES_16_HI - self.0[4], + ]); + neg.reduce32(); + + neg + } +} + impl Add for FieldElement32x4 { type Output = FieldElement32x4; #[inline]