sonobe/folding-schemes/src/utils/mod.rs
folding-schemes/src/utils/mod.rsRaw
1use std::path::Path;
2use std::path::PathBuf;
3
4use ark_crypto_primitives::sponge::poseidon::PoseidonConfig;
5use ark_ec::{AffineRepr, CurveGroup};
6use ark_ff::PrimeField;
7use ark_serialize::CanonicalSerialize;
8use ark_std::Zero;
9use sha3::{Digest, Sha3_256};
10
11use crate::arith::ArithSerializer;
12use crate::commitment::CommitmentScheme;
13use crate::Error;
14
15pub mod gadgets;
16pub mod hypercube;
17pub mod lagrange_poly;
18pub mod mle;
19pub mod vec;
20
21// expose espresso local modules
22pub mod espresso;
23pub use crate::utils::espresso::multilinear_polynomial;
24pub use crate::utils::espresso::sum_check;
25pub use crate::utils::espresso::virtual_polynomial;
26
27/// For a given x, returns [1, x^1, x^2, ..., x^n-1];
28pub fn powers_of<F: PrimeField>(x: F, n: usize) -> Vec<F> {
29 let mut c: Vec<F> = vec![F::zero(); n];
30 c[0] = F::one();
31 for i in 1..n {
32 c[i] = c[i - 1] * x;
33 }
34 c
35}
36
37/// returns the coordinates of a commitment point. This is compatible with the arkworks
38/// GC.to_constraint_field()[..2]
39pub fn get_cm_coordinates<C: CurveGroup>(cm: &C) -> Vec<C::BaseField> {
40 let zero = (&C::BaseField::zero(), &C::BaseField::zero());
41 let cm = cm.into_affine();
42 let (cm_x, cm_y) = cm.xy().unwrap_or(zero);
43 vec![*cm_x, *cm_y]
44}
45
46/// returns the hash of the given public parameters of the Folding Scheme
47pub fn pp_hash<C1, C2, CS1, CS2, const H: bool>(
48 arith: &impl ArithSerializer,
49 cf_arith: &impl ArithSerializer,
50 cs_vp: &CS1::VerifierParams,
51 cf_cs_vp: &CS2::VerifierParams,
52 poseidon_config: &PoseidonConfig<C1::ScalarField>,
53) -> Result<C1::ScalarField, Error>
54where
55 C1: CurveGroup,
56 C2: CurveGroup,
57 CS1: CommitmentScheme<C1, H>,
58 CS2: CommitmentScheme<C2, H>,
59{
60 let mut hasher = Sha3_256::new();
61
62 // Fr & Fq modulus bit size
63 hasher.update(C1::ScalarField::MODULUS_BIT_SIZE.to_le_bytes());
64 hasher.update(C2::ScalarField::MODULUS_BIT_SIZE.to_le_bytes());
65 // AugmentedFCircuit Arith params
66 hasher.update(arith.params_to_le_bytes());
67 // CycleFold Circuit Arith params
68 hasher.update(cf_arith.params_to_le_bytes());
69 // cs_vp & cf_cs_vp (commitments setup)
70 let mut cs_vp_bytes = Vec::new();
71 cs_vp.serialize_uncompressed(&mut cs_vp_bytes)?;
72 hasher.update(cs_vp_bytes);
73 let mut cf_cs_vp_bytes = Vec::new();
74 cf_cs_vp.serialize_uncompressed(&mut cf_cs_vp_bytes)?;
75 hasher.update(cf_cs_vp_bytes);
76 // poseidon params
77 let mut poseidon_config_bytes = Vec::new();
78 poseidon_config
79 .full_rounds
80 .serialize_uncompressed(&mut poseidon_config_bytes)?;
81 poseidon_config
82 .partial_rounds
83 .serialize_uncompressed(&mut poseidon_config_bytes)?;
84 poseidon_config
85 .alpha
86 .serialize_uncompressed(&mut poseidon_config_bytes)?;
87 poseidon_config
88 .ark
89 .serialize_uncompressed(&mut poseidon_config_bytes)?;
90 poseidon_config
91 .mds
92 .serialize_uncompressed(&mut poseidon_config_bytes)?;
93 poseidon_config
94 .rate
95 .serialize_uncompressed(&mut poseidon_config_bytes)?;
96 poseidon_config
97 .capacity
98 .serialize_uncompressed(&mut poseidon_config_bytes)?;
99 hasher.update(poseidon_config_bytes);
100
101 let public_params_hash = hasher.finalize();
102 Ok(C1::ScalarField::from_le_bytes_mod_order(
103 &public_params_hash,
104 ))
105}
106
107/// Tiny utility enum that allows to import circuits and wasm modules from files by passing their path
108/// or passing their content already read.
109///
110/// This enum implements the [`From`] trait for both [`Path`], [`PathBuf`] and [`Vec<u8>`].
111#[derive(Debug, Clone)]
112pub enum PathOrBin {
113 Path(PathBuf),
114 Bin(Vec<u8>),
115}
116
117impl From<&Path> for PathOrBin {
118 fn from(value: &Path) -> Self {
119 PathOrBin::Path(value.into())
120 }
121}
122
123impl From<PathBuf> for PathOrBin {
124 fn from(value: PathBuf) -> Self {
125 PathOrBin::Path(value)
126 }
127}
128
129impl From<Vec<u8>> for PathOrBin {
130 fn from(value: Vec<u8>) -> Self {
131 PathOrBin::Bin(value)
132 }
133}