Skip to content

Commit 19fbd6c

Browse files
committed
abstractions and refactoring, extract out tensor-iop-based-pcs trait
1 parent fec01ae commit 19fbd6c

File tree

5 files changed

+73
-95
lines changed

5 files changed

+73
-95
lines changed

pcs/src/orion.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use transcript::Transcript;
1010
use crate::PolynomialCommitmentScheme;
1111

1212
mod utils;
13-
pub use utils::{OrionPCSError, OrionResult};
13+
pub use utils::{OrionPCSError, OrionResult, SubsetSumLUTs, TensorIOPPCS};
1414

1515
mod linear_code;
1616
pub use linear_code::{OrionCodeParameter, ORION_CODE_PARAMETER_INSTANCE};

pcs/src/orion/pcs_impl.rs

+23-45
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::{orion::utils::SubsetSumLUTs, PCS_SOUNDNESS_BITS};
88

99
use super::{
1010
linear_code::{OrionCode, OrionCodeParameter},
11-
utils::{transpose_in_place, OrionPCSError, OrionResult},
11+
utils::{transpose_in_place, OrionPCSError, OrionResult, TensorIOPPCS},
1212
};
1313

1414
/**********************************************************
@@ -21,6 +21,16 @@ pub struct OrionPublicParams {
2121
pub code_instance: OrionCode,
2222
}
2323

24+
impl TensorIOPPCS for OrionPublicParams {
25+
fn codeword_len(&self) -> usize {
26+
self.code_instance.code_len()
27+
}
28+
29+
fn hamming_weight(&self) -> f64 {
30+
self.code_instance.hamming_weight()
31+
}
32+
}
33+
2434
#[derive(Clone, Debug)]
2535
pub struct OrionCommitmentWithData<F, ComPackF>
2636
where
@@ -53,17 +63,6 @@ pub struct OrionProof<EvalF: Field + FieldSerde> {
5363
}
5464

5565
impl OrionPublicParams {
56-
pub(crate) fn row_col_from_variables<F: Field>(num_variables: usize) -> (usize, usize) {
57-
let poly_variables: usize = num_variables;
58-
59-
let elems_for_smallest_tree = tree::leaf_adic::<F>() * 2;
60-
61-
let row_num: usize = elems_for_smallest_tree;
62-
let msg_size: usize = (1 << poly_variables) / row_num;
63-
64-
(row_num, msg_size)
65-
}
66-
6766
pub fn new<F: Field>(num_variables: usize, code_instance: OrionCode) -> OrionResult<Self> {
6867
let (_, msg_size) = Self::row_col_from_variables::<F>(num_variables);
6968
if msg_size != code_instance.msg_len() {
@@ -91,28 +90,6 @@ impl OrionPublicParams {
9190
}
9291
}
9392

94-
pub fn code_len(&self) -> usize {
95-
self.code_instance.code_len()
96-
}
97-
98-
pub fn query_complexity(&self, soundness_bits: usize) -> usize {
99-
// NOTE: use Ligero (AHIV22) or Avg-case dist to a code (BKS18)
100-
// version of avg case dist in unique decoding technique.
101-
let avg_case_dist = self.code_instance.hamming_weight() / 3f64;
102-
let sec_bits = -(1f64 - avg_case_dist).log2();
103-
104-
(soundness_bits as f64 / sec_bits).ceil() as usize
105-
}
106-
107-
pub fn proximity_repetition_num(&self, soundness_bits: usize, field_size_bits: usize) -> usize {
108-
// NOTE: use Ligero (AHIV22) or Avg-case dist to a code (BKS18)
109-
// version of avg case dist in unique decoding technique.
110-
// Here is the probability union bound
111-
let code_len_over_f_bits = field_size_bits - self.code_instance.code_len().ilog2() as usize;
112-
113-
(soundness_bits as f64 / code_len_over_f_bits as f64).ceil() as usize
114-
}
115-
11693
pub fn commit<F, ComPackF>(
11794
&self,
11895
poly: &MultiLinearPoly<F>,
@@ -146,17 +123,18 @@ impl OrionPublicParams {
146123
drop(scratch);
147124

148125
// NOTE: packed codeword buffer and encode over packed field
149-
let mut packed_interleaved_codewords = vec![ComPackF::ZERO; packed_rows * self.code_len()];
126+
let mut packed_interleaved_codewords =
127+
vec![ComPackF::ZERO; packed_rows * self.codeword_len()];
150128
packed_evals
151129
.chunks(msg_size)
152-
.zip(packed_interleaved_codewords.chunks_mut(self.code_len()))
130+
.zip(packed_interleaved_codewords.chunks_mut(self.codeword_len()))
153131
.try_for_each(|(evals, codeword)| {
154132
self.code_instance.encode_in_place(evals, codeword)
155133
})?;
156134
drop(packed_evals);
157135

158136
// NOTE: transpose codeword s.t., the matrix has codewords being columns
159-
let mut scratch = vec![ComPackF::ZERO; packed_rows * self.code_len()];
137+
let mut scratch = vec![ComPackF::ZERO; packed_rows * self.codeword_len()];
160138
transpose_in_place(&mut packed_interleaved_codewords, &mut scratch, packed_rows);
161139
drop(scratch);
162140

@@ -225,9 +203,8 @@ impl OrionPublicParams {
225203

226204
// NOTE: draw random linear combination out
227205
// and compose proximity response(s) of tensor code IOP based PCS
228-
let proximity_repetitions =
229-
self.proximity_repetition_num(PCS_SOUNDNESS_BITS, EvalF::FIELD_SIZE);
230-
let mut proximity_rows = vec![vec![EvalF::ZERO; msg_size]; proximity_repetitions];
206+
let proximity_test_num = self.proximity_repetitions::<EvalF>(PCS_SOUNDNESS_BITS);
207+
let mut proximity_rows = vec![vec![EvalF::ZERO; msg_size]; proximity_test_num];
231208

232209
proximity_rows.iter_mut().for_each(|row_buffer| {
233210
let random_coeffs = transcript.generate_challenge_field_elements(row_num);
@@ -238,6 +215,7 @@ impl OrionPublicParams {
238215
.zip(row_buffer.iter_mut())
239216
.for_each(|(p_col, res)| *res = luts.lookup_and_sum(p_col));
240217
});
218+
drop(luts);
241219

242220
// NOTE: working on evaluation on top of evaluation response
243221
let mut scratch = vec![EvalF::ZERO; msg_size];
@@ -246,6 +224,7 @@ impl OrionPublicParams {
246224
&point[..num_of_vars_in_msg],
247225
&mut scratch,
248226
);
227+
drop(scratch);
249228

250229
// NOTE: MT opening for point queries
251230
let leaf_range = row_num / tree::leaf_adic::<F>();
@@ -254,7 +233,7 @@ impl OrionPublicParams {
254233
let query_openings = query_indices
255234
.iter()
256235
.map(|qi| {
257-
let index = *qi % self.code_len();
236+
let index = *qi % self.codeword_len();
258237
let left = index * leaf_range;
259238
let right = left + leaf_range - 1;
260239

@@ -305,8 +284,7 @@ impl OrionPublicParams {
305284

306285
// NOTE: working on proximity responses, draw random linear combinations
307286
// then draw query points from fiat shamir transcripts
308-
let proximity_test_num =
309-
self.proximity_repetition_num(PCS_SOUNDNESS_BITS, EvalF::FIELD_SIZE);
287+
let proximity_test_num = self.proximity_repetitions::<EvalF>(PCS_SOUNDNESS_BITS);
310288
let random_linear_combinations: Vec<Vec<EvalF>> = (0..proximity_test_num)
311289
.map(|_| transcript.generate_challenge_field_elements(row_num))
312290
.collect();
@@ -320,7 +298,7 @@ impl OrionPublicParams {
320298
.iter()
321299
.zip(proof.query_openings.iter())
322300
.all(|(&qi, range_path)| {
323-
let index = qi % self.code_len();
301+
let index = qi % self.codeword_len();
324302
range_path.verify(commitment) && index == range_path.left / leaf_range
325303
});
326304
if !mt_consistency {
@@ -363,7 +341,7 @@ impl OrionPublicParams {
363341
.iter()
364342
.zip(packed_interleaved_alphabets.iter())
365343
.all(|(&qi, interleaved_alphabet)| {
366-
let index = qi % self.code_len();
344+
let index = qi % self.codeword_len();
367345
let alphabet = luts.lookup_and_sum(interleaved_alphabet);
368346
alphabet == codeword[index]
369347
})

pcs/src/orion/tests.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use polynomials::MultiLinearPoly;
88
use crate::orion::{
99
linear_code::{OrionCode, ORION_CODE_PARAMETER_INSTANCE},
1010
pcs_impl::{OrionCommitment, OrionCommitmentWithData, OrionPublicParams},
11-
utils::{transpose_in_place, SubsetSumLUTs},
11+
utils::{transpose_in_place, SubsetSumLUTs, TensorIOPPCS},
1212
};
1313

1414
fn column_combination<F, PackF>(mat: &[F], combination: &[F]) -> Vec<F>
@@ -95,7 +95,7 @@ where
9595
.flat_map(|msg| orion_pp.code_instance.encode(&msg).unwrap())
9696
.collect();
9797

98-
let mut scratch = vec![F::ZERO; row_num * orion_pp.code_len()];
98+
let mut scratch = vec![F::ZERO; row_num * orion_pp.codeword_len()];
9999
transpose_in_place(&mut interleaved_codewords, &mut scratch, row_num);
100100
drop(scratch);
101101

pcs/src/orion/utils.rs

+38-36
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use std::ops::Mul;
2-
31
use arith::{Field, FieldSerdeError, SimdField};
42
use thiserror::Error;
53

@@ -48,44 +46,48 @@ pub(crate) fn transpose_in_place<F: Field>(mat: &mut [F], scratch: &mut [F], row
4846
mat.copy_from_slice(scratch);
4947
}
5048

49+
/**********************************
50+
* TENSOR IOP BASED PCS UTILITIES *
51+
**********************************/
52+
53+
pub trait TensorIOPPCS {
54+
fn codeword_len(&self) -> usize;
55+
56+
fn hamming_weight(&self) -> f64;
57+
58+
fn row_col_from_variables<F: Field>(num_vars: usize) -> (usize, usize) {
59+
let elems_for_smallest_tree = tree::leaf_adic::<F>() * 2;
60+
61+
let row_num: usize = elems_for_smallest_tree;
62+
let msg_size: usize = (1 << num_vars) / row_num;
63+
64+
(row_num, msg_size)
65+
}
66+
67+
fn query_complexity(&self, soundness_bits: usize) -> usize {
68+
// NOTE: use Ligero (AHIV22) or Avg-case dist to a code (BKS18)
69+
// version of avg case dist in unique decoding technique.
70+
let avg_case_dist = self.hamming_weight() / 3f64;
71+
let sec_bits = -(1f64 - avg_case_dist).log2();
72+
73+
(soundness_bits as f64 / sec_bits).ceil() as usize
74+
}
75+
76+
fn proximity_repetitions<F: Field>(&self, soundness_bits: usize) -> usize {
77+
// NOTE: use Ligero (AHIV22) or Avg-case dist to a code (BKS18)
78+
// version of avg case dist in unique decoding technique.
79+
// Here is the probability union bound
80+
let single_run_soundness_bits = F::FIELD_SIZE - self.codeword_len().ilog2() as usize;
81+
82+
(soundness_bits as f64 / single_run_soundness_bits as f64).ceil() as usize
83+
}
84+
}
85+
5186
/*********************
5287
* LINEAR OPERATIONS *
5388
*********************/
5489

55-
#[allow(unused)]
56-
#[inline]
57-
pub(crate) fn simd_inner_prod<F0, F1, IPPackF0, IPPackF1>(
58-
l: &[F0],
59-
r: &[F1],
60-
scratch_pl: &mut [IPPackF0],
61-
scratch_pr: &mut [IPPackF1],
62-
) -> F1
63-
where
64-
F0: Field,
65-
F1: Field + From<F0> + Mul<F0, Output = F1>,
66-
IPPackF0: SimdField<Scalar = F0>,
67-
IPPackF1: SimdField<Scalar = F1> + Mul<IPPackF0, Output = IPPackF1>,
68-
{
69-
scratch_pl
70-
.iter_mut()
71-
.zip(l.chunks(IPPackF0::PACK_SIZE))
72-
.for_each(|(pl, ls)| *pl = IPPackF0::pack(ls));
73-
74-
scratch_pr
75-
.iter_mut()
76-
.zip(r.chunks(IPPackF1::PACK_SIZE))
77-
.for_each(|(pr, rs)| *pr = IPPackF1::pack(rs));
78-
79-
let simd_sum: IPPackF1 = scratch_pl
80-
.iter()
81-
.zip(scratch_pr.iter())
82-
.map(|(pl, pr)| *pr * *pl)
83-
.sum();
84-
85-
simd_sum.unpack().iter().sum()
86-
}
87-
88-
pub(crate) struct SubsetSumLUTs<F: Field> {
90+
pub struct SubsetSumLUTs<F: Field> {
8991
pub entry_bits: usize,
9092
pub tables: Vec<Vec<F>>,
9193
}

pcs/tests/test_orion.rs

+9-11
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,16 @@ where
2626
let mut rng = test_rng();
2727
let poly = MultiLinearPoly::<F>::random(params.num_vars, &mut rng);
2828

29-
(0..5).for_each(|_| {
30-
let opening_point: Vec<_> = (0..params.num_vars)
31-
.map(|_| EvalF::random_unsafe(&mut rng))
32-
.collect();
29+
let opening_point: Vec<_> = (0..params.num_vars)
30+
.map(|_| EvalF::random_unsafe(&mut rng))
31+
.collect();
3332

34-
common::test_pcs_e2e::<OrionPCS<F, EvalF, ComPackF, OpenPackF, T>>(
35-
&params,
36-
&poly,
37-
&opening_point,
38-
&mut rng,
39-
);
40-
})
33+
common::test_pcs_e2e::<OrionPCS<F, EvalF, ComPackF, OpenPackF, T>>(
34+
&params,
35+
&poly,
36+
&opening_point,
37+
&mut rng,
38+
);
4139
}
4240

4341
#[test]

0 commit comments

Comments
 (0)