Skip to content

Commit 7a30c3b

Browse files
author
Kunming Jiang
committed
More efficient custom_dense_poly construction
1 parent abe0522 commit 7a30c3b

File tree

3 files changed

+39
-27
lines changed

3 files changed

+39
-27
lines changed

spartan_parallel/src/custom_dense_mlpoly.rs

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#![allow(clippy::too_many_arguments)]
2-
use std::cmp::min;
2+
use std::cmp::{max, min};
3+
use std::mem;
34

45
use crate::dense_mlpoly::DensePolynomial;
56
use crate::scalar::SpartanExtensionField;
@@ -63,40 +64,51 @@ impl<S: SpartanExtensionField> DensePolynomialPqx<S> {
6364
// Assume z_mat is in its standard form of (p, q, x)
6465
// Reverse q and x and convert it to (p, q_rev, x_rev)
6566
pub fn new_rev(
66-
z_mat: &Vec<Vec<Vec<Vec<S>>>>,
67+
mut z_mat: Vec<Vec<Vec<Vec<S>>>>,
6768
num_proofs: Vec<usize>,
6869
max_num_proofs: usize,
6970
num_inputs: Vec<usize>,
7071
max_num_inputs: usize,
7172
) -> Self {
72-
let mut Z = Vec::new();
7373
let num_instances = z_mat.len();
7474
let num_witness_secs = z_mat[0][0].len();
7575
for p in 0..num_instances {
76-
Z.push(vec![
77-
vec![
78-
vec![S::field_zero(); num_inputs[p]];
79-
num_witness_secs
80-
];
81-
num_proofs[p]
82-
]);
83-
84-
let step_q = max_num_proofs / num_proofs[p];
76+
// Reverse the bits of x in place
8577
let step_x = max_num_inputs / num_inputs[p];
86-
for q in 0..num_proofs[p] {
87-
// Reverse the bits of q. q_rev is a multiple of step_q
88-
let q_rev = rev_bits(q, max_num_proofs);
89-
// Now q_rev is between 0 to num_proofs[p]
90-
let q_rev = q_rev / step_q;
91-
92-
for x in 0..num_inputs[p] {
78+
let mut x_swapped = vec![false; num_inputs[p]];
79+
for x in 0..num_inputs[p] {
80+
if !x_swapped[x] {
9381
// Reverse the bits of x. x_rev is a multiple of step_x
9482
let x_rev = rev_bits(x, max_num_inputs);
9583
// Now x_rev is between 0 to num_inputs[p]
9684
let x_rev = x_rev / step_x;
97-
for w in 0..num_witness_secs {
98-
Z[p][q_rev][w][x_rev] = z_mat[p][q][w][x];
85+
for q in 0..num_proofs[p] {
86+
for w in 0..num_witness_secs {
87+
let tmp = z_mat[p][q][w][x];
88+
z_mat[p][q][w][x] = z_mat[p][q][w][x_rev];
89+
z_mat[p][q][w][x_rev] = tmp;
90+
}
9991
}
92+
x_swapped[x_rev] = true;
93+
}
94+
}
95+
// Reverse the bits of q
96+
let step_q = max_num_proofs / num_proofs[p];
97+
let mut q_swapped = vec![false; num_proofs[p]];
98+
for q in 0..num_proofs[p] {
99+
if !q_swapped[q] {
100+
// Reverse the bits of q. q_rev is a multiple of step_q
101+
let q_rev = rev_bits(q, max_num_proofs);
102+
// Now q_rev is between 0 to num_proofs[p]
103+
let q_rev = q_rev / step_q;
104+
if q != q_rev {
105+
let q_low = min(q, q_rev);
106+
let q_high = max(q, q_rev);
107+
let (left, right) = z_mat[p].split_at_mut(q_low + 1);
108+
mem::swap(&mut left[q_low], &mut right[q_high - q_low - 1]);
109+
}
110+
111+
q_swapped[q_rev] = true;
100112
}
101113
}
102114
}
@@ -107,7 +119,7 @@ impl<S: SpartanExtensionField> DensePolynomialPqx<S> {
107119
num_witness_secs: num_witness_secs.next_power_of_two(),
108120
num_inputs,
109121
max_num_inputs,
110-
Z,
122+
Z: z_mat,
111123
}
112124
}
113125

spartan_parallel/src/r1csinstance.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -285,21 +285,21 @@ impl<S: SpartanExtensionField + Send + Sync> R1CSInstance<S> {
285285

286286
(
287287
DensePolynomialPqx::new_rev(
288-
&Az,
288+
Az,
289289
num_proofs.clone(),
290290
max_num_proofs,
291291
num_cons.clone(),
292292
max_num_cons,
293293
),
294294
DensePolynomialPqx::new_rev(
295-
&Bz,
295+
Bz,
296296
num_proofs.clone(),
297297
max_num_proofs,
298298
num_cons.clone(),
299299
max_num_cons,
300300
),
301301
DensePolynomialPqx::new_rev(
302-
&Cz,
302+
Cz,
303303
num_proofs,
304304
max_num_proofs,
305305
num_cons.clone(),

spartan_parallel/src/r1csproof.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ impl<S: SpartanExtensionField + Send + Sync> R1CSProof<S> {
311311
evals_ABC
312312
};
313313
let mut ABC_poly = DensePolynomialPqx::new_rev(
314-
&evals_ABC,
314+
evals_ABC,
315315
vec![1; num_instances],
316316
1,
317317
num_inputs.clone(),
@@ -322,7 +322,7 @@ impl<S: SpartanExtensionField + Send + Sync> R1CSProof<S> {
322322
let timer_tmp = Timer::new("prove_z_gen");
323323
// Construct a p * q * len(z) matrix Z and bound it to r_q
324324
let mut Z_poly = DensePolynomialPqx::new_rev(
325-
&z_mat,
325+
z_mat,
326326
num_proofs.clone(),
327327
max_num_proofs,
328328
num_inputs.clone(),

0 commit comments

Comments
 (0)