From 789a43f779a55e90639b49b1654b46d66b233a45 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Wed, 28 Aug 2024 12:58:37 -0700 Subject: [PATCH 1/3] MVPoly: fix typo in equation in comments Address https://github.com/o1-labs/proof-systems/pull/2495#discussion_r1734625902 --- mvpoly/tests/prime.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mvpoly/tests/prime.rs b/mvpoly/tests/prime.rs index 6656fdbe56..30dcdae874 100644 --- a/mvpoly/tests/prime.rs +++ b/mvpoly/tests/prime.rs @@ -607,7 +607,7 @@ fn test_from_expr_ec_addition() { assert_eq!(eval, exp_eval); } { - // - Constraint 3: Y3 - λ (X1 - X3) - Y1 = 0 + // - Constraint 3: Y3 - λ (X1 - X3) + Y1 = 0 let expr = y3.clone() - lambda.clone() * (x1.clone() - x3.clone()) + y1.clone(); let p = Dense::::from(expr); let random_evaluation: [Fp; 7] = std::array::from_fn(|_| Fp::rand(&mut rng)); From aa86be2f6006a5e9245f31f390b86aff3ff3d05a Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Wed, 28 Aug 2024 13:15:05 -0700 Subject: [PATCH 2/3] MVPoly: fix typo in comment in benches --- mvpoly/benches/prime.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mvpoly/benches/prime.rs b/mvpoly/benches/prime.rs index 93c190980e..bad7e84d04 100644 --- a/mvpoly/benches/prime.rs +++ b/mvpoly/benches/prime.rs @@ -20,7 +20,7 @@ fn bench_dense_mul(c: &mut Criterion) { let mut rng = o1_utils::tests::make_test_rng(None); c.bench_function("dense_mul", |b: &mut Bencher| { b.iter(|| { - // IMPROVEME: impleemnt mul on references and define the random + // IMPROVEME: implement mul on references and define the random // values before the benchmark let p1: Dense = unsafe { Dense::random(&mut rng) }; let p2: Dense = unsafe { Dense::random(&mut rng) }; From 293d74e8edf0830eca9788ca9cf973e4160cd491 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Wed, 28 Aug 2024 13:34:55 -0700 Subject: [PATCH 3/3] MVPoly: add max_degree optional parameter into random --- mvpoly/benches/prime.rs | 16 ++++++++-------- mvpoly/src/prime.rs | 32 ++++++++++++++++++++++++++------ mvpoly/tests/prime.rs | 34 +++++++++++++++++----------------- 3 files changed, 51 insertions(+), 31 deletions(-) diff --git a/mvpoly/benches/prime.rs b/mvpoly/benches/prime.rs index bad7e84d04..17a183bc11 100644 --- a/mvpoly/benches/prime.rs +++ b/mvpoly/benches/prime.rs @@ -7,8 +7,8 @@ use mvpoly::prime::Dense; // Should roughly cover the cases we care about fn bench_dense_add(c: &mut Criterion) { let mut rng = o1_utils::tests::make_test_rng(None); - let p1: Dense = unsafe { Dense::random(&mut rng) }; - let p2: Dense = unsafe { Dense::random(&mut rng) }; + let p1: Dense = unsafe { Dense::random(&mut rng, None) }; + let p2: Dense = unsafe { Dense::random(&mut rng, None) }; c.bench_function("dense_add", |b: &mut Bencher| { b.iter(|| { let _ = black_box(&p1) + black_box(&p2); @@ -22,8 +22,8 @@ fn bench_dense_mul(c: &mut Criterion) { b.iter(|| { // IMPROVEME: implement mul on references and define the random // values before the benchmark - let p1: Dense = unsafe { Dense::random(&mut rng) }; - let p2: Dense = unsafe { Dense::random(&mut rng) }; + let p1: Dense = unsafe { Dense::random(&mut rng, None) }; + let p2: Dense = unsafe { Dense::random(&mut rng, None) }; let _ = black_box(p1) * black_box(p2); }) }); @@ -31,7 +31,7 @@ fn bench_dense_mul(c: &mut Criterion) { fn bench_dense_neg(c: &mut Criterion) { let mut rng = o1_utils::tests::make_test_rng(None); - let p1: Dense = unsafe { Dense::random(&mut rng) }; + let p1: Dense = unsafe { Dense::random(&mut rng, None) }; c.bench_function("dense_neg", |b: &mut Bencher| { b.iter(|| { let _ = -black_box(&p1); @@ -41,8 +41,8 @@ fn bench_dense_neg(c: &mut Criterion) { fn bench_dense_sub(c: &mut Criterion) { let mut rng = o1_utils::tests::make_test_rng(None); - let p1: Dense = unsafe { Dense::random(&mut rng) }; - let p2: Dense = unsafe { Dense::random(&mut rng) }; + let p1: Dense = unsafe { Dense::random(&mut rng, None) }; + let p2: Dense = unsafe { Dense::random(&mut rng, None) }; c.bench_function("dense_sub", |b: &mut Bencher| { b.iter(|| { let _ = black_box(&p1) - black_box(&p2); @@ -52,7 +52,7 @@ fn bench_dense_sub(c: &mut Criterion) { fn bench_dense_eval(c: &mut Criterion) { let mut rng = o1_utils::tests::make_test_rng(None); - let p1: Dense = unsafe { Dense::random(&mut rng) }; + let p1: Dense = unsafe { Dense::random(&mut rng, None) }; let x: [Fp; 10] = std::array::from_fn(|_| Fp::rand(&mut rng)); c.bench_function("dense_eval", |b: &mut Bencher| { b.iter(|| { diff --git a/mvpoly/src/prime.rs b/mvpoly/src/prime.rs index 35cecda903..3c066fd3ef 100644 --- a/mvpoly/src/prime.rs +++ b/mvpoly/src/prime.rs @@ -224,7 +224,10 @@ impl Dense { } } - /// Generate a random polynomial + /// Generate a random polynomial of maximum degree `max_degree`. + /// + /// If `None` is provided as the maximum degree, the polynomial will be + /// generated with a maximum degree of `D`. /// /// # Safety /// @@ -234,12 +237,29 @@ impl Dense { /// polynomial random generator, if needed. /// /// For now, the function is only used for testing. - pub unsafe fn random(rng: &mut RNG) -> Self { + + pub unsafe fn random(rng: &mut RNG, max_degree: Option) -> Self { + let mut prime_gen = PrimeNumberGenerator::new(); let normalized_indices = Self::compute_normalized_indices(); - let coeff = normalized_indices - .iter() - .map(|_| F::rand(rng)) - .collect::>(); + // Different cases to avoid complexity in the case no maximum degree is + // provided + let coeff = if let Some(max_degree) = max_degree { + normalized_indices + .iter() + .map(|idx| { + let degree = naive_prime_factors(*idx, &mut prime_gen) + .iter() + .fold(0, |acc, (_, d)| acc + d); + if degree > max_degree { + F::zero() + } else { + F::rand(rng) + } + }) + .collect::>() + } else { + normalized_indices.iter().map(|_| F::rand(rng)).collect() + }; Dense { coeff, normalized_indices, diff --git a/mvpoly/tests/prime.rs b/mvpoly/tests/prime.rs index 30dcdae874..529b1d74ae 100644 --- a/mvpoly/tests/prime.rs +++ b/mvpoly/tests/prime.rs @@ -159,7 +159,7 @@ fn test_mul() { #[test] fn test_mul_by_one() { let mut rng = o1_utils::tests::make_test_rng(None); - let p1 = unsafe { Dense::::random(&mut rng) }; + let p1 = unsafe { Dense::::random(&mut rng, None) }; let one = Dense::::one(); let p2 = p1.clone() * one.clone(); assert_eq!(p1.clone(), p2); @@ -170,7 +170,7 @@ fn test_mul_by_one() { #[test] fn test_mul_by_zero() { let mut rng = o1_utils::tests::make_test_rng(None); - let p1 = unsafe { Dense::::random(&mut rng) }; + let p1 = unsafe { Dense::::random(&mut rng, None) }; let zero = Dense::::zero(); let p2 = p1.clone() * zero.clone(); assert_eq!(zero, p2); @@ -181,7 +181,7 @@ fn test_mul_by_zero() { #[test] fn test_add_zero() { let mut rng = o1_utils::tests::make_test_rng(None); - let p1 = unsafe { Dense::::random(&mut rng) }; + let p1 = unsafe { Dense::::random(&mut rng, None) }; let zero = Dense::::zero(); let p2 = p1.clone() + zero.clone(); @@ -193,7 +193,7 @@ fn test_add_zero() { #[test] fn test_double_is_add_twice() { let mut rng = o1_utils::tests::make_test_rng(None); - let p1 = unsafe { Dense::::random(&mut rng) }; + let p1 = unsafe { Dense::::random(&mut rng, None) }; let p2 = p1.clone() + p1.clone(); let p3 = p1.clone().double(); assert_eq!(p2, p3); @@ -202,7 +202,7 @@ fn test_double_is_add_twice() { #[test] fn test_sub_zero() { let mut rng = o1_utils::tests::make_test_rng(None); - let p1 = unsafe { Dense::::random(&mut rng) }; + let p1 = unsafe { Dense::::random(&mut rng, None) }; let zero = Dense::::zero(); let p2 = p1.clone() - zero.clone(); assert_eq!(p1.clone(), p2); @@ -211,7 +211,7 @@ fn test_sub_zero() { #[test] fn test_neg() { let mut rng = o1_utils::tests::make_test_rng(None); - let p1 = unsafe { Dense::::random(&mut rng) }; + let p1 = unsafe { Dense::::random(&mut rng, None) }; let p2 = -p1.clone(); // Test that p1 + (-p1) = 0 @@ -231,7 +231,7 @@ fn test_neg() { #[test] fn test_neg_ref() { let mut rng = o1_utils::tests::make_test_rng(None); - let p1 = unsafe { Dense::::random(&mut rng) }; + let p1 = unsafe { Dense::::random(&mut rng, None) }; let p2 = -&p1; // Test that p1 + (-&p1) = 0 @@ -246,7 +246,7 @@ fn test_neg_ref() { #[test] fn test_mul_by_scalar() { let mut rng = o1_utils::tests::make_test_rng(None); - let p1 = unsafe { Dense::::random(&mut rng) }; + let p1 = unsafe { Dense::::random(&mut rng, None) }; let mut p2 = Dense::::zero(); let c = Fp::rand(&mut rng); p2[0] = c; @@ -256,7 +256,7 @@ fn test_mul_by_scalar() { #[test] fn test_mul_by_scalar_with_zero() { let mut rng = o1_utils::tests::make_test_rng(None); - let p1 = unsafe { Dense::::random(&mut rng) }; + let p1 = unsafe { Dense::::random(&mut rng, None) }; let c = Fp::zero(); assert_eq!(p1.mul_by_scalar(c), Dense::::zero()) } @@ -264,7 +264,7 @@ fn test_mul_by_scalar_with_zero() { #[test] fn test_mul_by_scalar_with_one() { let mut rng = o1_utils::tests::make_test_rng(None); - let p1 = unsafe { Dense::::random(&mut rng) }; + let p1 = unsafe { Dense::::random(&mut rng, None) }; let c = Fp::one(); assert_eq!(p1.mul_by_scalar(c), p1) } @@ -272,7 +272,7 @@ fn test_mul_by_scalar_with_one() { #[test] fn test_mul_by_scalar_with_from() { let mut rng = o1_utils::tests::make_test_rng(None); - let p = unsafe { Dense::::random(&mut rng) }; + let p = unsafe { Dense::::random(&mut rng, None) }; let c = Fp::rand(&mut rng); // Create a constant polynomial from the field element @@ -410,8 +410,8 @@ fn test_eval_pbt_add() { let mut rng = o1_utils::tests::make_test_rng(None); let random_evaluation: [Fp; 6] = std::array::from_fn(|_| Fp::rand(&mut rng)); - let p1 = unsafe { Dense::::random(&mut rng) }; - let p2 = unsafe { Dense::::random(&mut rng) }; + let p1 = unsafe { Dense::::random(&mut rng, None) }; + let p2 = unsafe { Dense::::random(&mut rng, None) }; let p3 = p1.clone() + p2.clone(); let eval_p1 = p1.eval(&random_evaluation); let eval_p2 = p2.eval(&random_evaluation); @@ -424,8 +424,8 @@ fn test_eval_pbt_sub() { let mut rng = o1_utils::tests::make_test_rng(None); let random_evaluation: [Fp; 6] = std::array::from_fn(|_| Fp::rand(&mut rng)); - let p1 = unsafe { Dense::::random(&mut rng) }; - let p2 = unsafe { Dense::::random(&mut rng) }; + let p1 = unsafe { Dense::::random(&mut rng, None) }; + let p2 = unsafe { Dense::::random(&mut rng, None) }; let p3 = p1.clone() - p2.clone(); let eval_p1 = p1.eval(&random_evaluation); let eval_p2 = p2.eval(&random_evaluation); @@ -438,7 +438,7 @@ fn test_eval_pbt_mul_by_scalar() { let mut rng = o1_utils::tests::make_test_rng(None); let random_evaluation: [Fp; 6] = std::array::from_fn(|_| Fp::rand(&mut rng)); - let p1 = unsafe { Dense::::random(&mut rng) }; + let p1 = unsafe { Dense::::random(&mut rng, None) }; let c = Fp::rand(&mut rng); let p2 = p1.clone() * Dense::::from(c); let eval_p1 = p1.eval(&random_evaluation); @@ -451,7 +451,7 @@ fn test_eval_pbt_neg() { let mut rng = o1_utils::tests::make_test_rng(None); let random_evaluation: [Fp; 6] = std::array::from_fn(|_| Fp::rand(&mut rng)); - let p1 = unsafe { Dense::::random(&mut rng) }; + let p1 = unsafe { Dense::::random(&mut rng, None) }; let p2 = -p1.clone(); let eval_p1 = p1.eval(&random_evaluation); let eval_p2 = p2.eval(&random_evaluation);