mirror of
https://github.com/pseXperiments/ff-Goldilocks.git
synced 2026-01-09 04:57:59 -05:00
feat: mul-by-base api
This commit is contained in:
26
src/field.rs
26
src/field.rs
@@ -26,6 +26,14 @@ pub trait SmallField: PrimeField + Serialize + SerdeObject {
|
||||
fn from_limbs(limbs: &[Self::BaseField]) -> Self;
|
||||
/// Sample a random over the base field
|
||||
fn sample_base(rng: impl RngCore) -> Self;
|
||||
/// Mul-assign self by a base field element
|
||||
fn mul_assign_base(&mut self, rhs: &Self::BaseField);
|
||||
/// Multiply self by a base field element
|
||||
fn mul_base(&self, rhs: &Self::BaseField) -> Self {
|
||||
let mut res = self.clone();
|
||||
res.mul_assign_base(rhs);
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
impl SmallField for Goldilocks {
|
||||
@@ -56,6 +64,11 @@ impl SmallField for Goldilocks {
|
||||
fn sample_base(mut rng: impl RngCore) -> Self {
|
||||
Self::random(&mut rng)
|
||||
}
|
||||
|
||||
/// Mul-assign self by a base field element
|
||||
fn mul_assign_base(&mut self, rhs: &Self::BaseField) {
|
||||
*self *= rhs;
|
||||
}
|
||||
}
|
||||
impl SmallField for GoldilocksExt2 {
|
||||
type BaseField = Goldilocks;
|
||||
@@ -90,6 +103,12 @@ impl SmallField for GoldilocksExt2 {
|
||||
fn sample_base(mut rng: impl RngCore) -> Self {
|
||||
Self::BaseField::random(&mut rng).into()
|
||||
}
|
||||
|
||||
/// Mul-assign self by a base field element
|
||||
fn mul_assign_base(&mut self, rhs: &Self::BaseField) {
|
||||
self.0[0] *= rhs;
|
||||
self.0[1] *= rhs;
|
||||
}
|
||||
}
|
||||
impl SmallField for GoldilocksExt3 {
|
||||
type BaseField = Goldilocks;
|
||||
@@ -124,4 +143,11 @@ impl SmallField for GoldilocksExt3 {
|
||||
fn sample_base(mut rng: impl RngCore) -> Self {
|
||||
Self::BaseField::random(&mut rng).into()
|
||||
}
|
||||
|
||||
/// Mul-assign self by a base field element
|
||||
fn mul_assign_base(&mut self, rhs: &Self::BaseField) {
|
||||
self.0[0] *= rhs;
|
||||
self.0[1] *= rhs;
|
||||
self.0[2] *= rhs;
|
||||
}
|
||||
}
|
||||
|
||||
35
src/tests.rs
35
src/tests.rs
@@ -9,6 +9,41 @@ use rand_core::RngCore;
|
||||
use rand_core::SeedableRng;
|
||||
use rand_xorshift::XorShiftRng;
|
||||
|
||||
use crate::SmallField;
|
||||
|
||||
|
||||
pub fn random_small_field_tests<F: SmallField>(type_name: String) {
|
||||
let mut rng = XorShiftRng::from_seed([
|
||||
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,
|
||||
0xe5,
|
||||
]);
|
||||
|
||||
let message = format!("multiplication {}", type_name);
|
||||
let start = start_timer!(|| message);
|
||||
for _ in 0..1000000 {
|
||||
let a = F::random(&mut rng);
|
||||
let b = F::sample_base(&mut rng);
|
||||
let c = F::random(&mut rng);
|
||||
|
||||
let mut t0 = a; // (a * b) * c
|
||||
t0.mul_assign(&b);
|
||||
t0.mul_assign(&c);
|
||||
|
||||
let mut t1 = a; // (a * c) * b
|
||||
t1.mul_assign(&c);
|
||||
t1.mul_assign(&b);
|
||||
|
||||
let mut t2 = b; // (b * c) * a
|
||||
t2.mul_assign(&c);
|
||||
t2.mul_assign(&a);
|
||||
|
||||
assert_eq!(t0, t1);
|
||||
assert_eq!(t1, t2);
|
||||
}
|
||||
end_timer!(start);
|
||||
|
||||
}
|
||||
|
||||
pub fn random_field_tests<F: Field>(type_name: String) {
|
||||
let mut rng = XorShiftRng::from_seed([
|
||||
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,
|
||||
|
||||
@@ -7,6 +7,7 @@ use rand_xorshift::XorShiftRng;
|
||||
use super::random_field_tests;
|
||||
use super::random_inversion_tests;
|
||||
use super::random_prime_field_tests;
|
||||
use super::random_small_field_tests;
|
||||
use crate::fp::Goldilocks;
|
||||
use crate::fp::LegendreSymbol;
|
||||
|
||||
@@ -56,4 +57,5 @@ fn test_field() {
|
||||
random_field_tests::<Goldilocks>("Goldilocks".to_string());
|
||||
random_prime_field_tests::<Goldilocks>("Goldilocks".to_string());
|
||||
random_inversion_tests::<Goldilocks>("Goldilocks".to_string());
|
||||
random_small_field_tests::<Goldilocks>("Goldilocks".to_string());
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use super::random_field_tests;
|
||||
use super::random_inversion_tests;
|
||||
use super::random_prime_field_tests;
|
||||
use super::random_small_field_tests;
|
||||
use crate::fp::Goldilocks;
|
||||
use crate::fp2::GoldilocksExt2;
|
||||
|
||||
@@ -9,6 +10,7 @@ fn test_field() {
|
||||
random_field_tests::<GoldilocksExt2>("GoldilocksExt2".to_string());
|
||||
random_prime_field_tests::<GoldilocksExt2>("GoldilocksExt2".to_string());
|
||||
random_inversion_tests::<GoldilocksExt2>("GoldilocksExt2".to_string());
|
||||
random_small_field_tests::<GoldilocksExt2>("GoldilocksExt2".to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use super::random_field_tests;
|
||||
use super::random_prime_field_tests;
|
||||
use super::random_small_field_tests;
|
||||
use crate::fp::Goldilocks;
|
||||
use crate::fp3::GoldilocksExt3;
|
||||
|
||||
@@ -7,6 +8,7 @@ use crate::fp3::GoldilocksExt3;
|
||||
fn test_field() {
|
||||
random_field_tests::<GoldilocksExt3>("GoldilocksExt3".to_string());
|
||||
random_prime_field_tests::<GoldilocksExt3>("GoldilocksExt3".to_string());
|
||||
random_small_field_tests::<GoldilocksExt3>("GoldilocksExt3".to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user