Skip to content

Commit

Permalink
Add PrimeField::{ROOT_OF_UNITY_INV, DELTA}
Browse files Browse the repository at this point in the history
  • Loading branch information
str4d committed Nov 24, 2022
1 parent 9c30ad3 commit 93537e2
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 3 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ and this library adheres to Rust's notion of
- `ff::Field::{sqrt_ratio, sqrt_alt}`
- `core::iter::{Sum, Product}` bounds on `ff::Field`
- `ff::PrimeField::TWO_INV`
- `ff::PrimeField::{MULTIPLICATIVE_GENERATOR, ROOT_OF_UNITY}`
- Constants related to multiplicative generators:
- `ff::PrimeField::MULTIPLICATIVE_GENERATOR`
- `ff::PrimeField::{ROOT_OF_UNITY, ROOT_OF_UNITY_INV}`
- `ff::PrimeField::DELTA`
- `ff::helpers`:
- `sqrt_tonelli_shanks`
- `sqrt_ratio_generic`
Expand Down
18 changes: 17 additions & 1 deletion ff_derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,13 @@ fn prime_field_constants_and_sqrt(
}

// Compute 2^s root of unity given the generator
let root_of_unity = biguint_to_u64_vec(to_mont(exp(generator.clone(), &t, &modulus)), limbs);
let root_of_unity = exp(generator.clone(), &t, &modulus);
let root_of_unity_inv = biguint_to_u64_vec(to_mont(invert(root_of_unity.clone())), limbs);
let root_of_unity = biguint_to_u64_vec(to_mont(root_of_unity), limbs);
let delta = biguint_to_u64_vec(
to_mont(exp(generator.clone(), &(BigUint::one() << s), &modulus)),
limbs,
);
let generator = biguint_to_u64_vec(to_mont(generator), limbs);

let sqrt_impl =
Expand Down Expand Up @@ -637,6 +643,12 @@ fn prime_field_constants_and_sqrt(

/// 2^s root of unity computed by GENERATOR^t
const ROOT_OF_UNITY: #name = #name(#root_of_unity);

/// (2^s)^{-1} mod m
const ROOT_OF_UNITY_INV: #name = #name(#root_of_unity_inv);

/// GENERATOR^{2^s}
const DELTA: #name = #name(#delta);
},
sqrt_impl,
)
Expand Down Expand Up @@ -1236,6 +1248,10 @@ fn prime_field_impl(
const S: u32 = S;

const ROOT_OF_UNITY: Self = ROOT_OF_UNITY;

const ROOT_OF_UNITY_INV: Self = ROOT_OF_UNITY_INV;

const DELTA: Self = DELTA;
}

#prime_field_bits_impl
Expand Down
11 changes: 10 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ pub trait PrimeField: Field + From<u64> {
/// It can be calculated using [SageMath] as `GF(modulus).primitive_element()`.
///
/// Implementations of this trait MUST ensure that this is the generator used to
/// derive `Self::root_of_unity`.
/// derive `Self::ROOT_OF_UNITY`.
///
/// [SageMath]: https://www.sagemath.org/
const MULTIPLICATIVE_GENERATOR: Self;
Expand All @@ -313,6 +313,15 @@ pub trait PrimeField: Field + From<u64> {
/// It can be calculated by exponentiating `Self::MULTIPLICATIVE_GENERATOR` by `t`,
/// where `t = (modulus - 1) >> Self::S`.
const ROOT_OF_UNITY: Self;

/// Inverse of [`Self::ROOT_OF_UNITY`].
const ROOT_OF_UNITY_INV: Self;

/// Generator of the `t-order` multiplicative subgroup.
///
/// It can be calculated by exponentiating [`Self::MULTIPLICATIVE_GENERATOR`] by `2^s`,
/// where `s` is [`Self::S`].
const DELTA: Self;
}

/// This represents the bits of an element of a prime field.
Expand Down
22 changes: 22 additions & 0 deletions tests/derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,28 @@ fn constants() {
Bls381K12Scalar::from(2) * Bls381K12Scalar::TWO_INV,
Bls381K12Scalar::ONE,
);

assert_eq!(
Bls381K12Scalar::ROOT_OF_UNITY * Bls381K12Scalar::ROOT_OF_UNITY_INV,
Bls381K12Scalar::ONE,
);

// ROOT_OF_UNITY^{2^s} mod m == 1
assert_eq!(
Bls381K12Scalar::ROOT_OF_UNITY.pow(&[1u64 << Bls381K12Scalar::S, 0, 0, 0]),
Bls381K12Scalar::ONE,
);

// DELTA^{t} mod m == 1
assert_eq!(
Bls381K12Scalar::DELTA.pow(&[
0xfffe5bfeffffffff,
0x09a1d80553bda402,
0x299d7d483339d808,
0x73eda753,
]),
Bls381K12Scalar::ONE,
);
}

#[test]
Expand Down

0 comments on commit 93537e2

Please sign in to comment.