feat: mul-by-base api

This commit is contained in:
zhenfei
2024-01-11 13:34:17 -05:00
parent 1b53126fdc
commit 153a709961
5 changed files with 67 additions and 0 deletions

View File

@@ -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;
}
}

View File

@@ -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,

View File

@@ -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());
}

View File

@@ -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]

View File

@@ -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]