1
1
#![ allow( clippy:: too_many_arguments) ]
2
- use std:: cmp:: min;
2
+ use std:: cmp:: { max, min} ;
3
+ use std:: mem;
3
4
4
5
use crate :: dense_mlpoly:: DensePolynomial ;
5
6
use crate :: scalar:: SpartanExtensionField ;
@@ -63,40 +64,51 @@ impl<S: SpartanExtensionField> DensePolynomialPqx<S> {
63
64
// Assume z_mat is in its standard form of (p, q, x)
64
65
// Reverse q and x and convert it to (p, q_rev, x_rev)
65
66
pub fn new_rev (
66
- z_mat : & Vec < Vec < Vec < Vec < S > > > > ,
67
+ mut z_mat : Vec < Vec < Vec < Vec < S > > > > ,
67
68
num_proofs : Vec < usize > ,
68
69
max_num_proofs : usize ,
69
70
num_inputs : Vec < usize > ,
70
71
max_num_inputs : usize ,
71
72
) -> Self {
72
- let mut Z = Vec :: new ( ) ;
73
73
let num_instances = z_mat. len ( ) ;
74
74
let num_witness_secs = z_mat[ 0 ] [ 0 ] . len ( ) ;
75
75
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
85
77
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] {
93
81
// Reverse the bits of x. x_rev is a multiple of step_x
94
82
let x_rev = rev_bits ( x, max_num_inputs) ;
95
83
// Now x_rev is between 0 to num_inputs[p]
96
84
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
+ }
99
91
}
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 ;
100
112
}
101
113
}
102
114
}
@@ -107,7 +119,7 @@ impl<S: SpartanExtensionField> DensePolynomialPqx<S> {
107
119
num_witness_secs : num_witness_secs. next_power_of_two ( ) ,
108
120
num_inputs,
109
121
max_num_inputs,
110
- Z ,
122
+ Z : z_mat ,
111
123
}
112
124
}
113
125
0 commit comments