From 9211bcfed50c405381a3892e30010732ba60d138 Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Tue, 14 Dec 2021 17:12:14 +0100 Subject: [PATCH] Move characteristic to its own fn --- src/field/extension_field/quadratic.rs | 6 ++++-- src/field/extension_field/quartic.rs | 6 ++++-- src/field/field_types.rs | 17 +++++++++-------- src/field/goldilocks_field.rs | 6 ++++-- src/field/secp256k1_base.rs | 5 ++++- src/field/secp256k1_scalar.rs | 5 ++++- 6 files changed, 29 insertions(+), 16 deletions(-) diff --git a/src/field/extension_field/quadratic.rs b/src/field/extension_field/quadratic.rs index 16743f12..2243612e 100644 --- a/src/field/extension_field/quadratic.rs +++ b/src/field/extension_field/quadratic.rs @@ -59,8 +59,7 @@ impl> Field for QuadraticExtension { // long as `F::TWO_ADICITY >= 2`, `p` can be written as `4n + 1`, so `p + 1` can be written as // `2(2n + 1)`, which has a 2-adicity of 1. const TWO_ADICITY: usize = F::TWO_ADICITY + 1; - const CHARACTERISTIC_WITH_TWO_ADICITY: Option<(u64, usize)> = - F::CHARACTERISTIC_WITH_TWO_ADICITY; + const CHARACTERISTIC_TWO_ADICITY: usize = F::CHARACTERISTIC_TWO_ADICITY; const MULTIPLICATIVE_GROUP_GENERATOR: Self = Self(F::EXT_MULTIPLICATIVE_GROUP_GENERATOR); const POWER_OF_TWO_GENERATOR: Self = Self(F::EXT_POWER_OF_TWO_GENERATOR); @@ -70,6 +69,9 @@ impl> Field for QuadraticExtension { fn order() -> BigUint { F::order() * F::order() } + fn characteristic() -> BigUint { + F::characteristic() + } #[inline(always)] fn square(&self) -> Self { diff --git a/src/field/extension_field/quartic.rs b/src/field/extension_field/quartic.rs index 77329c94..781f79f5 100644 --- a/src/field/extension_field/quartic.rs +++ b/src/field/extension_field/quartic.rs @@ -61,8 +61,7 @@ impl> Field for QuarticExtension { // `2(2n + 1)`, which has a 2-adicity of 1. A similar argument can show that `p^2 + 1` also has // a 2-adicity of 1. const TWO_ADICITY: usize = F::TWO_ADICITY + 2; - const CHARACTERISTIC_WITH_TWO_ADICITY: Option<(u64, usize)> = - F::CHARACTERISTIC_WITH_TWO_ADICITY; + const CHARACTERISTIC_TWO_ADICITY: usize = F::CHARACTERISTIC_TWO_ADICITY; const MULTIPLICATIVE_GROUP_GENERATOR: Self = Self(F::EXT_MULTIPLICATIVE_GROUP_GENERATOR); const POWER_OF_TWO_GENERATOR: Self = Self(F::EXT_POWER_OF_TWO_GENERATOR); @@ -72,6 +71,9 @@ impl> Field for QuarticExtension { fn order() -> BigUint { F::order().pow(4u32) } + fn characteristic() -> BigUint { + F::characteristic() + } #[inline(always)] fn square(&self) -> Self { diff --git a/src/field/field_types.rs b/src/field/field_types.rs index cce96bec..f3d1c946 100644 --- a/src/field/field_types.rs +++ b/src/field/field_types.rs @@ -4,7 +4,7 @@ use std::iter::{Product, Sum}; use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; use num::bigint::BigUint; -use num::{Integer, One, Zero}; +use num::{Integer, One, ToPrimitive, Zero}; use rand::Rng; use serde::de::DeserializeOwned; use serde::Serialize; @@ -52,7 +52,7 @@ pub trait Field: /// The field's characteristic and it's 2-adicity. /// Set to `None` when the characteristic doesn't fit in a u64. - const CHARACTERISTIC_WITH_TWO_ADICITY: Option<(u64, usize)>; + const CHARACTERISTIC_TWO_ADICITY: usize; /// Generator of the entire multiplicative group, i.e. all non-zero elements. const MULTIPLICATIVE_GROUP_GENERATOR: Self; @@ -62,6 +62,7 @@ pub trait Field: const BITS: usize; fn order() -> BigUint; + fn characteristic() -> BigUint; #[inline] fn is_zero(&self) -> bool { @@ -204,24 +205,24 @@ pub trait Field: // exp exceeds t, we repeatedly multiply by 2^-t and reduce // exp until it's in the right range. - if let Some((p, two_adicity)) = Self::CHARACTERISTIC_WITH_TWO_ADICITY { + if let Some(p) = Self::characteristic().to_u64() { // NB: The only reason this is split into two cases is to save // the multiplication (and possible calculation of // inverse_2_pow_adicity) in the usual case that exp <= // TWO_ADICITY. Can remove the branch and simplify if that // saving isn't worth it. - if exp > two_adicity { + if exp > Self::CHARACTERISTIC_TWO_ADICITY { // NB: This should be a compile-time constant let inverse_2_pow_adicity: Self = - Self::from_canonical_u64(p - ((p - 1) >> two_adicity)); + Self::from_canonical_u64(p - ((p - 1) >> Self::CHARACTERISTIC_TWO_ADICITY)); let mut res = inverse_2_pow_adicity; - let mut e = exp - two_adicity; + let mut e = exp - Self::CHARACTERISTIC_TWO_ADICITY; - while e > two_adicity { + while e > Self::CHARACTERISTIC_TWO_ADICITY { res *= inverse_2_pow_adicity; - e -= two_adicity; + e -= Self::CHARACTERISTIC_TWO_ADICITY; } res * Self::from_canonical_u64(p - ((p - 1) >> e)) } else { diff --git a/src/field/goldilocks_field.rs b/src/field/goldilocks_field.rs index 14c0a281..d963fb9e 100644 --- a/src/field/goldilocks_field.rs +++ b/src/field/goldilocks_field.rs @@ -68,8 +68,7 @@ impl Field for GoldilocksField { const NEG_ONE: Self = Self(Self::ORDER - 1); const TWO_ADICITY: usize = 32; - const CHARACTERISTIC_WITH_TWO_ADICITY: Option<(u64, usize)> = - Some((Self::ORDER, Self::TWO_ADICITY)); + const CHARACTERISTIC_TWO_ADICITY: usize = Self::TWO_ADICITY; // Sage: `g = GF(p).multiplicative_generator()` const MULTIPLICATIVE_GROUP_GENERATOR: Self = Self(7); @@ -86,6 +85,9 @@ impl Field for GoldilocksField { fn order() -> BigUint { Self::ORDER.into() } + fn characteristic() -> BigUint { + Self::order() + } #[inline(always)] fn try_inverse(&self) -> Option { diff --git a/src/field/secp256k1_base.rs b/src/field/secp256k1_base.rs index 3e0d0ef0..0d79000f 100644 --- a/src/field/secp256k1_base.rs +++ b/src/field/secp256k1_base.rs @@ -78,7 +78,7 @@ impl Field for Secp256K1Base { ]); const TWO_ADICITY: usize = 1; - const CHARACTERISTIC_WITH_TWO_ADICITY: Option<(u64, usize)> = None; + const CHARACTERISTIC_TWO_ADICITY: usize = Self::TWO_ADICITY; // Sage: `g = GF(p).multiplicative_generator()` const MULTIPLICATIVE_GROUP_GENERATOR: Self = Self([5, 0, 0, 0]); @@ -94,6 +94,9 @@ impl Field for Secp256K1Base { 0xFFFFFFFF, ]) } + fn characteristic() -> BigUint { + Self::order() + } fn try_inverse(&self) -> Option { if self.is_zero() { diff --git a/src/field/secp256k1_scalar.rs b/src/field/secp256k1_scalar.rs index 595a27a3..a5b7a315 100644 --- a/src/field/secp256k1_scalar.rs +++ b/src/field/secp256k1_scalar.rs @@ -81,7 +81,7 @@ impl Field for Secp256K1Scalar { ]); const TWO_ADICITY: usize = 6; - const CHARACTERISTIC_WITH_TWO_ADICITY: Option<(u64, usize)> = None; + const CHARACTERISTIC_TWO_ADICITY: usize = Self::TWO_ADICITY; // Sage: `g = GF(p).multiplicative_generator()` const MULTIPLICATIVE_GROUP_GENERATOR: Self = Self([7, 0, 0, 0]); @@ -103,6 +103,9 @@ impl Field for Secp256K1Scalar { 0xFFFFFFFF, ]) } + fn characteristic() -> BigUint { + Self::order() + } fn try_inverse(&self) -> Option { if self.is_zero() {