ff: Remove frobenius_map from Field trait

It is only used internally in the bls12_381 crate, and field extensions
aren't exposed anywhere in the Zcash stack.
This commit is contained in:
Jack Grigg 2020-05-01 14:01:43 +12:00
parent 1761ebfb35
commit 55568b4d6e
10 changed files with 23 additions and 73 deletions

View File

@ -214,10 +214,6 @@ impl Field for Fr {
}
}
fn frobenius_map(&mut self, _: usize) {
// identity
}
fn sqrt(&self) -> CtOption<Self> {
// Tonelli-Shank's algorithm for q mod 16 = 1
// https://eprint.iacr.org/2012/685.pdf (page 12, algorithm 5)

View File

@ -1266,11 +1266,6 @@ fn prime_field_impl(
#invert_impl
}
#[inline(always)]
fn frobenius_map(&mut self, _: usize) {
// This has no effect in a prime field.
}
#[inline]
fn square(&self) -> Self
{

View File

@ -72,10 +72,6 @@ pub trait Field:
/// failing if the element is zero.
fn invert(&self) -> CtOption<Self>;
/// Exponentiates this element by a power of the base prime modulus via
/// the Frobenius automorphism.
fn frobenius_map(&mut self, power: usize);
/// Returns the square root of the field element, if it is
/// quadratic residue.
fn sqrt(&self) -> CtOption<Self>;

View File

@ -1865,7 +1865,6 @@ fn test_fq_root_of_unity() {
fn fq_field_tests() {
crate::tests::field::random_field_tests::<Fq>();
crate::tests::field::random_sqrt_tests::<Fq>();
crate::tests::field::random_frobenius_tests::<Fq, _>(Fq::char(), 13);
crate::tests::field::from_str_tests::<Fq>();
}

View File

@ -39,6 +39,15 @@ impl Fq12 {
self.c0.mul_by_nonresidue();
self.c0.add_assign(&aa);
}
pub fn frobenius_map(&mut self, power: usize) {
self.c0.frobenius_map(power);
self.c1.frobenius_map(power);
self.c1.c0.mul_assign(&FROBENIUS_COEFF_FQ12_C1[power % 12]);
self.c1.c1.mul_assign(&FROBENIUS_COEFF_FQ12_C1[power % 12]);
self.c1.c2.mul_assign(&FROBENIUS_COEFF_FQ12_C1[power % 12]);
}
}
impl ConditionallySelectable for Fq12 {
@ -200,15 +209,6 @@ impl Field for Fq12 {
}
}
fn frobenius_map(&mut self, power: usize) {
self.c0.frobenius_map(power);
self.c1.frobenius_map(power);
self.c1.c0.mul_assign(&FROBENIUS_COEFF_FQ12_C1[power % 12]);
self.c1.c1.mul_assign(&FROBENIUS_COEFF_FQ12_C1[power % 12]);
self.c1.c2.mul_assign(&FROBENIUS_COEFF_FQ12_C1[power % 12]);
}
fn square(&self) -> Self {
let mut ab = self.c0;
ab.mul_assign(&self.c1);
@ -282,8 +282,5 @@ fn test_fq12_mul_by_014() {
#[test]
fn fq12_field_tests() {
use ff::PrimeField;
crate::tests::field::random_field_tests::<Fq12>();
crate::tests::field::random_frobenius_tests::<Fq12, _>(super::fq::Fq::char(), 13);
}

View File

@ -53,6 +53,10 @@ impl Fq2 {
t1
}
pub fn frobenius_map(&mut self, power: usize) {
self.c1.mul_assign(&FROBENIUS_COEFF_FQ2_C1[power % 2]);
}
}
impl ConditionallySelectable for Fq2 {
@ -238,10 +242,6 @@ impl Field for Fq2 {
})
}
fn frobenius_map(&mut self, power: usize) {
self.c1.mul_assign(&FROBENIUS_COEFF_FQ2_C1[power % 2]);
}
/// WARNING: THIS IS NOT ACTUALLY CONSTANT TIME YET!
/// THIS WILL BE REPLACED BY THE bls12_381 CRATE, WHICH IS CONSTANT TIME!
fn sqrt(&self) -> CtOption<Self> {
@ -920,9 +920,6 @@ fn test_fq2_mul_nonresidue() {
#[test]
fn fq2_field_tests() {
use ff::PrimeField;
crate::tests::field::random_field_tests::<Fq2>();
crate::tests::field::random_sqrt_tests::<Fq2>();
crate::tests::field::random_frobenius_tests::<Fq2, _>(super::fq::Fq::char(), 13);
}

View File

@ -99,6 +99,15 @@ impl Fq6 {
self.c1 = t2;
self.c2 = t3;
}
pub fn frobenius_map(&mut self, power: usize) {
self.c0.frobenius_map(power);
self.c1.frobenius_map(power);
self.c2.frobenius_map(power);
self.c1.mul_assign(&FROBENIUS_COEFF_FQ6_C1[power % 6]);
self.c2.mul_assign(&FROBENIUS_COEFF_FQ6_C2[power % 6]);
}
}
impl ConditionallySelectable for Fq6 {
@ -305,15 +314,6 @@ impl Field for Fq6 {
}
}
fn frobenius_map(&mut self, power: usize) {
self.c0.frobenius_map(power);
self.c1.frobenius_map(power);
self.c2.frobenius_map(power);
self.c1.mul_assign(&FROBENIUS_COEFF_FQ6_C1[power % 6]);
self.c2.mul_assign(&FROBENIUS_COEFF_FQ6_C2[power % 6]);
}
fn square(&self) -> Self {
let s0 = self.c0.square();
let mut ab = self.c0;
@ -474,8 +474,5 @@ fn test_fq6_mul_by_01() {
#[test]
fn fq6_field_tests() {
use ff::PrimeField;
crate::tests::field::random_field_tests::<Fq6>();
crate::tests::field::random_frobenius_tests::<Fq6, _>(super::fq::Fq::char(), 13);
}

View File

@ -645,7 +645,6 @@ fn test_fr_root_of_unity() {
fn fr_field_tests() {
crate::tests::field::random_field_tests::<Fr>();
crate::tests::field::random_sqrt_tests::<Fr>();
crate::tests::field::random_frobenius_tests::<Fr, _>(Fr::char(), 13);
crate::tests::field::from_str_tests::<Fr>();
}

View File

@ -1,28 +1,7 @@
use ff::{Field, PowVartime, PrimeField};
use ff::{Field, PrimeField};
use rand_core::{RngCore, SeedableRng};
use rand_xorshift::XorShiftRng;
pub fn random_frobenius_tests<F: Field, C: AsRef<[u8]>>(characteristic: C, maxpower: usize) {
let mut rng = XorShiftRng::from_seed([
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,
0xe5,
]);
for _ in 0..100 {
for i in 0..=maxpower {
let mut a = F::random(&mut rng);
let mut b = a;
for _ in 0..i {
a = a.pow_vartime(&characteristic);
}
b.frobenius_map(i);
assert_eq!(a, b);
}
}
}
pub fn random_sqrt_tests<F: Field>() {
let mut rng = XorShiftRng::from_seed([
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,

View File

@ -499,11 +499,6 @@ impl Field for Fs {
CtOption::new(inverse, Choice::from(if self.is_zero() { 0 } else { 1 }))
}
#[inline(always)]
fn frobenius_map(&mut self, _: usize) {
// This has no effect in a prime field.
}
#[inline]
fn square(&self) -> Self {
let mut carry = 0;