Skip to content

Commit

Permalink
Adds fft checks for root of unity usage
Browse files Browse the repository at this point in the history
  • Loading branch information
howardwu committed Jun 26, 2021
1 parent a9de593 commit d40d954
Show file tree
Hide file tree
Showing 14 changed files with 314 additions and 58 deletions.
19 changes: 13 additions & 6 deletions curves/src/bls12_377/fr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ use snarkvm_utilities::biginteger::BigInteger256 as BigInteger;
/// o = q - 1
/// F = GF(q)
/// g = F.multiplicative_generator()
/// g = F.multiplicative_generator()
/// assert g.multiplicative_order() == o
/// g2 = g ** (o/2**s)
/// assert g2.multiplicative_order() == 2**s
Expand All @@ -49,12 +48,21 @@ impl FftParameters for FrParameters {

#[rustfmt::skip]
const TWO_ADICITY: u32 = 47;
/// TODO (howardwu): CRITICAL - Fix this after a migration plan has been determined.
/// - 0x3c3d3ca739381fb2,
/// - 0x9a14cda3ec99772b,
/// - 0xd7aacc7c59724826,
/// - 0xd1ba211c5cc349c,
/// + 12646347781564978760u64,
/// + 6783048705277173164u64,
/// + 268534165941069093u64,
/// + 1121515446318641358u64,
#[rustfmt::skip]
const TWO_ADIC_ROOT_OF_UNITY: BigInteger = BigInteger([
12646347781564978760u64,
6783048705277173164u64,
268534165941069093u64,
1121515446318641358u64,
0x3c3d3ca739381fb2,
0x9a14cda3ec99772b,
0xd7aacc7c59724826,
0xd1ba211c5cc349c,
]);
}

Expand All @@ -65,7 +73,6 @@ impl FieldParameters for FrParameters {
/// Encoded in Montgomery form, so the value is
/// (22 * R) % q = 5642976643016801619665363617888466827793962762719196659561577942948671127251
#[rustfmt::skip]
#[rustfmt::skip]
const GENERATOR: BigInteger = BigInteger([
2984901390528151251u64,
10561528701063790279u64,
Expand Down
7 changes: 5 additions & 2 deletions curves/src/bls12_377/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -397,9 +397,12 @@ fn test_fq_root_of_unity() {
0xe9185f1443ab18ec,
0x6b8
]),
Fq::root_of_unity()
Fq::two_adic_root_of_unity()
);
assert_eq!(
Fq::two_adic_root_of_unity().pow([1 << FqParameters::TWO_ADICITY]),
Fq::one()
);
assert_eq!(Fq::root_of_unity().pow([1 << FqParameters::TWO_ADICITY]), Fq::one());
assert!(Fq::multiplicative_generator().sqrt().is_none());
}

Expand Down
14 changes: 12 additions & 2 deletions curves/src/edwards_bls12/fr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,17 @@ impl FieldParameters for FrParameters {
#[rustfmt::skip]
const REPR_SHAVE_BITS: u32 = 5;
#[rustfmt::skip]
const T: BigInteger = BigInteger([0x0, 0x0, 0x0, 0x0]);
const T: BigInteger = BigInteger([
6678124996694371583,
2975139753996731775,
14706092969812227584,
168160046336021674
]);
#[rustfmt::skip]
const T_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([0x0, 0x0, 0x0, 0x0]);
const T_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
12562434535201961599,
1487569876998365887,
7353046484906113792,
84080023168010837
]);
}
18 changes: 16 additions & 2 deletions curves/src/edwards_sw6/fr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,21 @@ impl FieldParameters for FrParameters {
#[rustfmt::skip]
const REPR_SHAVE_BITS: u32 = 10;
#[rustfmt::skip]
const T: BigInteger = BigInteger([0x0, 0x0, 0x0, 0x0, 0x0, 0x0]);
const T: BigInteger = BigInteger([
5782852926996632741,
10160572951715783904,
8680081325396045328,
15623293663189641372,
6210983053257673289,
3784322272077959
]);
#[rustfmt::skip]
const T_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([0x0, 0x0, 0x0, 0x0, 0x0, 0x0]);
const T_MINUS_ONE_DIV_TWO: BigInteger = BigInteger([
2891426463498316370,
5080286475857891952,
4340040662698022664,
17035018868449596494,
12328863563483612452,
1892161136038979
]);
}
2 changes: 1 addition & 1 deletion fields/src/fp3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ impl<P: Fp3Parameters> Fp3<P> {

// Returns the value of QNR^T.
#[inline]
pub fn qnr_to_t() -> Self {
pub fn two_adic_root_of_unity() -> Self {
Self::new(
P::QUADRATIC_NONRESIDUE_TO_T.0,
P::QUADRATIC_NONRESIDUE_TO_T.1,
Expand Down
5 changes: 0 additions & 5 deletions fields/src/fp_256.rs
Original file line number Diff line number Diff line change
Expand Up @@ -329,11 +329,6 @@ impl<P: Fp256Parameters> PrimeField for Fp256<P> {
let r = *self;
r.0
}

#[inline]
fn root_of_unity() -> Self {
Fp256::<P>(P::TWO_ADIC_ROOT_OF_UNITY, PhantomData)
}
}

impl<P: Fp256Parameters> FftField for Fp256<P> {
Expand Down
5 changes: 0 additions & 5 deletions fields/src/fp_320.rs
Original file line number Diff line number Diff line change
Expand Up @@ -365,11 +365,6 @@ impl<P: Fp320Parameters> PrimeField for Fp320<P> {
let r = *self;
r.0
}

#[inline]
fn root_of_unity() -> Self {
Fp320::<P>(P::TWO_ADIC_ROOT_OF_UNITY, PhantomData)
}
}

impl<P: Fp320Parameters> FftField for Fp320<P> {
Expand Down
5 changes: 0 additions & 5 deletions fields/src/fp_384.rs
Original file line number Diff line number Diff line change
Expand Up @@ -395,11 +395,6 @@ impl<P: Fp384Parameters> PrimeField for Fp384<P> {
fn into_repr_raw(&self) -> BigInteger {
self.0
}

#[inline]
fn root_of_unity() -> Self {
Fp384::<P>(P::TWO_ADIC_ROOT_OF_UNITY, PhantomData)
}
}

impl<P: Fp384Parameters> FftField for Fp384<P> {
Expand Down
5 changes: 0 additions & 5 deletions fields/src/fp_768.rs
Original file line number Diff line number Diff line change
Expand Up @@ -709,11 +709,6 @@ impl<P: Fp768Parameters> PrimeField for Fp768<P> {
r.0
}

#[inline]
fn root_of_unity() -> Self {
Fp768::<P>(P::TWO_ADIC_ROOT_OF_UNITY, PhantomData)
}

#[inline]
fn size_in_bits() -> usize {
P::MODULUS_BITS as usize
Expand Down
5 changes: 0 additions & 5 deletions fields/src/fp_832.rs
Original file line number Diff line number Diff line change
Expand Up @@ -678,11 +678,6 @@ impl<P: Fp832Parameters> PrimeField for Fp832<P> {
r.0
}

#[inline]
fn root_of_unity() -> Self {
Fp832::<P>(P::TWO_ADIC_ROOT_OF_UNITY, PhantomData)
}

#[inline]
fn size_in_bits() -> usize {
P::MODULUS_BITS as usize
Expand Down
2 changes: 1 addition & 1 deletion fields/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ macro_rules! sqrt_impl {
Zero => Some(*$self),
QuadraticNonResidue => None,
QuadraticResidue => {
let mut z = $Self::qnr_to_t();
let mut z = $Self::two_adic_root_of_unity();
let mut w = $self.pow($P::T_MINUS_ONE_DIV_TWO);
let mut x = w * $self;
let mut b = x * w;
Expand Down
38 changes: 37 additions & 1 deletion fields/src/tests_field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with the snarkVM library. If not, see <https://www.gnu.org/licenses/>.

use crate::{Field, LegendreSymbol, PrimeField, SquareRootField};
use crate::{traits::FftParameters, FftField, Field, LegendreSymbol, PrimeField, SquareRootField};
use snarkvm_utilities::{
io::Cursor,
serialize::{CanonicalDeserialize, CanonicalSerialize, Flags, SWFlags},
Expand Down Expand Up @@ -334,10 +334,46 @@ pub fn field_test<F: Field>(a: F, b: F) {
random_field_tests::<F>();
}

pub fn fft_field_test<F: PrimeField + FftField>() {
let modulus_minus_one_div_two = F::from_repr(F::modulus_minus_one_div_two()).unwrap();
assert!(!modulus_minus_one_div_two.is_zero());

// modulus - 1 == 2^s * t
// => t == (modulus - 1) / 2^s
// => t == [(modulus - 1) / 2] * [1 / 2^(s-1)]
let two_adicity = F::FftParameters::TWO_ADICITY;
assert!(two_adicity > 0);
let two_s_minus_one = F::from(2_u32).pow(&[(two_adicity - 1) as u64]);
let trace = modulus_minus_one_div_two * two_s_minus_one.inverse().unwrap();
assert_eq!(trace, F::from_repr(F::trace()).unwrap());

// (trace - 1) / 2 == trace_minus_one_div_two
let trace_minus_one_div_two = F::from_repr(F::trace_minus_one_div_two()).unwrap();
assert!(!trace_minus_one_div_two.is_zero());
assert_eq!((trace - F::one()) / F::one().double(), trace_minus_one_div_two);

// multiplicative_generator^trace == root of unity
let generator = F::multiplicative_generator();
assert!(!generator.is_zero());
let two_adic_root_of_unity = F::two_adic_root_of_unity();
assert!(!two_adic_root_of_unity.is_zero());
assert_eq!(two_adic_root_of_unity.pow([1 << two_adicity]), F::one());
// TODO (howardwu): CRITICAL - Reenable this after BLS12-377 Fr root_of_unity has been fixed.
// assert_eq!(generator.pow(trace.into_repr().as_ref()), two_adic_root_of_unity);
}

pub fn primefield_test<F: PrimeField>() {
let one = F::one();
assert_eq!(F::from_repr(one.into_repr()).unwrap(), one);
assert_eq!(F::from_str("1").ok().unwrap(), one);
assert_eq!(F::from_str(&one.to_string()).ok().unwrap(), one);

let two = F::one().double();
assert_eq!(F::from_repr(two.into_repr()).unwrap(), two);
assert_eq!(F::from_str("2").ok().unwrap(), two);
assert_eq!(F::from_str(&two.to_string()).ok().unwrap(), two);

fft_field_test::<F>();
}

pub fn sqrt_field_test<F: SquareRootField>(elem: F) {
Expand Down
20 changes: 2 additions & 18 deletions fields/src/traits/prime_field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,35 +37,19 @@ pub trait PrimeField: FftField<FftParameters = <Self as PrimeField>::Parameters>
/// Returns the underlying raw representation of the prime field element.
fn into_repr_raw(&self) -> Self::BigInteger;

/// Returns the 2^s root of unity.
fn root_of_unity() -> Self;

/// Return the a QNR^T
fn qnr_to_t() -> Self {
Self::root_of_unity()
}

/// Returns the field size in bits.
fn size_in_bits() -> usize {
Self::Parameters::MODULUS_BITS as usize
}

/// Returns the trace.
fn trace() -> Self::BigInteger {
// TODO (howardwu): This function has been disabled as
// `snarkvm_curves::edwards_bls12::Fr` and `snarkvm_curves::edwards_sw6::Fr`
// do NOT implement `FieldParameters::T` or `FieldParameters::T_MINUS_ONE_DIV_TWO`.
unimplemented!()
// Self::Parameters::T
Self::Parameters::T
}

/// Returns the trace minus one divided by two.
fn trace_minus_one_div_two() -> Self::BigInteger {
// TODO (howardwu): This function has been disabled as
// `snarkvm_curves::edwards_bls12::Fr` and `snarkvm_curves::edwards_sw6::Fr`
// do NOT implement `FieldParameters::T` or `FieldParameters::T_MINUS_ONE_DIV_TWO`.
unimplemented!()
// Self::Parameters::T_MINUS_ONE_DIV_TWO
Self::Parameters::T_MINUS_ONE_DIV_TWO
}

/// Returns the modulus minus one divided by two.
Expand Down
Loading

0 comments on commit d40d954

Please sign in to comment.