Skip to content

Commit

Permalink
Remove SquareRootField, and move functionality to Field (#422)
Browse files Browse the repository at this point in the history
* Removed SquareRootField

* Merge cleanup

* Reverted changes to track master

* Added Tonelli-Shanks and Shanks sqrt algorithms for cubic extension fields

* Apply suggestions from code review

* WIP: Drafted square root algorithms for cubic extensions

* Small fix

* Remove old imports

Fix

* As a first step, use Tonelli-Shanks for cubic sqrt

* Expose attributes on CubicExtField

- `TWO_ADICITY`
- `TRACE_MINUS_ONE_DIV_TWO`
- `QUADRATIC_NONRESIDUE_TO_T`
needed to compute sqrt in cubic extensions

* re-introduce SQRT_PRECOMP

* Call `sqrt_impl` macro from FpConfig square_root

* Test sqrt on Fq6_3over2

should panic with `not implemented`

* sqrt on Fp3 should still work

* Mark SqrtPrecomputation enum as non-exhaustive

Likely to add more variants in the future

* Delegate sqrt precom definition to config

* Rename PRECOMP -> SQRT_PRECOMP

* Call `from_base_prime_field` instead

* Remove old code

* Add default impl of sqrt

* Delegate SQRT_PRECOMP to FpConfig

* Add comments and sort definitions

* Move `SQRT_PRECOMP` to `MontConfig`

* Remove `sqrt_impl` macro

* fmt

* Update CHANGELOG

Co-authored-by: Solomon <solomon.joseph@berkeley.edu>
Co-authored-by: Pratyush Mishra <pratyushmishra@berkeley.edu>
  • Loading branch information
3 people authored Jul 14, 2022
1 parent 7ae421f commit 6bf24dd
Show file tree
Hide file tree
Showing 27 changed files with 225 additions and 250 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
- [\#408](https://github.com/arkworks-rs/algebra/pull/408) (`ark-ff`) Change the output of `Display` formatting for BigInt & Fp from hex to decimal.
- [\#412](https://github.com/arkworks-rs/algebra/pull/412) (`ark-poly`) Rename UV/MVPolynomial to DenseUV/MVPolynomial.
- [\#417](https://github.com/arkworks-rs/algebra/pull/417) (`ark-ff`) Remove `ToBytes` and `FromBytes`.
- [\#422](https://github.com/arkworks-rs/algebra/pull/422) (`ark-ff`) Remove `SquareRootField`, and move functionality to `Field`
- [\#425](https://github.com/arkworks-rs/algebra/pull/425) (`ark-ec`) Refactor `VariableBase` struct to `VariableBaseMSM` trait and implement it for `GroupProjective`.
- [\#438](https://github.com/arkworks-rs/algebra/pull/438) (`ark-ec`) Rename modules, structs, and traits related to `ec`.
- `short_weierstrass_jacobian``short_weierstrass`
Expand Down
2 changes: 1 addition & 1 deletion ec/src/hashing/curve_maps/swu/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::models::short_weierstrass::SWCurveConfig;
use ark_ff::{BigInteger, Field, One, PrimeField, SquareRootField, Zero};
use ark_ff::{BigInteger, Field, One, PrimeField, Zero};
use ark_std::string::ToString;
use core::marker::PhantomData;

Expand Down
7 changes: 3 additions & 4 deletions ec/src/hashing/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,10 @@ use crate::{
CurveConfig,
};
use ark_ff::{
biginteger::BigInteger64, field_hashers::DefaultFieldHasher, fields::Fp64, BigInt, MontBackend,
MontFp,
biginteger::BigInteger64, field_hashers::DefaultFieldHasher, fields::Fp64, BigInt, Field,
MontBackend, MontFp,
};

use ark_ff::SquareRootField;
use ark_std::vec::Vec;
use ark_test_curves::bls12_381::{Fq, Fq2, Fq6};
use hashbrown::HashMap;
Expand Down Expand Up @@ -119,7 +118,7 @@ fn test_field_division() {
/// Check that the hashing parameters are sane: zeta should be a non-square
#[test]
fn checking_the_hashing_parameters() {
assert!(!SquareRootField::legendre(&TestSWUMapToCurveParams::ZETA).is_qr());
assert!(!Field::legendre(&TestSWUMapToCurveParams::ZETA).is_qr());
}

/// The point of the test is to get a simple SWU compatible curve and make
Expand Down
12 changes: 6 additions & 6 deletions ec/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ extern crate derivative;
extern crate ark_std;

use ark_ff::{
fields::{Field, PrimeField, SquareRootField},
fields::{Field, PrimeField},
UniformRand,
};
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
Expand Down Expand Up @@ -50,7 +50,7 @@ pub mod wnaf;
/// how to compute a pairing over a pairing-friendly curve.
pub trait PairingEngine: Sized + 'static + Copy + Debug + Sync + Send + Eq + PartialEq {
/// This is the scalar field of the G1/G2 groups.
type Fr: PrimeField + SquareRootField;
type Fr: PrimeField;

/// The projective representation of an element in G1.
type G1Projective: ProjectiveCurve<BaseField = Self::Fq, ScalarField = Self::Fr, Affine = Self::G1Affine>
Expand Down Expand Up @@ -87,10 +87,10 @@ pub trait PairingEngine: Sized + 'static + Copy + Debug + Sync + Send + Eq + Par
type G2Prepared: Default + Clone + Send + Sync + Debug + From<Self::G2Affine>;

/// The base field that hosts G1.
type Fq: PrimeField + SquareRootField;
type Fq: PrimeField;

/// The extension field that hosts G2.
type Fqe: SquareRootField;
type Fqe: Field;

/// The extension field that hosts the target group of the pairing.
type Fqk: Field;
Expand Down Expand Up @@ -161,7 +161,7 @@ pub trait ProjectiveCurve:
+ From<<Self as ProjectiveCurve>::Affine>
{
type Config: CurveConfig<ScalarField = Self::ScalarField, BaseField = Self::BaseField>;
type ScalarField: PrimeField + SquareRootField;
type ScalarField: PrimeField;
type BaseField: Field;
type Affine: AffineCurve<
Config = Self::Config,
Expand Down Expand Up @@ -251,7 +251,7 @@ pub trait AffineCurve:

/// The group defined by this curve has order `h * r` where `r` is a large
/// prime. `Self::ScalarField` is the prime field defined by `r`
type ScalarField: PrimeField + SquareRootField + Into<<Self::ScalarField as PrimeField>::BigInt>;
type ScalarField: PrimeField + Into<<Self::ScalarField as PrimeField>::BigInt>;

/// The finite field over which this curve is defined.
type BaseField: Field;
Expand Down
4 changes: 2 additions & 2 deletions ec/src/models/bls12/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use ark_ff::fields::{
fp12_2over3over2::{Fp12, Fp12Config},
fp2::Fp2Config,
fp6_3over2::Fp6Config,
BitIteratorBE, Field, Fp2, PrimeField, SquareRootField,
BitIteratorBE, Field, Fp2, PrimeField,
};
use core::marker::PhantomData;
use num_traits::{One, Zero};
Expand All @@ -33,7 +33,7 @@ pub trait Bls12Parameters: 'static {
/// What kind of twist is this?
const TWIST_TYPE: TwistType;

type Fp: PrimeField + SquareRootField + Into<<Self::Fp as PrimeField>::BigInt>;
type Fp: PrimeField + Into<<Self::Fp as PrimeField>::BigInt>;
type Fp2Config: Fp2Config<Fp = Self::Fp>;
type Fp6Config: Fp6Config<Fp2Config = Self::Fp2Config>;
type Fp12Config: Fp12Config<Fp6Config = Self::Fp6Config>;
Expand Down
4 changes: 2 additions & 2 deletions ec/src/models/bn/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use ark_ff::fields::{
fp12_2over3over2::{Fp12, Fp12Config},
fp2::Fp2Config,
fp6_3over2::Fp6Config,
Field, Fp2, PrimeField, SquareRootField,
Field, Fp2, PrimeField,
};
use num_traits::One;

Expand All @@ -31,7 +31,7 @@ pub trait BnParameters: 'static {
const TWIST_TYPE: TwistType;
const TWIST_MUL_BY_Q_X: Fp2<Self::Fp2Config>;
const TWIST_MUL_BY_Q_Y: Fp2<Self::Fp2Config>;
type Fp: PrimeField + SquareRootField + Into<<Self::Fp as PrimeField>::BigInt>;
type Fp: PrimeField + Into<<Self::Fp as PrimeField>::BigInt>;
type Fp2Config: Fp2Config<Fp = Self::Fp>;
type Fp6Config: Fp6Config<Fp2Config = Self::Fp2Config>;
type Fp12Config: Fp12Config<Fp6Config = Self::Fp6Config>;
Expand Down
4 changes: 2 additions & 2 deletions ec/src/models/bw6/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{
use ark_ff::fields::{
fp3::Fp3Config,
fp6_2over3::{Fp6, Fp6Config},
BitIteratorBE, Field, PrimeField, SquareRootField,
BitIteratorBE, Field, PrimeField,
};
use num_traits::One;

Expand All @@ -24,7 +24,7 @@ pub trait BW6Parameters: 'static + Eq + PartialEq {
const ATE_LOOP_COUNT_2: &'static [i8];
const ATE_LOOP_COUNT_2_IS_NEGATIVE: bool;
const TWIST_TYPE: TwistType;
type Fp: PrimeField + SquareRootField + Into<<Self::Fp as PrimeField>::BigInt>;
type Fp: PrimeField + Into<<Self::Fp as PrimeField>::BigInt>;
type Fp3Config: Fp3Config<Fp = Self::Fp>;
type Fp6Config: Fp6Config<Fp3Config = Self::Fp3Config>;
type G1Parameters: SWCurveConfig<BaseField = Self::Fp>;
Expand Down
6 changes: 3 additions & 3 deletions ec/src/models/mnt4/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{
use ark_ff::{
fp2::{Fp2, Fp2Config},
fp4::{Fp4, Fp4Config},
BitIteratorBE, Field, PrimeField, SquareRootField,
BitIteratorBE, Field, PrimeField,
};
use num_traits::{One, Zero};

Expand All @@ -30,8 +30,8 @@ pub trait MNT4Parameters: 'static {
const FINAL_EXPONENT_LAST_CHUNK_1: <Self::Fp as PrimeField>::BigInt;
const FINAL_EXPONENT_LAST_CHUNK_W0_IS_NEG: bool;
const FINAL_EXPONENT_LAST_CHUNK_ABS_OF_W0: <Self::Fp as PrimeField>::BigInt;
type Fp: PrimeField + SquareRootField + Into<<Self::Fp as PrimeField>::BigInt>;
type Fr: PrimeField + SquareRootField + Into<<Self::Fr as PrimeField>::BigInt>;
type Fp: PrimeField + Into<<Self::Fp as PrimeField>::BigInt>;
type Fr: PrimeField + Into<<Self::Fr as PrimeField>::BigInt>;
type Fp2Config: Fp2Config<Fp = Self::Fp>;
type Fp4Config: Fp4Config<Fp2Config = Self::Fp2Config>;
type G1Parameters: SWCurveConfig<BaseField = Self::Fp, ScalarField = Self::Fr>;
Expand Down
6 changes: 3 additions & 3 deletions ec/src/models/mnt6/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{
use ark_ff::{
fp3::{Fp3, Fp3Config},
fp6_2over3::{Fp6, Fp6Config},
BitIteratorBE, Field, PrimeField, SquareRootField,
BitIteratorBE, Field, PrimeField,
};
use num_traits::{One, Zero};

Expand All @@ -30,8 +30,8 @@ pub trait MNT6Parameters: 'static {
const FINAL_EXPONENT_LAST_CHUNK_1: <Self::Fp as PrimeField>::BigInt;
const FINAL_EXPONENT_LAST_CHUNK_W0_IS_NEG: bool;
const FINAL_EXPONENT_LAST_CHUNK_ABS_OF_W0: <Self::Fp as PrimeField>::BigInt;
type Fp: PrimeField + SquareRootField + Into<<Self::Fp as PrimeField>::BigInt>;
type Fr: PrimeField + SquareRootField + Into<<Self::Fr as PrimeField>::BigInt>;
type Fp: PrimeField + Into<<Self::Fp as PrimeField>::BigInt>;
type Fr: PrimeField + Into<<Self::Fr as PrimeField>::BigInt>;
type Fp3Config: Fp3Config<Fp = Self::Fp>;
type Fp6Config: Fp6Config<Fp3Config = Self::Fp3Config>;
type G1Parameters: SWCurveConfig<BaseField = Self::Fp, ScalarField = Self::Fr>;
Expand Down
6 changes: 3 additions & 3 deletions ec/src/models/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use ark_ff::{Field, PrimeField, SquareRootField};
use ark_ff::{Field, PrimeField};

pub mod bls12;
pub mod bn;
Expand All @@ -16,10 +16,10 @@ pub mod twisted_edwards;
/// prime-order subgroup of the curve.
pub trait CurveConfig: Send + Sync + Sized + 'static {
/// Base field that the curve is defined over.
type BaseField: Field + SquareRootField;
type BaseField: Field;
/// Finite prime field corresponding to an appropriate prime-order subgroup
/// of the curve group.
type ScalarField: PrimeField + SquareRootField + Into<<Self::ScalarField as PrimeField>::BigInt>;
type ScalarField: PrimeField + Into<<Self::ScalarField as PrimeField>::BigInt>;

const COFACTOR: &'static [u64];
const COFACTOR_INV: Self::ScalarField;
Expand Down
2 changes: 1 addition & 1 deletion ec/src/models/short_weierstrass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use ark_std::{
};

use ark_ff::{
fields::{Field, PrimeField, SquareRootField},
fields::{Field, PrimeField},
ToConstraintField, UniformRand,
};

Expand Down
2 changes: 1 addition & 1 deletion ec/src/models/twisted_edwards.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use num_traits::{One, Zero};
use zeroize::Zeroize;

use ark_ff::{
fields::{Field, PrimeField, SquareRootField},
fields::{Field, PrimeField},
ToConstraintField, UniformRand,
};

Expand Down
63 changes: 0 additions & 63 deletions ff/src/fields/arithmetic.rs
Original file line number Diff line number Diff line change
@@ -1,66 +1,3 @@
macro_rules! sqrt_impl {
($Self:ident, $P:tt, $self:expr) => {{
// https://eprint.iacr.org/2012/685.pdf (page 12, algorithm 5)
// Actually this is just normal Tonelli-Shanks; since `P::Generator`
// is a quadratic non-residue, `P::ROOT_OF_UNITY = P::GENERATOR ^ t`
// is also a quadratic non-residue (since `t` is odd).
if $self.is_zero() {
return Some($Self::zero());
}
// Try computing the square root (x at the end of the algorithm)
// Check at the end of the algorithm if x was a square root
// Begin Tonelli-Shanks
let mut z = $Self::qnr_to_t();
let mut w = $self.pow($P::TRACE_MINUS_ONE_DIV_TWO);
let mut x = w * $self;
let mut b = x * &w;

let mut v = $P::TWO_ADICITY as usize;

while !b.is_one() {
let mut k = 0usize;

let mut b2k = b;
while !b2k.is_one() {
// invariant: b2k = b^(2^k) after entering this loop
b2k.square_in_place();
k += 1;
}

if k == ($P::TWO_ADICITY as usize) {
// We are in the case where self^(T * 2^k) = x^(P::MODULUS - 1) = 1,
// which means that no square root exists.
return None;
}
let j = v - k;
w = z;
for _ in 1..j {
w.square_in_place();
}

z = w.square();
b *= &z;
x *= &w;
v = k;
}
// Is x the square root? If so, return it.
if (x.square() == *$self) {
return Some(x);
} else {
// Consistency check that if no square root is found,
// it is because none exists.
#[cfg(debug_assertions)]
{
use crate::fields::LegendreSymbol::*;
if ($self.legendre() != QuadraticNonResidue) {
panic!("Input has a square root per its legendre symbol, but it was not found")
}
}
None
}
}};
}

// Implements AddAssign on Self by deferring to an implementation on &Self
#[macro_export]
macro_rules! impl_additive_ops_from_ref {
Expand Down
Loading

0 comments on commit 6bf24dd

Please sign in to comment.