ark_poly_commit/linear_codes/multilinear_brakedown/
mod.rs1use crate::Error;
2
3use super::utils::tensor_vec;
4use super::{BrakedownPCParams, LinearEncode};
5use ark_crypto_primitives::{
6 crh::{CRHScheme, TwoToOneCRHScheme},
7 merkle_tree::Config,
8};
9use ark_ff::{Field, PrimeField};
10use ark_poly::{MultilinearExtension, Polynomial};
11#[cfg(not(feature = "std"))]
12use ark_std::vec::Vec;
13use ark_std::{log2, marker::PhantomData, rand::RngCore};
14
15mod tests;
16
17pub struct MultilinearBrakedown<F: PrimeField, C: Config, P: MultilinearExtension<F>, H: CRHScheme>
24{
25 _phantom: PhantomData<(F, C, P, H)>,
26}
27
28impl<F, C, P, H> LinearEncode<F, C, P, H> for MultilinearBrakedown<F, C, P, H>
29where
30 F: PrimeField,
31 C: Config,
32 P: MultilinearExtension<F>,
33 <P as Polynomial<F>>::Point: Into<Vec<F>>,
34 H: CRHScheme,
35{
36 type LinCodePCParams = BrakedownPCParams<F, C, H>;
37
38 fn setup<R: RngCore>(
39 _max_degree: usize,
40 num_vars: Option<usize>,
41 rng: &mut R,
42 leaf_hash_param: <<C as Config>::LeafHash as CRHScheme>::Parameters,
43 two_to_one_hash_param: <<C as Config>::TwoToOneHash as TwoToOneCRHScheme>::Parameters,
44 col_hash_params: H::Parameters,
45 ) -> Self::LinCodePCParams {
46 Self::LinCodePCParams::default(
47 rng,
48 1 << num_vars.unwrap(),
49 true,
50 leaf_hash_param,
51 two_to_one_hash_param,
52 col_hash_params,
53 )
54 }
55
56 fn encode(msg: &[F], pp: &Self::LinCodePCParams) -> Result<Vec<F>, Error> {
57 if msg.len() != pp.m {
58 return Err(Error::EncodingError);
59 }
60 let cw_len = pp.m_ext;
61 let mut cw = Vec::with_capacity(cw_len);
62 cw.extend_from_slice(msg);
63
64 for (i, &s) in pp.start.iter().enumerate() {
66 let mut src = pp.a_mats[i].row_mul(&cw[s - pp.a_dims[i].0..s]);
67 cw.append(&mut src);
68 }
69
70 cw.resize(cw_len, F::zero());
72 let rss = *pp.start.last().unwrap_or(&0);
74 let rsie = rss + pp.a_dims.last().unwrap_or(&(0, pp.m, 0)).1;
75 let rsoe = *pp.end.last().unwrap_or(&cw_len);
76 naive_reed_solomon(&mut cw, rss, rsie, rsoe);
77
78 for (i, (&s, &e)) in pp.start.iter().zip(&pp.end).enumerate() {
80 let src = &pp.b_mats[i].row_mul(&cw[s..e]);
81 cw[e..e + pp.b_dims[i].1].copy_from_slice(src);
82 }
83 Ok(cw.to_vec())
84 }
85
86 fn poly_to_vec(polynomial: &P) -> Vec<F> {
87 polynomial.to_evaluations()
88 }
89
90 fn point_to_vec(point: <P as Polynomial<F>>::Point) -> Vec<F> {
91 point
92 }
93
94 fn tensor(
97 point: &<P as Polynomial<F>>::Point,
98 left_len: usize,
99 _right_len: usize,
100 ) -> (Vec<F>, Vec<F>) {
101 let point: Vec<F> = Self::point_to_vec(point.clone());
102
103 let split = log2(left_len) as usize;
104 let left = &point[..split];
105 let right = &point[split..];
106 (tensor_vec(left), tensor_vec(right))
107 }
108}
109
110fn naive_reed_solomon<F: Field>(cw: &mut [F], s: usize, ie: usize, oe: usize) {
112 let mut res = vec![F::zero(); oe - s];
113 let mut x = F::one();
114 for r in res.iter_mut() {
115 for j in (s..ie).rev() {
116 *r *= x;
117 *r += cw[j];
118 }
119 x += F::one();
120 }
121 cw[s..oe].copy_from_slice(&res);
122}