mirror of
https://github.com/arnaucube/sonobe.git
synced 2026-01-13 01:11:32 +01:00
Optimize native nimfs (#110)
* Optimize the HyperNova `compute_g`, `compute_Ls` and `to_lcccs` methods - Optimize the HyperNova `compute_g`, `compute_Ls` and `to_lcccs` methods - in some tests, increase the size of test matrices to a more real-world size. | method | matrix size | old version seconds | new version seconds | | --------------------- | ------------- | ------------------- | ------------------- | | compute_g | 2^8 x 2^8 | 16.48 | 0.16 | | compute_g | 2^9 x 2^9 | 122.62 | 0.51 | | compute_Ls | 2^8 x 2^8 | 9.73 | 0.11 | | compute_Ls | 2^9 x 2^9 | 67.16 | 0.38 | | to_lcccs | 2^8 x 2^8 | 4.56 | 0.21 | | to_lcccs | 2^9 x 2^9 | 67.65 | 0.84 | - Note: 2^16 x 2^16 is the actual size (upperbound) of the circuit, which is not represented in the table since it was needing too much ram to even be computed. * Optimize HyperNova's `compute_sigmas_thetas` and `compute_Q` | method | matrix size | old version seconds | new version seconds | | ------------- | ------------- | ------------------- | ------------------- | | compute_sigmas_thetas | 2^8 x 2^8 | 12.86 | 0.13 | | compute_sigmas_thetas | 2^9 x 2^9 | 100.01 | 0.51 | | compute_Q | 2^8 x 2^8 | 4.49 | 0.07 | | compute_Q | 2^9 x 2^9 | 70.77 | 0.55 | * optimize LCCCS::check_relation & CCCS::check_relation, and remove unnessary methods after last reimplementations
This commit is contained in:
@@ -1,20 +1,18 @@
|
||||
use ark_ec::CurveGroup;
|
||||
use ark_ff::PrimeField;
|
||||
use ark_poly::DenseMultilinearExtension;
|
||||
use ark_std::One;
|
||||
use std::sync::Arc;
|
||||
use ark_poly::MultilinearExtension;
|
||||
|
||||
use ark_std::rand::Rng;
|
||||
|
||||
use super::cccs::Witness;
|
||||
use super::utils::{compute_all_sum_Mz_evals, compute_sum_Mz};
|
||||
use crate::ccs::CCS;
|
||||
use crate::commitment::{
|
||||
pedersen::{Params as PedersenParams, Pedersen},
|
||||
CommitmentScheme,
|
||||
};
|
||||
use crate::utils::mle::{matrix_to_mle, vec_to_mle};
|
||||
use crate::utils::virtual_polynomial::VirtualPolynomial;
|
||||
use crate::utils::mle::dense_vec_to_dense_mle;
|
||||
use crate::utils::vec::mat_vec_mul;
|
||||
use crate::Error;
|
||||
|
||||
/// Linearized Committed CCS instance
|
||||
@@ -33,12 +31,6 @@ pub struct LCCCS<C: CurveGroup> {
|
||||
}
|
||||
|
||||
impl<F: PrimeField> CCS<F> {
|
||||
/// Compute v_j values of the linearized committed CCS form
|
||||
/// Given `r`, compute: \sum_{y \in {0,1}^s'} M_j(r, y) * z(y)
|
||||
fn compute_v_j(&self, z: &[F], r: &[F]) -> Vec<F> {
|
||||
compute_all_sum_Mz_evals(&self.M, z, r, self.s_prime)
|
||||
}
|
||||
|
||||
pub fn to_lcccs<R: Rng, C: CurveGroup>(
|
||||
&self,
|
||||
rng: &mut R,
|
||||
@@ -54,7 +46,18 @@ impl<F: PrimeField> CCS<F> {
|
||||
let C = Pedersen::<C, true>::commit(pedersen_params, &w, &r_w)?;
|
||||
|
||||
let r_x: Vec<C::ScalarField> = (0..self.s).map(|_| C::ScalarField::rand(rng)).collect();
|
||||
let v = self.compute_v_j(z, &r_x);
|
||||
|
||||
let Mzs: Vec<DenseMultilinearExtension<F>> = self
|
||||
.M
|
||||
.iter()
|
||||
.map(|M_j| Ok(dense_vec_to_dense_mle(self.s, &mat_vec_mul(M_j, z)?)))
|
||||
.collect::<Result<_, Error>>()?;
|
||||
|
||||
// compute v_j
|
||||
let v: Vec<F> = Mzs
|
||||
.iter()
|
||||
.map(|Mz| Mz.evaluate(&r_x).ok_or(Error::EvaluationFail))
|
||||
.collect::<Result<_, Error>>()?;
|
||||
|
||||
Ok((
|
||||
LCCCS::<C> {
|
||||
@@ -70,29 +73,6 @@ impl<F: PrimeField> CCS<F> {
|
||||
}
|
||||
|
||||
impl<C: CurveGroup> LCCCS<C> {
|
||||
/// Compute all L_j(x) polynomials
|
||||
pub fn compute_Ls(
|
||||
&self,
|
||||
ccs: &CCS<C::ScalarField>,
|
||||
z: &[C::ScalarField],
|
||||
) -> Vec<VirtualPolynomial<C::ScalarField>> {
|
||||
let z_mle = vec_to_mle(ccs.s_prime, z);
|
||||
// Convert all matrices to MLE
|
||||
let M_x_y_mle: Vec<DenseMultilinearExtension<C::ScalarField>> =
|
||||
ccs.M.clone().into_iter().map(matrix_to_mle).collect();
|
||||
|
||||
let mut vec_L_j_x = Vec::with_capacity(ccs.t);
|
||||
for M_j in M_x_y_mle {
|
||||
let sum_Mz = compute_sum_Mz(M_j, &z_mle, ccs.s_prime);
|
||||
let sum_Mz_virtual =
|
||||
VirtualPolynomial::new_from_mle(&Arc::new(sum_Mz.clone()), C::ScalarField::one());
|
||||
let L_j_x = sum_Mz_virtual.build_f_hat(&self.r_x).unwrap();
|
||||
vec_L_j_x.push(L_j_x);
|
||||
}
|
||||
|
||||
vec_L_j_x
|
||||
}
|
||||
|
||||
/// Perform the check of the LCCCS instance described at section 4.2
|
||||
pub fn check_relation(
|
||||
&self,
|
||||
@@ -108,7 +88,15 @@ impl<C: CurveGroup> LCCCS<C> {
|
||||
|
||||
// check CCS relation
|
||||
let z: Vec<C::ScalarField> = [vec![self.u], self.x.clone(), w.w.to_vec()].concat();
|
||||
let computed_v = compute_all_sum_Mz_evals(&ccs.M, &z, &self.r_x, ccs.s_prime);
|
||||
|
||||
let computed_v: Vec<C::ScalarField> = ccs
|
||||
.M
|
||||
.iter()
|
||||
.map(|M_j| {
|
||||
let Mz_mle = dense_vec_to_dense_mle(ccs.s, &mat_vec_mul(M_j, &z)?);
|
||||
Mz_mle.evaluate(&self.r_x).ok_or(Error::EvaluationFail)
|
||||
})
|
||||
.collect::<Result<_, Error>>()?;
|
||||
if computed_v != self.v {
|
||||
return Err(Error::NotSatisfied);
|
||||
}
|
||||
@@ -118,31 +106,64 @@ impl<C: CurveGroup> LCCCS<C> {
|
||||
|
||||
#[cfg(test)]
|
||||
pub mod tests {
|
||||
use super::*;
|
||||
use ark_std::Zero;
|
||||
|
||||
use crate::ccs::tests::{get_test_ccs, get_test_z};
|
||||
use crate::utils::hypercube::BooleanHypercube;
|
||||
use ark_std::test_rng;
|
||||
|
||||
use ark_pallas::{Fr, Projective};
|
||||
use ark_std::test_rng;
|
||||
use ark_std::One;
|
||||
use ark_std::UniformRand;
|
||||
use ark_std::Zero;
|
||||
use std::sync::Arc;
|
||||
|
||||
use super::*;
|
||||
use crate::ccs::{
|
||||
r1cs::R1CS,
|
||||
tests::{get_test_ccs, get_test_z},
|
||||
};
|
||||
use crate::utils::hypercube::BooleanHypercube;
|
||||
use crate::utils::virtual_polynomial::{build_eq_x_r_vec, VirtualPolynomial};
|
||||
|
||||
// method for testing
|
||||
pub fn compute_Ls<C: CurveGroup>(
|
||||
ccs: &CCS<C::ScalarField>,
|
||||
lcccs: &LCCCS<C>,
|
||||
z: &[C::ScalarField],
|
||||
) -> Vec<VirtualPolynomial<C::ScalarField>> {
|
||||
let eq_rx = build_eq_x_r_vec(&lcccs.r_x).unwrap();
|
||||
let eq_rx_mle = dense_vec_to_dense_mle(ccs.s, &eq_rx);
|
||||
|
||||
let mut Ls = Vec::with_capacity(ccs.t);
|
||||
for M_j in ccs.M.iter() {
|
||||
let mut L = VirtualPolynomial::<C::ScalarField>::new(ccs.s);
|
||||
let mut Mz = vec![dense_vec_to_dense_mle(ccs.s, &mat_vec_mul(M_j, z).unwrap())];
|
||||
Mz.push(eq_rx_mle.clone());
|
||||
L.add_mle_list(
|
||||
Mz.iter().map(|v| Arc::new(v.clone())),
|
||||
C::ScalarField::one(),
|
||||
)
|
||||
.unwrap();
|
||||
Ls.push(L);
|
||||
}
|
||||
Ls
|
||||
}
|
||||
|
||||
#[test]
|
||||
/// Test linearized CCCS v_j against the L_j(x)
|
||||
fn test_lcccs_v_j() {
|
||||
let mut rng = test_rng();
|
||||
|
||||
let ccs = get_test_ccs();
|
||||
let z = get_test_z(3);
|
||||
ccs.check_relation(&z.clone()).unwrap();
|
||||
let n_rows = 2_u32.pow(5) as usize;
|
||||
let n_cols = 2_u32.pow(5) as usize;
|
||||
let r1cs = R1CS::rand(&mut rng, n_rows, n_cols);
|
||||
let ccs = CCS::from_r1cs(r1cs);
|
||||
let z: Vec<Fr> = (0..n_cols).map(|_| Fr::rand(&mut rng)).collect();
|
||||
|
||||
let (pedersen_params, _) =
|
||||
Pedersen::<Projective>::setup(&mut rng, ccs.n - ccs.l - 1).unwrap();
|
||||
|
||||
let (lcccs, _) = ccs.to_lcccs(&mut rng, &pedersen_params, &z).unwrap();
|
||||
// with our test vector coming from R1CS, v should have length 3
|
||||
assert_eq!(lcccs.v.len(), 3);
|
||||
|
||||
let vec_L_j_x = lcccs.compute_Ls(&ccs, &z);
|
||||
let vec_L_j_x = compute_Ls(&ccs, &lcccs, &z);
|
||||
assert_eq!(vec_L_j_x.len(), lcccs.v.len());
|
||||
|
||||
for (v_i, L_j_x) in lcccs.v.into_iter().zip(vec_L_j_x) {
|
||||
@@ -175,7 +196,7 @@ pub mod tests {
|
||||
assert_eq!(lcccs.v.len(), 3);
|
||||
|
||||
// Bad compute L_j(x) with the bad z
|
||||
let vec_L_j_x = lcccs.compute_Ls(&ccs, &bad_z);
|
||||
let vec_L_j_x = compute_Ls(&ccs, &lcccs, &bad_z);
|
||||
assert_eq!(vec_L_j_x.len(), lcccs.v.len());
|
||||
|
||||
// Make sure that the LCCCS is not satisfied given these L_j(x)
|
||||
@@ -189,7 +210,6 @@ pub mod tests {
|
||||
satisfied = false;
|
||||
}
|
||||
}
|
||||
|
||||
assert!(!satisfied);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user