mirror of https://github.com/zcash/halo2.git
Remove deterministic square root calculation as it's no longer needed.
This commit is contained in:
parent
98c1d80c90
commit
f308eb969c
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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!(
|
||||
|
|
|
@ -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!(
|
||||
|
|
Loading…
Reference in New Issue