Remove deterministic square root calculation as it's no longer needed.

This commit is contained in:
Sean Bowe 2020-12-24 12:32:43 -07:00
parent 98c1d80c90
commit f308eb969c
No known key found for this signature in database
GPG Key ID: 95684257D8F8B031
4 changed files with 0 additions and 129 deletions

View File

@ -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<Self> {
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 {

View File

@ -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);
}

View File

@ -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!(

View File

@ -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!(