Skip to content

Commit 2b20347

Browse files
Add MINUS_ONE to Field, FpConfig (#1004)
* Add `MINUS_ONE` to `Field`, `FpConfig` * Fix comment * Fix comments --------- Co-authored-by: Weikeng Chen <w.k@berkeley.edu>
1 parent 25d4b7e commit 2b20347

File tree

7 files changed

+28
-3
lines changed

7 files changed

+28
-3
lines changed

ff/src/fields/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,9 @@ pub trait Field:
207207
/// The multiplicative identity of the field.
208208
const ONE: Self;
209209

210+
/// Negation of the multiplicative identity of the field.
211+
const NEG_ONE: Self;
212+
210213
/// Returns the characteristic of the field,
211214
/// in little-endian representation.
212215
fn characteristic() -> &'static [u64] {

ff/src/fields/models/cubic_extension.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,12 @@ impl<P: CubicExtConfig> Field for CubicExtField<P> {
186186

187187
const ONE: Self = Self::new(P::BaseField::ONE, P::BaseField::ZERO, P::BaseField::ZERO);
188188

189+
const NEG_ONE: Self = Self::new(
190+
P::BaseField::NEG_ONE,
191+
P::BaseField::ZERO,
192+
P::BaseField::ZERO,
193+
);
194+
189195
fn extension_degree() -> u64 {
190196
3 * P::BaseField::extension_degree()
191197
}

ff/src/fields/models/fp/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ pub trait FpConfig<const N: usize>: Send + Sync + 'static + Sized {
4040
/// such that, for all elements `f` of the field, `e * f = f`.
4141
const ONE: Fp<Self, N>;
4242

43+
/// Negation of `Self::ONE`.
44+
const NEG_ONE: Fp<Self, N>;
45+
4346
/// Let `N` be the size of the multiplicative group defined by the field.
4447
/// Then `TWO_ADICITY` is the two-adicity of `N`, i.e. the integer `s`
4548
/// such that `N = 2^s * t` for some odd integer `t`.
@@ -211,6 +214,7 @@ impl<P: FpConfig<N>, const N: usize> Field for Fp<P, N> {
211214

212215
const SQRT_PRECOMP: Option<SqrtPrecomputation<Self>> = P::SQRT_PRECOMP;
213216
const ONE: Self = P::ONE;
217+
const NEG_ONE: Self = P::NEG_ONE;
214218

215219
fn extension_degree() -> u64 {
216220
1

ff/src/fields/models/fp/montgomery_backend.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,9 @@ impl<T: MontConfig<N>, const N: usize> FpConfig<N> for MontBackend<T, N> {
610610
/// such that, for all elements `f` of the field, `e * f = f`.
611611
const ONE: Fp<Self, N> = Fp::new_unchecked(T::R);
612612

613+
/// Negation of `Self::ONE`.
614+
const NEG_ONE: Fp<Self, N> = Fp::new_unchecked(Self::MODULUS.const_sub_with_borrow(&T::R).0);
615+
613616
const TWO_ADICITY: u32 = Self::MODULUS.two_adic_valuation();
614617
const TWO_ADIC_ROOT_OF_UNITY: Fp<Self, N> = T::TWO_ADIC_ROOT_OF_UNITY;
615618
const SMALL_SUBGROUP_BASE: Option<u32> = T::SMALL_SUBGROUP_BASE;

ff/src/fields/models/quadratic_extension.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,8 @@ impl<P: QuadExtConfig> Field for QuadExtField<P> {
212212

213213
const ONE: Self = Self::new(P::BaseField::ONE, P::BaseField::ZERO);
214214

215+
const NEG_ONE: Self = Self::new(P::BaseField::NEG_ONE, P::BaseField::ZERO);
216+
215217
fn extension_degree() -> u64 {
216218
2 * P::BaseField::extension_degree()
217219
}
@@ -270,7 +272,7 @@ impl<P: QuadExtConfig> Field for QuadExtField<P> {
270272
// = (c0^2 + beta * c1^2, 2 c0 * c1)
271273
// Where beta is P::NONRESIDUE.
272274
// When beta = -1, we can re-use intermediate additions to improve performance.
273-
if P::NONRESIDUE == -P::BaseField::ONE {
275+
if P::NONRESIDUE == P::BaseField::NEG_ONE {
274276
// When the non-residue is -1, we save 2 intermediate additions,
275277
// and use one fewer intermediate variable
276278

serialize/src/test.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use std::collections::{HashMap, HashSet};
2-
31
use super::*;
42
use ark_std::{
53
collections::{BTreeMap, BTreeSet, LinkedList, VecDeque},
@@ -288,9 +286,11 @@ fn test_btreeset() {
288286
test_serialize(set);
289287
}
290288

289+
#[cfg(feature = "std")]
291290
#[test]
292291
#[allow(clippy::zero_sized_map_values)]
293292
fn test_hashmap() {
293+
use std::collections::HashMap;
294294
let mut map = HashMap::new();
295295
map.insert(0u64, Dummy);
296296
map.insert(5u64, Dummy);
@@ -301,8 +301,11 @@ fn test_hashmap() {
301301
test_serialize(map);
302302
}
303303

304+
#[cfg(feature = "std")]
304305
#[test]
305306
fn test_hashset() {
307+
use std::collections::HashSet;
308+
306309
let mut set = HashSet::new();
307310
set.insert(Dummy);
308311
set.insert(Dummy);

test-templates/src/fields.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,11 +215,14 @@ macro_rules! __test_field {
215215
let mut rng = test_rng();
216216
let zero = <$field>::zero();
217217
let one = <$field>::one();
218+
let minus_one = <$field>::NEG_ONE;
218219
assert_eq!(one.inverse().unwrap(), one, "One inverse failed");
219220
assert!(one.is_one(), "One is not one");
220221

221222
assert!(<$field>::ONE.is_one(), "One constant is not one");
222223
assert_eq!(<$field>::ONE, one, "One constant is incorrect");
224+
assert_eq!(<$field>::NEG_ONE, -one, "NEG_ONE constant is incorrect");
225+
assert_eq!(<$field>::ONE + <$field>::NEG_ONE, zero, "1 + -1 neq 0");
223226

224227
for _ in 0..ITERATIONS {
225228
// Associativity
@@ -235,6 +238,7 @@ macro_rules! __test_field {
235238
assert_eq!(one * a, a, "Identity mul failed");
236239
assert_eq!(one * b, b, "Identity mul failed");
237240
assert_eq!(one * c, c, "Identity mul failed");
241+
assert_eq!(minus_one * c, -c, "NEG_ONE mul failed");
238242

239243
assert_eq!(zero * a, zero, "Mul by zero failed");
240244
assert_eq!(zero * b, zero, "Mul by zero failed");

0 commit comments

Comments
 (0)