From f308eb969c4ceb089a4ace7ef66f2fb072650985 Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Thu, 24 Dec 2020 12:32:43 -0700 Subject: [PATCH] Remove deterministic square root calculation as it's no longer needed. --- src/arithmetic/fields.rs | 71 ---------------------------------------- src/pasta/fields.rs | 18 ---------- src/pasta/fields/fp.rs | 20 ----------- src/pasta/fields/fq.rs | 20 ----------- 4 files changed, 129 deletions(-) diff --git a/src/arithmetic/fields.rs b/src/arithmetic/fields.rs index 5c209f0..196e3ba 100644 --- a/src/arithmetic/fields.rs +++ b/src/arithmetic/fields.rs @@ -16,15 +16,6 @@ pub trait FieldExt: /// Inverse of `ROOT_OF_UNITY` const ROOT_OF_UNITY_INV: Self; - /// The value $(2^S)^{-1} \mod t$. - const UNROLL_T_EXPONENT: [u64; 4]; - - /// Represents $t$ where $2^S \cdot t = p - 1$ with $t$ odd. - const T_EXPONENT: [u64; 4]; - - /// The value $t^{-1} \mod 2^S$. - const UNROLL_S_EXPONENT: u64; - /// Generator of the $t-order$ multiplicative subgroup const DELTA: Self; @@ -67,68 +58,6 @@ pub trait FieldExt: /// byte representation of an integer. fn from_bytes_wide(bytes: &[u8; 64]) -> Self; - /// Returns a square root of this element, if it exists and this element is - /// nonzero. Always returns the same square root, and it is efficient to - /// check that it has done so using `extract_radix2_vartime`. - fn deterministic_sqrt(&self) -> Option { - let sqrt = self.sqrt(); - if bool::from(sqrt.is_none()) { - return None; - } - let sqrt = sqrt.unwrap(); - let extracted = sqrt.extract_radix2_vartime()?; - - if extracted.1 >> (Self::S - 1) == 1 { - Some(-sqrt) - } else { - Some(sqrt) - } - } - - /// Returns an element $a$ of multiplicative order $t$ together with an - /// integer `s` such that `self` is the square of $a \cdot \omega^{s}$ if - /// indeed `self` is a square. - fn extract_radix2_vartime(&self) -> Option<(Self, u64)> { - if bool::from(self.ct_is_zero()) { - return None; - } - - // TODO: these can probably be simplified - let t = self.pow_vartime(&[1 << Self::S, 0, 0, 0]); - let t = t.pow_vartime(&Self::UNROLL_T_EXPONENT); - let t = t.pow_vartime(&Self::UNROLL_T_EXPONENT); - let s = self.pow_vartime(&Self::T_EXPONENT); - let mut s = s.pow_vartime(&[Self::UNROLL_S_EXPONENT, 0, 0, 0]); - - let mut m = Self::S; - let mut c = Self::ROOT_OF_UNITY_INV; - - let mut extract: u64 = 0; - - let mut cur = 1; - while s != Self::one() { - let mut i = 1; - { - let mut s2i = s; - s2i = s2i.square(); - while s2i != Self::one() { - i += 1; - s2i = s2i.square(); - } - } - - for _ in 0..(m - i) { - c = c.square(); - cur <<= 1; - } - extract |= cur; - s *= c; - m = i; - } - - Some((t, extract)) - } - /// Exponentiates `self` by `by`, where `by` is a little-endian order /// integer exponent. fn pow(&self, by: &[u64; 4]) -> Self { diff --git a/src/pasta/fields.rs b/src/pasta/fields.rs index 5b0647d..e19389e 100644 --- a/src/pasta/fields.rs +++ b/src/pasta/fields.rs @@ -6,21 +6,3 @@ mod fq; pub use fp::*; pub use fq::*; - -#[cfg(test)] -use ff::{Field, PrimeField}; - -#[cfg(test)] -use crate::arithmetic::FieldExt; - -#[test] -fn test_extract() { - let a = Fq::rand(); - let a = a.square(); - let (t, s) = a.extract_radix2_vartime().unwrap(); - assert_eq!( - t.pow_vartime(&[1 << Fq::S, 0, 0, 0]) * Fq::ROOT_OF_UNITY.pow_vartime(&[s, 0, 0, 0]), - a - ); - assert_eq!(a.deterministic_sqrt().unwrap().square(), a); -} diff --git a/src/pasta/fields/fp.rs b/src/pasta/fields/fp.rs index 2cba5c3..c28182e 100644 --- a/src/pasta/fields/fp.rs +++ b/src/pasta/fields/fp.rs @@ -643,20 +643,7 @@ impl FieldExt for Fp { 0xb4ed8e647196dad1, 0x2cd5282c53116b5c, ]); - const UNROLL_T_EXPONENT: [u64; 4] = [ - 0x955a0a417453113c, - 0x0000000022016b89, - 0xc000000000000000, - 0x3f7ed4c6, - ]; - const T_EXPONENT: [u64; 4] = [ - 0x094cf91b992d30ed, - 0x00000000224698fc, - 0x0000000000000000, - 0x40000000, - ]; const DELTA: Self = DELTA; - const UNROLL_S_EXPONENT: u64 = 0x204ace5; const TWO_INV: Self = Fp::from_raw([ 0xcc96987680000001, 0x11234c7e04a67c8d, @@ -791,13 +778,6 @@ fn test_sqrt() { assert!(v == Fp::TWO_INV || (-v) == Fp::TWO_INV); } -#[test] -fn test_deterministic_sqrt() { - // NB: TWO_INV is standing in as a "random" field element - let v = (Fp::TWO_INV).square().deterministic_sqrt().unwrap(); - assert!(v == Fp::TWO_INV || (-v) == Fp::TWO_INV); -} - #[test] fn test_zeta() { assert_eq!( diff --git a/src/pasta/fields/fq.rs b/src/pasta/fields/fq.rs index 3ffbc32..6c3c989 100644 --- a/src/pasta/fields/fq.rs +++ b/src/pasta/fields/fq.rs @@ -643,20 +643,7 @@ impl FieldExt for Fq { 0xf4c8f353124086c1, 0x2235e1a7415bf936, ]); - const UNROLL_T_EXPONENT: [u64; 4] = [ - 0xcc771cc2ac1e1664, - 0x00000000062dfe9e, - 0xc000000000000000, - 0xb89e9c7, - ]; - const T_EXPONENT: [u64; 4] = [ - 0x0994a8dd8c46eb21, - 0x00000000224698fc, - 0x0000000000000000, - 0x40000000, - ]; const DELTA: Self = DELTA; - const UNROLL_S_EXPONENT: u64 = 0xd1d858e1; const TWO_INV: Self = Fq::from_raw([ 0xc623759080000001, 0x11234c7e04ca546e, @@ -791,13 +778,6 @@ fn test_sqrt() { assert!(v == Fq::TWO_INV || (-v) == Fq::TWO_INV); } -#[test] -fn test_deterministic_sqrt() { - // NB: TWO_INV is standing in as a "random" field element - let v = (Fq::TWO_INV).square().deterministic_sqrt().unwrap(); - assert!(v == Fq::TWO_INV || (-v) == Fq::TWO_INV); -} - #[test] fn test_zeta() { assert_eq!(