mirror of
https://github.com/saymrwulf/pasta_curves-source.git
synced 2026-09-06 20:20:34 +00:00
Remove deterministic square root calculation as it's no longer needed.
This commit is contained in:
parent
98c1d80c90
commit
f308eb969c
4 changed files with 0 additions and 129 deletions
|
|
@ -16,15 +16,6 @@ pub trait FieldExt:
|
||||||
/// Inverse of `ROOT_OF_UNITY`
|
/// Inverse of `ROOT_OF_UNITY`
|
||||||
const ROOT_OF_UNITY_INV: Self;
|
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
|
/// Generator of the $t-order$ multiplicative subgroup
|
||||||
const DELTA: Self;
|
const DELTA: Self;
|
||||||
|
|
||||||
|
|
@ -67,68 +58,6 @@ pub trait FieldExt:
|
||||||
/// byte representation of an integer.
|
/// byte representation of an integer.
|
||||||
fn from_bytes_wide(bytes: &[u8; 64]) -> Self;
|
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
|
/// Exponentiates `self` by `by`, where `by` is a little-endian order
|
||||||
/// integer exponent.
|
/// integer exponent.
|
||||||
fn pow(&self, by: &[u64; 4]) -> Self {
|
fn pow(&self, by: &[u64; 4]) -> Self {
|
||||||
|
|
|
||||||
|
|
@ -6,21 +6,3 @@ mod fq;
|
||||||
|
|
||||||
pub use fp::*;
|
pub use fp::*;
|
||||||
pub use fq::*;
|
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,
|
0xb4ed8e647196dad1,
|
||||||
0x2cd5282c53116b5c,
|
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 DELTA: Self = DELTA;
|
||||||
const UNROLL_S_EXPONENT: u64 = 0x204ace5;
|
|
||||||
const TWO_INV: Self = Fp::from_raw([
|
const TWO_INV: Self = Fp::from_raw([
|
||||||
0xcc96987680000001,
|
0xcc96987680000001,
|
||||||
0x11234c7e04a67c8d,
|
0x11234c7e04a67c8d,
|
||||||
|
|
@ -791,13 +778,6 @@ fn test_sqrt() {
|
||||||
assert!(v == Fp::TWO_INV || (-v) == Fp::TWO_INV);
|
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]
|
#[test]
|
||||||
fn test_zeta() {
|
fn test_zeta() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|
|
||||||
|
|
@ -643,20 +643,7 @@ impl FieldExt for Fq {
|
||||||
0xf4c8f353124086c1,
|
0xf4c8f353124086c1,
|
||||||
0x2235e1a7415bf936,
|
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 DELTA: Self = DELTA;
|
||||||
const UNROLL_S_EXPONENT: u64 = 0xd1d858e1;
|
|
||||||
const TWO_INV: Self = Fq::from_raw([
|
const TWO_INV: Self = Fq::from_raw([
|
||||||
0xc623759080000001,
|
0xc623759080000001,
|
||||||
0x11234c7e04ca546e,
|
0x11234c7e04ca546e,
|
||||||
|
|
@ -791,13 +778,6 @@ fn test_sqrt() {
|
||||||
assert!(v == Fq::TWO_INV || (-v) == Fq::TWO_INV);
|
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]
|
#[test]
|
||||||
fn test_zeta() {
|
fn test_zeta() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue