mirror of
https://git.proxmox.com/git/rustc
synced 2025-08-17 20:35:53 +00:00
138 lines
3.8 KiB
Rust
138 lines
3.8 KiB
Rust
//! This module exercises the `ff_derive` procedural macros, to ensure that changes to the
|
|
//! `ff` crate are reflected in `ff_derive`. It also uses the resulting field to test some
|
|
//! of the APIs provided by `ff`, such as batch inversion.
|
|
|
|
#[macro_use]
|
|
extern crate ff;
|
|
|
|
/// The BLS12-381 scalar field.
|
|
#[derive(PrimeField)]
|
|
#[PrimeFieldModulus = "52435875175126190479447740508185965837690552500527637822603658699938581184513"]
|
|
#[PrimeFieldGenerator = "7"]
|
|
#[PrimeFieldReprEndianness = "little"]
|
|
struct Bls381K12Scalar([u64; 4]);
|
|
|
|
mod fermat {
|
|
/// The largest known Fermat prime, used to test the case `t = 1`.
|
|
#[derive(PrimeField)]
|
|
#[PrimeFieldModulus = "65537"]
|
|
#[PrimeFieldGenerator = "3"]
|
|
#[PrimeFieldReprEndianness = "little"]
|
|
struct Fermat65537Field([u64; 1]);
|
|
}
|
|
|
|
mod full_limbs {
|
|
#[derive(PrimeField)]
|
|
#[PrimeFieldModulus = "39402006196394479212279040100143613805079739270465446667948293404245721771496870329047266088258938001861606973112319"]
|
|
#[PrimeFieldGenerator = "19"]
|
|
#[PrimeFieldReprEndianness = "little"]
|
|
struct F384p([u64; 7]);
|
|
|
|
#[test]
|
|
fn random_masking_does_not_overflow() {
|
|
use ff::Field;
|
|
use rand::rngs::OsRng;
|
|
|
|
let _ = F384p::random(OsRng);
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn constants() {
|
|
use ff::{Field, PrimeField};
|
|
|
|
assert_eq!(
|
|
Bls381K12Scalar::MODULUS,
|
|
"0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001",
|
|
);
|
|
|
|
assert_eq!(
|
|
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]
|
|
fn from_u128() {
|
|
use ff::{Field, PrimeField};
|
|
|
|
assert_eq!(Bls381K12Scalar::from_u128(1), Bls381K12Scalar::ONE);
|
|
assert_eq!(Bls381K12Scalar::from_u128(2), Bls381K12Scalar::from(2));
|
|
assert_eq!(
|
|
Bls381K12Scalar::from_u128(u128::MAX),
|
|
Bls381K12Scalar::from_str_vartime("340282366920938463463374607431768211455").unwrap(),
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn batch_inversion() {
|
|
use ff::{BatchInverter, Field};
|
|
|
|
let one = Bls381K12Scalar::ONE;
|
|
|
|
// [1, 2, 3, 4]
|
|
let values: Vec<_> = (0..4)
|
|
.scan(one, |acc, _| {
|
|
let ret = *acc;
|
|
*acc += &one;
|
|
Some(ret)
|
|
})
|
|
.collect();
|
|
|
|
// Test BatchInverter::invert_with_external_scratch
|
|
{
|
|
let mut elements = values.clone();
|
|
let mut scratch_space = vec![Bls381K12Scalar::ZERO; elements.len()];
|
|
BatchInverter::invert_with_external_scratch(&mut elements, &mut scratch_space);
|
|
for (a, a_inv) in values.iter().zip(elements.into_iter()) {
|
|
assert_eq!(*a * a_inv, one);
|
|
}
|
|
}
|
|
|
|
// Test BatchInverter::invert_with_internal_scratch
|
|
{
|
|
let mut items: Vec<_> = values.iter().cloned().map(|p| (p, one)).collect();
|
|
BatchInverter::invert_with_internal_scratch(
|
|
&mut items,
|
|
|item| &mut item.0,
|
|
|item| &mut item.1,
|
|
);
|
|
for (a, (a_inv, _)) in values.iter().zip(items.into_iter()) {
|
|
assert_eq!(*a * a_inv, one);
|
|
}
|
|
}
|
|
|
|
// Test BatchInvert trait
|
|
#[cfg(feature = "alloc")]
|
|
{
|
|
use ff::BatchInvert;
|
|
let mut elements = values.clone();
|
|
elements.iter_mut().batch_invert();
|
|
for (a, a_inv) in values.iter().zip(elements.into_iter()) {
|
|
assert_eq!(*a * a_inv, one);
|
|
}
|
|
}
|
|
}
|