Skip to content

Commit

Permalink
saffron/storage_proof: use eval challenge to combine commitments
Browse files Browse the repository at this point in the history
  • Loading branch information
marcbeunardeau88 committed Feb 12, 2025
1 parent b9a9a0e commit 0c8bf15
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 34 deletions.
24 changes: 5 additions & 19 deletions saffron/src/commitment.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
use ark_ec::AffineRepr;
use ark_ff::One;
use ark_ff::Zero;

use ark_poly::{Evaluations, Radix2EvaluationDomain as D};
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
use kimchi::curve::KimchiCurve;
use mina_poseidon::FqSponge;
use poly_commitment::{
commitment::{absorb_commitment, CommitmentCurve},
ipa::SRS,
PolyComm, SRS as _,
};
use poly_commitment::{commitment::CommitmentCurve, ipa::SRS, PolyComm, SRS as _};
use rayon::prelude::*;
use serde::{Deserialize, Serialize};
use serde_with::serde_as;
Expand All @@ -21,24 +17,14 @@ use tracing::instrument;
#[serde(bound = "G::ScalarField: CanonicalDeserialize + CanonicalSerialize")]
pub struct Commitment<G: CommitmentCurve> {
pub chunks: Vec<PolyComm<G>>,
#[serde_as(as = "o1_utils::serialization::SerdeAs")]
// TODO: we don't want to store alpha and folded anymore
// We'll delete that in a follow-up commit
pub alpha: G::ScalarField,
pub folded: PolyComm<G>,
}

impl<G: KimchiCurve> Commitment<G> {
pub fn from_chunks<EFqSponge>(chunks: Vec<PolyComm<G>>, sponge: &mut EFqSponge) -> Self
pub fn from_chunks<EFqSponge>(chunks: Vec<PolyComm<G>>, _sponge: &mut EFqSponge) -> Self
where
EFqSponge: FqSponge<G::BaseField, G, G::ScalarField>,
{
let folded: PolyComm<G> = fold_commitments::<_, EFqSponge>(G::ScalarField::zero(), &chunks);
Self {
chunks,
alpha: G::ScalarField::zero(),
folded,
}
Self { chunks }
}

pub fn update<EFqSponge>(&self, diff: Vec<PolyComm<G>>, sponge: &mut EFqSponge) -> Self
Expand Down Expand Up @@ -71,7 +57,7 @@ where
}

#[instrument(skip_all, level = "debug")]
fn fold_commitments<G: AffineRepr, EFqSponge: FqSponge<G::BaseField, G, G::ScalarField>>(
pub fn fold_commitments<G: AffineRepr, EFqSponge: FqSponge<G::BaseField, G, G::ScalarField>>(
alpha: G::ScalarField,
commitments: &[PolyComm<G>],
) -> PolyComm<G> {
Expand Down
13 changes: 9 additions & 4 deletions saffron/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,12 @@ fn encode_file(args: cli::EncodeFileArgs) -> Result<()> {
rmp_serde::from_slice(&asserted.0).expect("failed to decode asserted commitment");

assert_eq!(
blob.commitment.folded,
blob.commitment,
asserted_commitment,
"commitment mismatch: asserted {}, computed {}",
asserted,
HexString(
rmp_serde::encode::to_vec(&blob.commitment.folded)
.expect("failed to encode commitment")
rmp_serde::encode::to_vec(&blob.commitment).expect("failed to encode commitment")
)
);
};
Expand All @@ -115,7 +114,7 @@ pub fn compute_commitment(args: cli::ComputeCommitmentArgs) -> Result<HexString>
let mut writer = File::create(args.output)?;
rmp_serde::encode::write(&mut writer, &commitment)?;
}
let c = rmp_serde::encode::to_vec(&commitment.folded)?;
let c = rmp_serde::encode::to_vec(&commitment)?;
Ok(HexString(c))
}

Expand All @@ -133,6 +132,9 @@ pub fn storage_proof(args: cli::StorageProofArgs) -> Result<HexString> {
blob,
evaluation_point,
&mut rng,
// We can reuse the same challenge to combine commitment
// and to choose the eval point
evaluation_point,
)
};
let res = rmp_serde::to_vec(&proof)?;
Expand All @@ -153,6 +155,9 @@ pub fn verify_storage_proof(args: cli::VerifyStorageProofArgs) -> Result<()> {
evaluation_point,
&proof,
&mut rng,
// We can reuse the same challenge to combine commitment
// and to choose the eval point
evaluation_point,
);
assert!(res);
Ok(())
Expand Down
26 changes: 15 additions & 11 deletions saffron/src/proof.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use crate::blob::FieldBlob;
use crate::{
blob::FieldBlob,
commitment::{fold_commitments, Commitment},
};
use ark_ec::AffineRepr;
use ark_ff::{One, PrimeField, Zero};
use ark_poly::{univariate::DensePolynomial, Polynomial, Radix2EvaluationDomain as D};
Expand Down Expand Up @@ -33,6 +36,7 @@ pub fn storage_proof<G: KimchiCurve, EFqSponge: Clone + FqSponge<G::BaseField, G
blob: FieldBlob<G>,
evaluation_point: G::ScalarField,
rng: &mut OsRng,
alpha: G::ScalarField,
) -> StorageProof<G>
where
G::BaseField: PrimeField,
Expand All @@ -42,10 +46,7 @@ where
blob.chunks
.into_iter()
.fold(init, |(acc_poly, curr_power), curr_poly| {
(
acc_poly + curr_poly.scale(curr_power),
curr_power * blob.commitment.alpha,
)
(acc_poly + curr_poly.scale(curr_power), curr_power * alpha)
})
.0
};
Expand All @@ -68,7 +69,7 @@ where
},
)],
&[evaluation_point],
G::ScalarField::one(), // Single evaluation, so we don't care
G::ScalarField::one(), // Single polynomial, so we don't care
G::ScalarField::one(), // Single evaluation, so we don't care
opening_proof_sponge,
rng,
Expand All @@ -86,17 +87,18 @@ pub fn verify_storage_proof<
>(
srs: &SRS<G>,
group_map: &G::Map,
commitment: PolyComm<G>,
commitment: Commitment<G>,
evaluation_point: G::ScalarField,
proof: &StorageProof<G>,
rng: &mut OsRng,
alpha: G::ScalarField,
) -> bool
where
G::BaseField: PrimeField,
{
let mut opening_proof_sponge = EFqSponge::new(G::other_curve_sponge_params());
opening_proof_sponge.absorb_fr(&[proof.evaluation]);

let combined_commitment = fold_commitments::<_, EFqSponge>(alpha, &commitment.chunks);
srs.verify(
group_map,
&mut [BatchEvaluationProof {
Expand All @@ -105,7 +107,7 @@ where
polyscale: G::ScalarField::one(),
evalscale: G::ScalarField::one(),
evaluations: vec![Evaluation {
commitment,
commitment: combined_commitment,
evaluations: vec![vec![proof.evaluation]],
}],
opening: &proof.opening_proof,
Expand Down Expand Up @@ -159,17 +161,19 @@ mod tests {
};
let blob = FieldBlob::<Vesta>::encode::<_, VestaFqSponge>(&*SRS, *DOMAIN, &data);
let evaluation_point = Fp::rand(&mut rng);
let alpha = Fp::rand(&mut rng);
let proof = storage_proof::<
Vesta, VestaFqSponge

>(&*SRS, &*GROUP_MAP, blob, evaluation_point, &mut rng);
>(&*SRS, &*GROUP_MAP, blob, evaluation_point, &mut rng, alpha);
let res = verify_storage_proof::<Vesta, VestaFqSponge>(
&*SRS,
&*GROUP_MAP,
commitment.folded,
commitment,
evaluation_point,
&proof,
&mut rng,
alpha,
);
prop_assert!(res);
}
Expand Down

0 comments on commit 0c8bf15

Please sign in to comment.