From f8124dc21c26d41c64d3ab325b49f83d5d2c0a8f Mon Sep 17 00:00:00 2001 From: TomAFrench Date: Mon, 6 Jan 2025 21:04:37 +0000 Subject: [PATCH 1/2] feat: improve blob simulation speed --- .../crates/blob/src/blob.nr | 177 ++++++++---------- 1 file changed, 83 insertions(+), 94 deletions(-) diff --git a/noir-projects/noir-protocol-circuits/crates/blob/src/blob.nr b/noir-projects/noir-protocol-circuits/crates/blob/src/blob.nr index d2f9d809332..d3347c68030 100644 --- a/noir-projects/noir-protocol-circuits/crates/blob/src/blob.nr +++ b/noir-projects/noir-protocol-circuits/crates/blob/src/blob.nr @@ -227,67 +227,70 @@ fn barycentric_evaluate_blob_at_z(z: F, ys: [F; FIELDS_PER_BLOB]) -> F { __compute_partial_sums(fracs, ROOTS) }; - // We split off the first term to check the initial sum - - // partial_sums[0] <- (lhs[0] * rhs[0] + ... + lhs[7] * rhs[7]) - // => (lhs[0] * rhs[0] + ... + lhs[7] * rhs[7]) - partial_sums[0] == 0 - let lhs = [ - [ROOTS[0]], [ROOTS[1]], [ROOTS[2]], [ROOTS[3]], [ROOTS[4]], [ROOTS[5]], [ROOTS[6]], - [ROOTS[7]], - ]; - let rhs = [ - [fracs[0]], [fracs[1]], [fracs[2]], [fracs[3]], [fracs[4]], [fracs[5]], [fracs[6]], - [fracs[7]], - ]; - BigNum::evaluate_quadratic_expression( - lhs, - [[false], [false], [false], [false], [false], [false], [false], [false]], - rhs, - [[false], [false], [false], [false], [false], [false], [false], [false]], - [partial_sums[0]], - [true], - ); - for i in 1..NUM_PARTIAL_SUMS { - // Seeking: - // ___i*8 - 1 ___i*8 + 7 - // \ omega^i \ / y_k \ - // sum_out = / y_i . --------- + / omega^k . | --------- | - // /____ z - omega^i /____ \ z - omega^k / - // 0 k = i*8 - // ^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - // sum partial_sum - // - // ... that is: - // - // ___i*8 - 1 ___ 7 - // \ omega^i \ - // sum_out = / y_i . --------- + / lhs[j] . rhs[j] - // /____ z - omega^i /____ - // 0 j = 0 - // ^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^ - // sum partial_sum - // - - let mut lhs: [[F; 1]; 8] = [std::mem::zeroed(); 8]; - let mut rhs: [[F; 1]; 8] = [std::mem::zeroed(); 8]; - for j in 0..8 { - let k = i * 8 + j; - lhs[j] = [ROOTS[k]]; // omega^k - rhs[j] = [fracs[k]]; // y_k / (z - omega^k) - } - - let linear_terms = [partial_sums[i - 1], partial_sums[i]]; - - // partial_sums[i] <- partial_sums[i-1] + (lhs[8*i] * rhs[8*i] + ... + lhs[8*i + 7] * rhs[8*i + 7]) - // => (lhs[8*i] * rhs[8*i] + ... + lhs[8*i + 7] * rhs[8*i + 7]) + partial_sums[i-1] - partial_sums[i] == 0 + if !std::runtime::is_unconstrained() { + // We split off the first term to check the initial sum + + // partial_sums[0] <- (lhs[0] * rhs[0] + ... + lhs[7] * rhs[7]) + // => (lhs[0] * rhs[0] + ... + lhs[7] * rhs[7]) - partial_sums[0] == 0 + let lhs = [ + [ROOTS[0]], [ROOTS[1]], [ROOTS[2]], [ROOTS[3]], [ROOTS[4]], [ROOTS[5]], [ROOTS[6]], + [ROOTS[7]], + ]; + let rhs = [ + [fracs[0]], [fracs[1]], [fracs[2]], [fracs[3]], [fracs[4]], [fracs[5]], [fracs[6]], + [fracs[7]], + ]; BigNum::evaluate_quadratic_expression( lhs, [[false], [false], [false], [false], [false], [false], [false], [false]], rhs, [[false], [false], [false], [false], [false], [false], [false], [false]], - linear_terms, - [false, true], + [partial_sums[0]], + [true], ); + for i in 1..NUM_PARTIAL_SUMS { + // Seeking: + // ___i*8 - 1 ___i*8 + 7 + // \ omega^i \ / y_k \ + // sum_out = / y_i . --------- + / omega^k . | --------- | + // /____ z - omega^i /____ \ z - omega^k / + // 0 k = i*8 + // ^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + // sum partial_sum + // + // ... that is: + // + // ___i*8 - 1 ___ 7 + // \ omega^i \ + // sum_out = / y_i . --------- + / lhs[j] . rhs[j] + // /____ z - omega^i /____ + // 0 j = 0 + // ^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^ + // sum partial_sum + // + + + // partial_sums[i] <- partial_sums[i-1] + (lhs[8*i] * rhs[8*i] + ... + lhs[8*i + 7] * rhs[8*i + 7]) + // => (lhs[8*i] * rhs[8*i] + ... + lhs[8*i + 7] * rhs[8*i + 7]) + partial_sums[i-1] - partial_sums[i] == 0 + let mut lhs: [[F; 1]; 8] = [std::mem::zeroed(); 8]; + let mut rhs: [[F; 1]; 8] = [std::mem::zeroed(); 8]; + for j in 0..8 { + let k = i * 8 + j; + lhs[j] = [ROOTS[k]]; // omega^k + rhs[j] = [fracs[k]]; // y_k / (z - omega^k) + } + + let linear_terms = [partial_sums[i - 1], partial_sums[i]]; + + BigNum::evaluate_quadratic_expression( + lhs, + [[false], [false], [false], [false], [false], [false], [false], [false]], + rhs, + [[false], [false], [false], [false], [false], [false], [false], [false]], + linear_terms, + [false, true], + ); + } } let factor = compute_factor(z); @@ -317,14 +320,16 @@ fn compute_factor(z: F) -> F { // (z_pow_d - one) * (D_INV) - factor = 0 // z_pow_d * D_INV - D_INV - factor = 0 - BigNum::evaluate_quadratic_expression( - [[z_pow_d]], - [[false]], - [[D_INV]], - [[false]], - [factor, D_INV], - [true, true], - ); + if !std::runtime::is_unconstrained() { + BigNum::evaluate_quadratic_expression( + [[z_pow_d]], + [[false]], + [[D_INV]], + [[false]], + [factor, D_INV], + [true, true], + ); + } // This version doesn't work: // BigNum::evaluate_quadratic_expression( @@ -371,17 +376,19 @@ fn compute_fracs( __compute_fracs(z, ys, ROOTS) }; - for i in 0..FIELDS_PER_BLOB { - // frac <-- ys[i] / (z + neg_roots[i]) - // frac * (z + neg_roots[i]) - ys[i] = 0 - BigNum::evaluate_quadratic_expression( - [[fracs[i]]], - [[false]], - [[z, ROOTS[i].neg()]], - [[false, false]], - [ys[i]], - [true], - ); + if !std::runtime::is_unconstrained() { + for i in 0..FIELDS_PER_BLOB { + // frac <-- ys[i] / (z + neg_roots[i]) + // frac * (z + neg_roots[i]) - ys[i] = 0 + BigNum::evaluate_quadratic_expression( + [[fracs[i]]], + [[false]], + [[z, ROOTS[i].neg()]], + [[false, false]], + [ys[i]], + [true], + ); + } } fracs @@ -442,7 +449,7 @@ mod tests { field_to_bignum, }, blob_public_inputs::BlobCommitment, - unconstrained_config::{D, D_INV, F, LOG_FIELDS_PER_BLOB}, + unconstrained_config::{D, D_INV, F}, }; use bigint::{BigNum, fields::bls12_381Fr::BLS12_381_Fr_Params}; use types::{ @@ -451,24 +458,6 @@ mod tests { tests::{fixture_builder::FixtureBuilder, utils::pad_end}, }; - // Helper to return (z^d - 1)/d (unsafe - test only) - fn z_d_helper(challenge_z: F) -> F { - let mut t1 = unsafe { challenge_z.__mul(challenge_z) }; - let mut t2: F = BigNum::new(); - for _i in 0..LOG_FIELDS_PER_BLOB - 1 { - t2 = unsafe { t1.__mul(t1) }; - t1 = t2; - } - - let z_pow_d = t1; - - let one: F = BigNum::one(); - - t1 = unsafe { z_pow_d.__sub(one) }; - let factor = unsafe { t1.__mul(D_INV) }; - factor - } - #[test] unconstrained fn test_one_note() { let mut tx_data = FixtureBuilder::new(); @@ -500,7 +489,7 @@ mod tests { //* p(z).(z - 1) = --------- //* d // - let rhs = z_d_helper(challenge_z); + let rhs = super::compute_factor(challenge_z); let z_minus_1 = unsafe { challenge_z.__sub(BigNum::one()) }; let lhs = y.__mul(z_minus_1); assert_eq(lhs, rhs); From 00054d07754116d3566c4aa1b4391a32eecd6ac9 Mon Sep 17 00:00:00 2001 From: Tom French Date: Tue, 7 Jan 2025 10:08:43 +0000 Subject: [PATCH 2/2] . --- .../crates/blob/src/blob.nr | 37 +++++++++---------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/noir-projects/noir-protocol-circuits/crates/blob/src/blob.nr b/noir-projects/noir-protocol-circuits/crates/blob/src/blob.nr index d3347c68030..10ebc5c1694 100644 --- a/noir-projects/noir-protocol-circuits/crates/blob/src/blob.nr +++ b/noir-projects/noir-protocol-circuits/crates/blob/src/blob.nr @@ -269,27 +269,26 @@ fn barycentric_evaluate_blob_at_z(z: F, ys: [F; FIELDS_PER_BLOB]) -> F { // sum partial_sum // - // partial_sums[i] <- partial_sums[i-1] + (lhs[8*i] * rhs[8*i] + ... + lhs[8*i + 7] * rhs[8*i + 7]) // => (lhs[8*i] * rhs[8*i] + ... + lhs[8*i + 7] * rhs[8*i + 7]) + partial_sums[i-1] - partial_sums[i] == 0 - let mut lhs: [[F; 1]; 8] = [std::mem::zeroed(); 8]; - let mut rhs: [[F; 1]; 8] = [std::mem::zeroed(); 8]; - for j in 0..8 { - let k = i * 8 + j; - lhs[j] = [ROOTS[k]]; // omega^k - rhs[j] = [fracs[k]]; // y_k / (z - omega^k) - } - - let linear_terms = [partial_sums[i - 1], partial_sums[i]]; - - BigNum::evaluate_quadratic_expression( - lhs, - [[false], [false], [false], [false], [false], [false], [false], [false]], - rhs, - [[false], [false], [false], [false], [false], [false], [false], [false]], - linear_terms, - [false, true], - ); + let mut lhs: [[F; 1]; 8] = [std::mem::zeroed(); 8]; + let mut rhs: [[F; 1]; 8] = [std::mem::zeroed(); 8]; + for j in 0..8 { + let k = i * 8 + j; + lhs[j] = [ROOTS[k]]; // omega^k + rhs[j] = [fracs[k]]; // y_k / (z - omega^k) + } + + let linear_terms = [partial_sums[i - 1], partial_sums[i]]; + + BigNum::evaluate_quadratic_expression( + lhs, + [[false], [false], [false], [false], [false], [false], [false], [false]], + rhs, + [[false], [false], [false], [false], [false], [false], [false], [false]], + linear_terms, + [false, true], + ); } }