ark_poly_commit/linear_codes/multilinear_ligero/
mod.rs

1use crate::{
2    linear_codes::{
3        utils::{reed_solomon, tensor_vec},
4        LigeroPCParams, LinearEncode,
5    },
6    Error,
7};
8use ark_crypto_primitives::{
9    crh::{CRHScheme, TwoToOneCRHScheme},
10    merkle_tree::Config,
11};
12use ark_ff::{FftField, PrimeField};
13use ark_poly::{MultilinearExtension, Polynomial};
14#[cfg(not(feature = "std"))]
15use ark_std::vec::Vec;
16use ark_std::{log2, marker::PhantomData};
17
18mod tests;
19
20/// The multilinear Ligero polynomial commitment scheme based on [[Ligero]][ligero].
21/// The scheme defaults to the naive batching strategy.
22///
23/// Note: The scheme currently does not support hiding.
24///
25/// [ligero]: https://eprint.iacr.org/2022/1608.pdf
26pub struct MultilinearLigero<F: PrimeField, C: Config, P: MultilinearExtension<F>, H: CRHScheme> {
27    _phantom: PhantomData<(F, C, P, H)>,
28}
29
30impl<F, C, P, H> LinearEncode<F, C, P, H> for MultilinearLigero<F, C, P, H>
31where
32    F: PrimeField + FftField,
33    C: Config,
34    P: MultilinearExtension<F>,
35    <P as Polynomial<F>>::Point: Into<Vec<F>>,
36    H: CRHScheme,
37{
38    type LinCodePCParams = LigeroPCParams<F, C, H>;
39
40    fn setup<R>(
41        _max_degree: usize,
42        _num_vars: Option<usize>,
43        _rng: &mut R,
44        leaf_hash_param: <<C as Config>::LeafHash as CRHScheme>::Parameters,
45        two_to_one_hash_param: <<C as Config>::TwoToOneHash as TwoToOneCRHScheme>::Parameters,
46        col_hash_params: H::Parameters,
47    ) -> Self::LinCodePCParams {
48        Self::LinCodePCParams::new(
49            128,
50            2,
51            true,
52            leaf_hash_param,
53            two_to_one_hash_param,
54            col_hash_params,
55        )
56    }
57
58    fn encode(msg: &[F], param: &Self::LinCodePCParams) -> Result<Vec<F>, Error> {
59        Ok(reed_solomon(msg, param.rho_inv))
60    }
61
62    fn poly_to_vec(polynomial: &P) -> Vec<F> {
63        polynomial.to_evaluations()
64    }
65
66    fn point_to_vec(point: <P as Polynomial<F>>::Point) -> Vec<F> {
67        point
68    }
69
70    /// For a multilinear polynomial in n+m variables it returns a tuple for k={n,m}:
71    /// ((1-z_1)*(1-z_2)*...*(1_z_k), z_1*(1-z_2)*...*(1-z_k), ..., z_1*z_2*...*z_k)
72    fn tensor(
73        point: &<P as Polynomial<F>>::Point,
74        left_len: usize,
75        _right_len: usize,
76    ) -> (Vec<F>, Vec<F>) {
77        let point: Vec<F> = Self::point_to_vec(point.clone());
78
79        let split = log2(left_len) as usize;
80        let left = &point[..split];
81        let right = &point[split..];
82        (tensor_vec(left), tensor_vec(right))
83    }
84}