mirror of https://github.com/zcash/halo2.git
Replace ChallengeSpace with EncodedChallenge API
Co-authored-by: Sean Bowe <ewillbefull@gmail.com>
This commit is contained in:
parent
85c5f4412d
commit
32f011d52d
|
@ -6,7 +6,7 @@ use halo2::arithmetic::FieldExt;
|
||||||
use halo2::pasta::{EqAffine, Fp};
|
use halo2::pasta::{EqAffine, Fp};
|
||||||
use halo2::plonk::*;
|
use halo2::plonk::*;
|
||||||
use halo2::poly::{commitment::Params, Rotation};
|
use halo2::poly::{commitment::Params, Rotation};
|
||||||
use halo2::transcript::{Blake2bRead, Blake2bWrite, ChallengeScalarEndo};
|
use halo2::transcript::{Blake2bRead, Blake2bWrite, Challenge255};
|
||||||
|
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
@ -256,7 +256,7 @@ fn bench_with_k(name: &str, k: u32, c: &mut Criterion) {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create a proof
|
// Create a proof
|
||||||
let mut transcript = Blake2bWrite::<_, _, ChallengeScalarEndo<EqAffine>>::init(vec![]);
|
let mut transcript = Blake2bWrite::<_, _, Challenge255>::init(vec![]);
|
||||||
create_proof(¶ms, &pk, &[circuit], &[&[]], &mut transcript)
|
create_proof(¶ms, &pk, &[circuit], &[&[]], &mut transcript)
|
||||||
.expect("proof generation should not fail")
|
.expect("proof generation should not fail")
|
||||||
});
|
});
|
||||||
|
@ -268,7 +268,7 @@ fn bench_with_k(name: &str, k: u32, c: &mut Criterion) {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create a proof
|
// Create a proof
|
||||||
let mut transcript = Blake2bWrite::<_, _, ChallengeScalarEndo<EqAffine>>::init(vec![]);
|
let mut transcript = Blake2bWrite::<_, _, Challenge255>::init(vec![]);
|
||||||
create_proof(¶ms, &pk, &[circuit], &[&[]], &mut transcript)
|
create_proof(¶ms, &pk, &[circuit], &[&[]], &mut transcript)
|
||||||
.expect("proof generation should not fail");
|
.expect("proof generation should not fail");
|
||||||
let proof = transcript.finalize();
|
let proof = transcript.finalize();
|
||||||
|
@ -276,8 +276,7 @@ fn bench_with_k(name: &str, k: u32, c: &mut Criterion) {
|
||||||
c.bench_function(&verifier_name, |b| {
|
c.bench_function(&verifier_name, |b| {
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let msm = params.empty_msm();
|
let msm = params.empty_msm();
|
||||||
let mut transcript =
|
let mut transcript = Blake2bRead::<_, _, Challenge255>::init(&proof[..]);
|
||||||
Blake2bRead::<_, _, ChallengeScalarEndo<EqAffine>>::init(&proof[..]);
|
|
||||||
let guard = verify_proof(¶ms, pk.get_vk(), msm, &[&[]], &mut transcript).unwrap();
|
let guard = verify_proof(¶ms, pk.get_vk(), msm, &[&[]], &mut transcript).unwrap();
|
||||||
let msm = guard.clone().use_challenges();
|
let msm = guard.clone().use_challenges();
|
||||||
assert!(msm.eval());
|
assert!(msm.eval());
|
||||||
|
|
|
@ -8,7 +8,7 @@ use halo2::{
|
||||||
Error, VerifyingKey,
|
Error, VerifyingKey,
|
||||||
},
|
},
|
||||||
poly::commitment::Params,
|
poly::commitment::Params,
|
||||||
transcript::{Blake2bRead, Blake2bWrite, ChallengeScalarEndo},
|
transcript::{Blake2bRead, Blake2bWrite, Challenge255},
|
||||||
};
|
};
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
|
@ -128,7 +128,7 @@ fn bench(name: &str, k: u32, c: &mut Criterion) {
|
||||||
// Create a proof
|
// Create a proof
|
||||||
let proof_path = Path::new("./benches/sha256_assets/sha256_proof");
|
let proof_path = Path::new("./benches/sha256_assets/sha256_proof");
|
||||||
if File::open(&proof_path).is_err() {
|
if File::open(&proof_path).is_err() {
|
||||||
let mut transcript = Blake2bWrite::<_, _, ChallengeScalarEndo<EqAffine>>::init(vec![]);
|
let mut transcript = Blake2bWrite::<_, _, Challenge255>::init(vec![]);
|
||||||
create_proof(¶ms, &pk, &[circuit], &[], &mut transcript)
|
create_proof(¶ms, &pk, &[circuit], &[], &mut transcript)
|
||||||
.expect("proof generation should not fail");
|
.expect("proof generation should not fail");
|
||||||
let proof: Vec<u8> = transcript.finalize();
|
let proof: Vec<u8> = transcript.finalize();
|
||||||
|
@ -145,8 +145,7 @@ fn bench(name: &str, k: u32, c: &mut Criterion) {
|
||||||
c.bench_function(&verifier_name, |b| {
|
c.bench_function(&verifier_name, |b| {
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let msm = params.empty_msm();
|
let msm = params.empty_msm();
|
||||||
let mut transcript =
|
let mut transcript = Blake2bRead::<_, _, Challenge255>::init(&proof[..]);
|
||||||
Blake2bRead::<_, _, ChallengeScalarEndo<EqAffine>>::init(&proof[..]);
|
|
||||||
let guard = verify_proof(¶ms, pk.get_vk(), msm, &[], &mut transcript).unwrap();
|
let guard = verify_proof(¶ms, pk.get_vk(), msm, &[], &mut transcript).unwrap();
|
||||||
let msm = guard.clone().use_challenges();
|
let msm = guard.clone().use_challenges();
|
||||||
assert!(msm.eval());
|
assert!(msm.eval());
|
||||||
|
|
|
@ -12,7 +12,7 @@ use crate::poly::{
|
||||||
commitment::Params, Coeff, EvaluationDomain, ExtendedLagrangeCoeff, LagrangeCoeff,
|
commitment::Params, Coeff, EvaluationDomain, ExtendedLagrangeCoeff, LagrangeCoeff,
|
||||||
PinnedEvaluationDomain, Polynomial,
|
PinnedEvaluationDomain, Polynomial,
|
||||||
};
|
};
|
||||||
use crate::transcript::{ChallengeScalar, ChallengeSpace, Transcript};
|
use crate::transcript::{ChallengeScalar, EncodedChallenge, Transcript};
|
||||||
|
|
||||||
mod circuit;
|
mod circuit;
|
||||||
mod keygen;
|
mod keygen;
|
||||||
|
@ -79,7 +79,7 @@ impl<C: CurveAffine> VerifyingKey<C> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Hashes a verification key into a transcript.
|
/// Hashes a verification key into a transcript.
|
||||||
pub fn hash_into<S: ChallengeSpace<C>, T: Transcript<C, S>>(
|
pub fn hash_into<E: EncodedChallenge<C, [u8; 64]>, T: Transcript<C, [u8; 64], E>>(
|
||||||
&self,
|
&self,
|
||||||
transcript: &mut T,
|
transcript: &mut T,
|
||||||
) -> io::Result<()> {
|
) -> io::Result<()> {
|
||||||
|
|
|
@ -10,7 +10,7 @@ use crate::{
|
||||||
multiopen::ProverQuery,
|
multiopen::ProverQuery,
|
||||||
Coeff, EvaluationDomain, ExtendedLagrangeCoeff, LagrangeCoeff, Polynomial, Rotation,
|
Coeff, EvaluationDomain, ExtendedLagrangeCoeff, LagrangeCoeff, Polynomial, Rotation,
|
||||||
},
|
},
|
||||||
transcript::{ChallengeSpace, TranscriptWrite},
|
transcript::{EncodedChallenge, TranscriptWrite},
|
||||||
};
|
};
|
||||||
use ff::Field;
|
use ff::Field;
|
||||||
use group::Curve;
|
use group::Curve;
|
||||||
|
@ -72,7 +72,13 @@ impl<F: FieldExt> Argument<F> {
|
||||||
/// - constructs Permuted<C> struct using permuted_input_value = A', and
|
/// - constructs Permuted<C> struct using permuted_input_value = A', and
|
||||||
/// permuted_table_expression = S'.
|
/// permuted_table_expression = S'.
|
||||||
/// The Permuted<C> struct is used to update the Lookup, and is then returned.
|
/// The Permuted<C> struct is used to update the Lookup, and is then returned.
|
||||||
pub(in crate::plonk) fn commit_permuted<'a, C, S: ChallengeSpace<C>, T: TranscriptWrite<C, S>>(
|
pub(in crate::plonk) fn commit_permuted<
|
||||||
|
'a,
|
||||||
|
C,
|
||||||
|
I,
|
||||||
|
E: EncodedChallenge<C, I>,
|
||||||
|
T: TranscriptWrite<C, I, E>,
|
||||||
|
>(
|
||||||
&self,
|
&self,
|
||||||
pk: &ProvingKey<C>,
|
pk: &ProvingKey<C>,
|
||||||
params: &Params<C>,
|
params: &Params<C>,
|
||||||
|
@ -244,7 +250,11 @@ impl<C: CurveAffine> Permuted<C> {
|
||||||
/// grand product polynomial over the lookup. The grand product polynomial
|
/// grand product polynomial over the lookup. The grand product polynomial
|
||||||
/// is used to populate the Product<C> struct. The Product<C> struct is
|
/// is used to populate the Product<C> struct. The Product<C> struct is
|
||||||
/// added to the Lookup and finally returned by the method.
|
/// added to the Lookup and finally returned by the method.
|
||||||
pub(in crate::plonk) fn commit_product<S: ChallengeSpace<C>, T: TranscriptWrite<C, S>>(
|
pub(in crate::plonk) fn commit_product<
|
||||||
|
I,
|
||||||
|
E: EncodedChallenge<C, I>,
|
||||||
|
T: TranscriptWrite<C, I, E>,
|
||||||
|
>(
|
||||||
self,
|
self,
|
||||||
pk: &ProvingKey<C>,
|
pk: &ProvingKey<C>,
|
||||||
params: &Params<C>,
|
params: &Params<C>,
|
||||||
|
@ -488,7 +498,7 @@ impl<'a, C: CurveAffine> Committed<C> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: CurveAffine> Constructed<C> {
|
impl<C: CurveAffine> Constructed<C> {
|
||||||
pub(in crate::plonk) fn evaluate<S: ChallengeSpace<C>, T: TranscriptWrite<C, S>>(
|
pub(in crate::plonk) fn evaluate<I, E: EncodedChallenge<C, I>, T: TranscriptWrite<C, I, E>>(
|
||||||
self,
|
self,
|
||||||
pk: &ProvingKey<C>,
|
pk: &ProvingKey<C>,
|
||||||
x: ChallengeX<C>,
|
x: ChallengeX<C>,
|
||||||
|
|
|
@ -8,7 +8,7 @@ use crate::{
|
||||||
arithmetic::{CurveAffine, FieldExt},
|
arithmetic::{CurveAffine, FieldExt},
|
||||||
plonk::{Error, VerifyingKey},
|
plonk::{Error, VerifyingKey},
|
||||||
poly::{multiopen::VerifierQuery, Rotation},
|
poly::{multiopen::VerifierQuery, Rotation},
|
||||||
transcript::{ChallengeSpace, TranscriptRead},
|
transcript::{EncodedChallenge, TranscriptRead},
|
||||||
};
|
};
|
||||||
use ff::Field;
|
use ff::Field;
|
||||||
|
|
||||||
|
@ -34,8 +34,9 @@ pub struct Evaluated<C: CurveAffine> {
|
||||||
impl<F: FieldExt> Argument<F> {
|
impl<F: FieldExt> Argument<F> {
|
||||||
pub(in crate::plonk) fn read_permuted_commitments<
|
pub(in crate::plonk) fn read_permuted_commitments<
|
||||||
C: CurveAffine,
|
C: CurveAffine,
|
||||||
S: ChallengeSpace<C>,
|
I,
|
||||||
T: TranscriptRead<C, S>,
|
E: EncodedChallenge<C, I>,
|
||||||
|
T: TranscriptRead<C, I, E>,
|
||||||
>(
|
>(
|
||||||
&self,
|
&self,
|
||||||
transcript: &mut T,
|
transcript: &mut T,
|
||||||
|
@ -56,8 +57,9 @@ impl<F: FieldExt> Argument<F> {
|
||||||
|
|
||||||
impl<C: CurveAffine> PermutationCommitments<C> {
|
impl<C: CurveAffine> PermutationCommitments<C> {
|
||||||
pub(in crate::plonk) fn read_product_commitment<
|
pub(in crate::plonk) fn read_product_commitment<
|
||||||
S: ChallengeSpace<C>,
|
I,
|
||||||
T: TranscriptRead<C, S>,
|
E: EncodedChallenge<C, I>,
|
||||||
|
T: TranscriptRead<C, I, E>,
|
||||||
>(
|
>(
|
||||||
self,
|
self,
|
||||||
transcript: &mut T,
|
transcript: &mut T,
|
||||||
|
@ -74,7 +76,7 @@ impl<C: CurveAffine> PermutationCommitments<C> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: CurveAffine> Committed<C> {
|
impl<C: CurveAffine> Committed<C> {
|
||||||
pub(crate) fn evaluate<S: ChallengeSpace<C>, T: TranscriptRead<C, S>>(
|
pub(crate) fn evaluate<I, E: EncodedChallenge<C, I>, T: TranscriptRead<C, I, E>>(
|
||||||
self,
|
self,
|
||||||
transcript: &mut T,
|
transcript: &mut T,
|
||||||
) -> Result<Evaluated<C>, Error> {
|
) -> Result<Evaluated<C>, Error> {
|
||||||
|
|
|
@ -12,7 +12,7 @@ use crate::{
|
||||||
multiopen::ProverQuery,
|
multiopen::ProverQuery,
|
||||||
Coeff, ExtendedLagrangeCoeff, LagrangeCoeff, Polynomial, Rotation,
|
Coeff, ExtendedLagrangeCoeff, LagrangeCoeff, Polynomial, Rotation,
|
||||||
},
|
},
|
||||||
transcript::{ChallengeSpace, TranscriptWrite},
|
transcript::{EncodedChallenge, TranscriptWrite},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) struct Committed<C: CurveAffine> {
|
pub(crate) struct Committed<C: CurveAffine> {
|
||||||
|
@ -34,8 +34,9 @@ pub(crate) struct Evaluated<C: CurveAffine> {
|
||||||
impl Argument {
|
impl Argument {
|
||||||
pub(in crate::plonk) fn commit<
|
pub(in crate::plonk) fn commit<
|
||||||
C: CurveAffine,
|
C: CurveAffine,
|
||||||
S: ChallengeSpace<C>,
|
I,
|
||||||
T: TranscriptWrite<C, S>,
|
E: EncodedChallenge<C, I>,
|
||||||
|
T: TranscriptWrite<C, I, E>,
|
||||||
>(
|
>(
|
||||||
&self,
|
&self,
|
||||||
params: &Params<C>,
|
params: &Params<C>,
|
||||||
|
@ -257,7 +258,7 @@ impl<C: CurveAffine> super::ProvingKey<C> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: CurveAffine> Constructed<C> {
|
impl<C: CurveAffine> Constructed<C> {
|
||||||
pub(in crate::plonk) fn evaluate<S: ChallengeSpace<C>, T: TranscriptWrite<C, S>>(
|
pub(in crate::plonk) fn evaluate<I, E: EncodedChallenge<C, I>, T: TranscriptWrite<C, I, E>>(
|
||||||
self,
|
self,
|
||||||
pk: &plonk::ProvingKey<C>,
|
pk: &plonk::ProvingKey<C>,
|
||||||
pkey: &ProvingKey<C>,
|
pkey: &ProvingKey<C>,
|
||||||
|
|
|
@ -7,7 +7,7 @@ use crate::{
|
||||||
arithmetic::{CurveAffine, FieldExt},
|
arithmetic::{CurveAffine, FieldExt},
|
||||||
plonk::{self, Error},
|
plonk::{self, Error},
|
||||||
poly::{multiopen::VerifierQuery, Rotation},
|
poly::{multiopen::VerifierQuery, Rotation},
|
||||||
transcript::{ChallengeSpace, TranscriptRead},
|
transcript::{EncodedChallenge, TranscriptRead},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct Committed<C: CurveAffine> {
|
pub struct Committed<C: CurveAffine> {
|
||||||
|
@ -24,8 +24,9 @@ pub struct Evaluated<C: CurveAffine> {
|
||||||
impl Argument {
|
impl Argument {
|
||||||
pub(crate) fn read_product_commitment<
|
pub(crate) fn read_product_commitment<
|
||||||
C: CurveAffine,
|
C: CurveAffine,
|
||||||
S: ChallengeSpace<C>,
|
I,
|
||||||
T: TranscriptRead<C, S>,
|
E: EncodedChallenge<C, I>,
|
||||||
|
T: TranscriptRead<C, I, E>,
|
||||||
>(
|
>(
|
||||||
&self,
|
&self,
|
||||||
transcript: &mut T,
|
transcript: &mut T,
|
||||||
|
@ -41,7 +42,7 @@ impl Argument {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: CurveAffine> Committed<C> {
|
impl<C: CurveAffine> Committed<C> {
|
||||||
pub(crate) fn evaluate<S: ChallengeSpace<C>, T: TranscriptRead<C, S>>(
|
pub(crate) fn evaluate<I, E: EncodedChallenge<C, I>, T: TranscriptRead<C, I, E>>(
|
||||||
self,
|
self,
|
||||||
vkey: &VerifyingKey<C>,
|
vkey: &VerifyingKey<C>,
|
||||||
transcript: &mut T,
|
transcript: &mut T,
|
||||||
|
|
|
@ -12,15 +12,15 @@ use crate::poly::{
|
||||||
multiopen::{self, ProverQuery},
|
multiopen::{self, ProverQuery},
|
||||||
Coeff, ExtendedLagrangeCoeff, LagrangeCoeff, Polynomial,
|
Coeff, ExtendedLagrangeCoeff, LagrangeCoeff, Polynomial,
|
||||||
};
|
};
|
||||||
use crate::transcript::{ChallengeSpace, TranscriptWrite};
|
use crate::transcript::{EncodedChallenge, TranscriptWrite};
|
||||||
|
|
||||||
/// This creates a proof for the provided `circuit` when given the public
|
/// This creates a proof for the provided `circuit` when given the public
|
||||||
/// parameters `params` and the proving key [`ProvingKey`] that was
|
/// parameters `params` and the proving key [`ProvingKey`] that was
|
||||||
/// generated previously for the same circuit.
|
/// generated previously for the same circuit.
|
||||||
pub fn create_proof<
|
pub fn create_proof<
|
||||||
C: CurveAffine,
|
C: CurveAffine,
|
||||||
S: ChallengeSpace<C>,
|
E: EncodedChallenge<C, [u8; 64]>,
|
||||||
T: TranscriptWrite<C, S>,
|
T: TranscriptWrite<C, [u8; 64], E>,
|
||||||
ConcreteCircuit: Circuit<C::Scalar>,
|
ConcreteCircuit: Circuit<C::Scalar>,
|
||||||
>(
|
>(
|
||||||
params: &Params<C>,
|
params: &Params<C>,
|
||||||
|
|
|
@ -10,7 +10,7 @@ use crate::{
|
||||||
multiopen::ProverQuery,
|
multiopen::ProverQuery,
|
||||||
Coeff, EvaluationDomain, ExtendedLagrangeCoeff, Polynomial,
|
Coeff, EvaluationDomain, ExtendedLagrangeCoeff, Polynomial,
|
||||||
},
|
},
|
||||||
transcript::{ChallengeSpace, TranscriptWrite},
|
transcript::{EncodedChallenge, TranscriptWrite},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(in crate::plonk) struct Constructed<C: CurveAffine> {
|
pub(in crate::plonk) struct Constructed<C: CurveAffine> {
|
||||||
|
@ -23,7 +23,7 @@ pub(in crate::plonk) struct Evaluated<C: CurveAffine> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: CurveAffine> Argument<C> {
|
impl<C: CurveAffine> Argument<C> {
|
||||||
pub(in crate::plonk) fn construct<S: ChallengeSpace<C>, T: TranscriptWrite<C, S>>(
|
pub(in crate::plonk) fn construct<I, E: EncodedChallenge<C, I>, T: TranscriptWrite<C, I, E>>(
|
||||||
params: &Params<C>,
|
params: &Params<C>,
|
||||||
domain: &EvaluationDomain<C::Scalar>,
|
domain: &EvaluationDomain<C::Scalar>,
|
||||||
expressions: impl Iterator<Item = Polynomial<C::Scalar, ExtendedLagrangeCoeff>>,
|
expressions: impl Iterator<Item = Polynomial<C::Scalar, ExtendedLagrangeCoeff>>,
|
||||||
|
@ -69,7 +69,7 @@ impl<C: CurveAffine> Argument<C> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: CurveAffine> Constructed<C> {
|
impl<C: CurveAffine> Constructed<C> {
|
||||||
pub(in crate::plonk) fn evaluate<S: ChallengeSpace<C>, T: TranscriptWrite<C, S>>(
|
pub(in crate::plonk) fn evaluate<I, E: EncodedChallenge<C, I>, T: TranscriptWrite<C, I, E>>(
|
||||||
self,
|
self,
|
||||||
x: ChallengeX<C>,
|
x: ChallengeX<C>,
|
||||||
transcript: &mut T,
|
transcript: &mut T,
|
||||||
|
|
|
@ -4,7 +4,7 @@ use crate::{
|
||||||
arithmetic::CurveAffine,
|
arithmetic::CurveAffine,
|
||||||
plonk::{Error, VerifyingKey},
|
plonk::{Error, VerifyingKey},
|
||||||
poly::multiopen::VerifierQuery,
|
poly::multiopen::VerifierQuery,
|
||||||
transcript::{read_n_points, read_n_scalars, ChallengeSpace, TranscriptRead},
|
transcript::{read_n_points, read_n_scalars, EncodedChallenge, TranscriptRead},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::super::{ChallengeX, ChallengeY};
|
use super::super::{ChallengeX, ChallengeY};
|
||||||
|
@ -20,7 +20,11 @@ pub struct Evaluated<C: CurveAffine> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: CurveAffine> Argument<C> {
|
impl<C: CurveAffine> Argument<C> {
|
||||||
pub(in crate::plonk) fn read_commitments<S: ChallengeSpace<C>, T: TranscriptRead<C, S>>(
|
pub(in crate::plonk) fn read_commitments<
|
||||||
|
I,
|
||||||
|
E: EncodedChallenge<C, I>,
|
||||||
|
T: TranscriptRead<C, I, E>,
|
||||||
|
>(
|
||||||
vk: &VerifyingKey<C>,
|
vk: &VerifyingKey<C>,
|
||||||
transcript: &mut T,
|
transcript: &mut T,
|
||||||
) -> Result<Committed<C>, Error> {
|
) -> Result<Committed<C>, Error> {
|
||||||
|
@ -33,7 +37,7 @@ impl<C: CurveAffine> Argument<C> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: CurveAffine> Committed<C> {
|
impl<C: CurveAffine> Committed<C> {
|
||||||
pub(in crate::plonk) fn evaluate<S: ChallengeSpace<C>, T: TranscriptRead<C, S>>(
|
pub(in crate::plonk) fn evaluate<I, E: EncodedChallenge<C, I>, T: TranscriptRead<C, I, E>>(
|
||||||
self,
|
self,
|
||||||
transcript: &mut T,
|
transcript: &mut T,
|
||||||
) -> Result<Evaluated<C>, Error> {
|
) -> Result<Evaluated<C>, Error> {
|
||||||
|
|
|
@ -7,16 +7,21 @@ use crate::poly::{
|
||||||
commitment::{Guard, Params, MSM},
|
commitment::{Guard, Params, MSM},
|
||||||
multiopen::{self, VerifierQuery},
|
multiopen::{self, VerifierQuery},
|
||||||
};
|
};
|
||||||
use crate::transcript::{read_n_points, read_n_scalars, ChallengeSpace, TranscriptRead};
|
use crate::transcript::{read_n_points, read_n_scalars, EncodedChallenge, TranscriptRead};
|
||||||
|
|
||||||
/// Returns a boolean indicating whether or not the proof is valid
|
/// Returns a boolean indicating whether or not the proof is valid
|
||||||
pub fn verify_proof<'a, C: CurveAffine, S: ChallengeSpace<C>, T: TranscriptRead<C, S>>(
|
pub fn verify_proof<
|
||||||
|
'a,
|
||||||
|
C: CurveAffine,
|
||||||
|
E: EncodedChallenge<C, [u8; 64]>,
|
||||||
|
T: TranscriptRead<C, [u8; 64], E>,
|
||||||
|
>(
|
||||||
params: &'a Params<C>,
|
params: &'a Params<C>,
|
||||||
vk: &VerifyingKey<C>,
|
vk: &VerifyingKey<C>,
|
||||||
msm: MSM<'a, C>,
|
msm: MSM<'a, C>,
|
||||||
instance_commitments: &[&[C]],
|
instance_commitments: &[&[C]],
|
||||||
transcript: &mut T,
|
transcript: &mut T,
|
||||||
) -> Result<Guard<'a, C, S>, Error> {
|
) -> Result<Guard<'a, C, [u8; 64], E>, Error> {
|
||||||
// Check that instance_commitments matches the expected number of instance columns
|
// Check that instance_commitments matches the expected number of instance columns
|
||||||
for instance_commitments in instance_commitments.iter() {
|
for instance_commitments in instance_commitments.iter() {
|
||||||
if instance_commitments.len() != vk.cs.num_instance_columns {
|
if instance_commitments.len() != vk.cs.num_instance_columns {
|
||||||
|
|
|
@ -306,7 +306,7 @@ fn test_opening_proof() {
|
||||||
use crate::arithmetic::{eval_polynomial, FieldExt};
|
use crate::arithmetic::{eval_polynomial, FieldExt};
|
||||||
use crate::pasta::{EpAffine, Fq};
|
use crate::pasta::{EpAffine, Fq};
|
||||||
use crate::transcript::{
|
use crate::transcript::{
|
||||||
Blake2bRead, Blake2bWrite, ChallengeScalarEndo, Transcript, TranscriptRead, TranscriptWrite,
|
Blake2bRead, Blake2bWrite, Challenge255, Transcript, TranscriptRead, TranscriptWrite,
|
||||||
};
|
};
|
||||||
|
|
||||||
let params = Params::<EpAffine>::new(K);
|
let params = Params::<EpAffine>::new(K);
|
||||||
|
@ -326,8 +326,7 @@ fn test_opening_proof() {
|
||||||
|
|
||||||
let p = params.commit(&px, blind).to_affine();
|
let p = params.commit(&px, blind).to_affine();
|
||||||
|
|
||||||
let mut transcript =
|
let mut transcript = Blake2bWrite::<Vec<u8>, EpAffine, Challenge255>::init(vec![]);
|
||||||
Blake2bWrite::<Vec<u8>, EpAffine, ChallengeScalarEndo<EpAffine>>::init(vec![]);
|
|
||||||
transcript.write_point(p).unwrap();
|
transcript.write_point(p).unwrap();
|
||||||
let x = transcript.squeeze_challenge_scalar::<()>();
|
let x = transcript.squeeze_challenge_scalar::<()>();
|
||||||
// Evaluate the polynomial
|
// Evaluate the polynomial
|
||||||
|
@ -341,8 +340,7 @@ fn test_opening_proof() {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Verify the opening proof
|
// Verify the opening proof
|
||||||
let mut transcript =
|
let mut transcript = Blake2bRead::<&[u8], EpAffine, Challenge255>::init(&proof[..]);
|
||||||
Blake2bRead::<&[u8], EpAffine, ChallengeScalarEndo<EpAffine>>::init(&proof[..]);
|
|
||||||
let p_prime = transcript.read_point().unwrap();
|
let p_prime = transcript.read_point().unwrap();
|
||||||
assert_eq!(p, p_prime);
|
assert_eq!(p, p_prime);
|
||||||
let x_prime = transcript.squeeze_challenge_scalar::<()>();
|
let x_prime = transcript.squeeze_challenge_scalar::<()>();
|
||||||
|
|
|
@ -5,7 +5,7 @@ use super::{Blind, Params};
|
||||||
use crate::arithmetic::{
|
use crate::arithmetic::{
|
||||||
best_multiexp, compute_inner_product, eval_polynomial, parallelize, CurveAffine, FieldExt,
|
best_multiexp, compute_inner_product, eval_polynomial, parallelize, CurveAffine, FieldExt,
|
||||||
};
|
};
|
||||||
use crate::transcript::{ChallengeSpace, TranscriptWrite};
|
use crate::transcript::{EncodedChallenge, TranscriptWrite};
|
||||||
|
|
||||||
use group::Curve;
|
use group::Curve;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
@ -23,7 +23,7 @@ use std::io;
|
||||||
/// opening v, and the point x. It's probably also nice for the transcript
|
/// opening v, and the point x. It's probably also nice for the transcript
|
||||||
/// to have seen the elliptic curve description and the URS, if you want to
|
/// to have seen the elliptic curve description and the URS, if you want to
|
||||||
/// be rigorous.
|
/// be rigorous.
|
||||||
pub fn create_proof<C: CurveAffine, S: ChallengeSpace<C>, T: TranscriptWrite<C, S>>(
|
pub fn create_proof<C: CurveAffine, I, E: EncodedChallenge<C, I>, T: TranscriptWrite<C, I, E>>(
|
||||||
params: &Params<C>,
|
params: &Params<C>,
|
||||||
transcript: &mut T,
|
transcript: &mut T,
|
||||||
px: &Polynomial<C::Scalar, Coeff>,
|
px: &Polynomial<C::Scalar, Coeff>,
|
||||||
|
|
|
@ -1,33 +1,36 @@
|
||||||
use ff::Field;
|
use ff::Field;
|
||||||
use group::Curve;
|
use group::Curve;
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
use super::super::Error;
|
use super::super::Error;
|
||||||
use super::{Params, MSM};
|
use super::{Params, MSM};
|
||||||
use crate::transcript::{ChallengeSpace, TranscriptRead};
|
use crate::transcript::{EncodedChallenge, TranscriptRead};
|
||||||
|
|
||||||
use crate::arithmetic::{best_multiexp, BatchInvert, CurveAffine};
|
use crate::arithmetic::{best_multiexp, BatchInvert, CurveAffine};
|
||||||
|
|
||||||
/// A guard returned by the verifier
|
/// A guard returned by the verifier
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Guard<'a, C: CurveAffine, S: ChallengeSpace<C>> {
|
pub struct Guard<'a, C: CurveAffine, I, E: EncodedChallenge<C, I>> {
|
||||||
msm: MSM<'a, C>,
|
msm: MSM<'a, C>,
|
||||||
neg_a: C::Scalar,
|
neg_a: C::Scalar,
|
||||||
challenges: Vec<C::Scalar>,
|
challenges: Vec<C::Scalar>,
|
||||||
challenges_packed: Vec<S::Challenge>,
|
challenges_packed: Vec<E>,
|
||||||
|
_marker: PhantomData<I>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An accumulator instance consisting of an evaluation claim and a proof.
|
/// An accumulator instance consisting of an evaluation claim and a proof.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Accumulator<C: CurveAffine, S: ChallengeSpace<C>> {
|
pub struct Accumulator<C: CurveAffine, I, E: EncodedChallenge<C, I>> {
|
||||||
/// The claimed output of the linear-time polycommit opening protocol
|
/// The claimed output of the linear-time polycommit opening protocol
|
||||||
pub g: C,
|
pub g: C,
|
||||||
|
|
||||||
/// A vector of 128-bit challenges sampled by the verifier, to be used in
|
/// A vector of 128-bit challenges sampled by the verifier, to be used in
|
||||||
/// computing g.
|
/// computing g.
|
||||||
pub challenges_packed: Vec<S::Challenge>,
|
pub challenges_packed: Vec<E>,
|
||||||
|
_marker: PhantomData<I>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, C: CurveAffine, S: ChallengeSpace<C>> Guard<'a, C, S> {
|
impl<'a, C: CurveAffine, I, E: EncodedChallenge<C, I>> Guard<'a, C, I, E> {
|
||||||
/// Lets caller supply the challenges and obtain an MSM with updated
|
/// Lets caller supply the challenges and obtain an MSM with updated
|
||||||
/// scalars and points.
|
/// scalars and points.
|
||||||
pub fn use_challenges(mut self) -> MSM<'a, C> {
|
pub fn use_challenges(mut self) -> MSM<'a, C> {
|
||||||
|
@ -40,12 +43,13 @@ impl<'a, C: CurveAffine, S: ChallengeSpace<C>> Guard<'a, C, S> {
|
||||||
|
|
||||||
/// Lets caller supply the purported G point and simply appends
|
/// Lets caller supply the purported G point and simply appends
|
||||||
/// [-a] G to return an updated MSM.
|
/// [-a] G to return an updated MSM.
|
||||||
pub fn use_g(mut self, g: C) -> (MSM<'a, C>, Accumulator<C, S>) {
|
pub fn use_g(mut self, g: C) -> (MSM<'a, C>, Accumulator<C, I, E>) {
|
||||||
self.msm.append_term(self.neg_a, g);
|
self.msm.append_term(self.neg_a, g);
|
||||||
|
|
||||||
let accumulator = Accumulator {
|
let accumulator = Accumulator {
|
||||||
g,
|
g,
|
||||||
challenges_packed: self.challenges_packed,
|
challenges_packed: self.challenges_packed,
|
||||||
|
_marker: PhantomData,
|
||||||
};
|
};
|
||||||
|
|
||||||
(self.msm, accumulator)
|
(self.msm, accumulator)
|
||||||
|
@ -64,13 +68,19 @@ impl<'a, C: CurveAffine, S: ChallengeSpace<C>> Guard<'a, C, S> {
|
||||||
/// Checks to see if the proof represented within `transcript` is valid, and a
|
/// Checks to see if the proof represented within `transcript` is valid, and a
|
||||||
/// point `x` that the polynomial commitment `P` opens purportedly to the value
|
/// point `x` that the polynomial commitment `P` opens purportedly to the value
|
||||||
/// `v`. The provided `msm` should evaluate to the commitment `P` being opened.
|
/// `v`. The provided `msm` should evaluate to the commitment `P` being opened.
|
||||||
pub fn verify_proof<'a, C: CurveAffine, S: ChallengeSpace<C>, T: TranscriptRead<C, S>>(
|
pub fn verify_proof<
|
||||||
|
'a,
|
||||||
|
C: CurveAffine,
|
||||||
|
I,
|
||||||
|
E: EncodedChallenge<C, I>,
|
||||||
|
T: TranscriptRead<C, I, E>,
|
||||||
|
>(
|
||||||
params: &'a Params<C>,
|
params: &'a Params<C>,
|
||||||
mut msm: MSM<'a, C>,
|
mut msm: MSM<'a, C>,
|
||||||
transcript: &mut T,
|
transcript: &mut T,
|
||||||
x: C::Scalar,
|
x: C::Scalar,
|
||||||
v: C::Scalar,
|
v: C::Scalar,
|
||||||
) -> Result<Guard<'a, C, S>, Error> {
|
) -> Result<Guard<'a, C, I, E>, Error> {
|
||||||
let k = params.k as usize;
|
let k = params.k as usize;
|
||||||
|
|
||||||
// P - [v] G_0 + S * iota
|
// P - [v] G_0 + S * iota
|
||||||
|
@ -91,7 +101,7 @@ pub fn verify_proof<'a, C: CurveAffine, S: ChallengeSpace<C>, T: TranscriptRead<
|
||||||
let r = transcript.read_point().map_err(|_| Error::OpeningError)?;
|
let r = transcript.read_point().map_err(|_| Error::OpeningError)?;
|
||||||
|
|
||||||
let challenge_packed = transcript.squeeze_challenge();
|
let challenge_packed = transcript.squeeze_challenge();
|
||||||
let challenge = *S::to_challenge_scalar::<()>(challenge_packed);
|
let challenge = *T::as_challenge_scalar::<()>(&challenge_packed);
|
||||||
|
|
||||||
rounds.push((
|
rounds.push((
|
||||||
l,
|
l,
|
||||||
|
@ -108,7 +118,7 @@ pub fn verify_proof<'a, C: CurveAffine, S: ChallengeSpace<C>, T: TranscriptRead<
|
||||||
.batch_invert();
|
.batch_invert();
|
||||||
|
|
||||||
let mut challenges = Vec::with_capacity(k);
|
let mut challenges = Vec::with_capacity(k);
|
||||||
let mut challenges_packed: Vec<S::Challenge> = Vec::with_capacity(k);
|
let mut challenges_packed: Vec<E> = Vec::with_capacity(k);
|
||||||
for (l, r, challenge, challenge_inv, challenge_packed) in rounds {
|
for (l, r, challenge, challenge_inv, challenge_packed) in rounds {
|
||||||
msm.append_term(challenge_inv, l);
|
msm.append_term(challenge_inv, l);
|
||||||
msm.append_term(challenge, r);
|
msm.append_term(challenge, r);
|
||||||
|
@ -143,6 +153,7 @@ pub fn verify_proof<'a, C: CurveAffine, S: ChallengeSpace<C>, T: TranscriptRead<
|
||||||
neg_a,
|
neg_a,
|
||||||
challenges,
|
challenges,
|
||||||
challenges_packed,
|
challenges_packed,
|
||||||
|
_marker: PhantomData,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(guard)
|
Ok(guard)
|
||||||
|
|
|
@ -211,7 +211,7 @@ fn test_roundtrip() {
|
||||||
use super::commitment::{Blind, Params};
|
use super::commitment::{Blind, Params};
|
||||||
use crate::arithmetic::{eval_polynomial, FieldExt};
|
use crate::arithmetic::{eval_polynomial, FieldExt};
|
||||||
use crate::pasta::{EqAffine, Fp};
|
use crate::pasta::{EqAffine, Fp};
|
||||||
use crate::transcript::ChallengeScalarEndo;
|
use crate::transcript::Challenge255;
|
||||||
|
|
||||||
const K: u32 = 4;
|
const K: u32 = 4;
|
||||||
|
|
||||||
|
@ -245,8 +245,7 @@ fn test_roundtrip() {
|
||||||
let bvx = eval_polynomial(&bx, x);
|
let bvx = eval_polynomial(&bx, x);
|
||||||
let cvy = eval_polynomial(&cx, y);
|
let cvy = eval_polynomial(&cx, y);
|
||||||
|
|
||||||
let mut transcript =
|
let mut transcript = crate::transcript::Blake2bWrite::<_, _, Challenge255>::init(vec![]);
|
||||||
crate::transcript::Blake2bWrite::<_, _, ChallengeScalarEndo<EqAffine>>::init(vec![]);
|
|
||||||
create_proof(
|
create_proof(
|
||||||
¶ms,
|
¶ms,
|
||||||
&mut transcript,
|
&mut transcript,
|
||||||
|
@ -272,8 +271,7 @@ fn test_roundtrip() {
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut proof = &proof[..];
|
let mut proof = &proof[..];
|
||||||
let mut transcript =
|
let mut transcript = crate::transcript::Blake2bRead::<_, _, Challenge255>::init(&mut proof);
|
||||||
crate::transcript::Blake2bRead::<_, _, ChallengeScalarEndo<EqAffine>>::init(&mut proof);
|
|
||||||
let msm = params.empty_msm();
|
let msm = params.empty_msm();
|
||||||
|
|
||||||
let guard = verify_proof(
|
let guard = verify_proof(
|
||||||
|
@ -306,8 +304,7 @@ fn test_roundtrip() {
|
||||||
{
|
{
|
||||||
let mut proof = &proof[..];
|
let mut proof = &proof[..];
|
||||||
|
|
||||||
let mut transcript =
|
let mut transcript = crate::transcript::Blake2bRead::<_, _, Challenge255>::init(&mut proof);
|
||||||
crate::transcript::Blake2bRead::<_, _, ChallengeScalarEndo<EqAffine>>::init(&mut proof);
|
|
||||||
let msm = params.empty_msm();
|
let msm = params.empty_msm();
|
||||||
|
|
||||||
let guard = verify_proof(
|
let guard = verify_proof(
|
||||||
|
|
|
@ -8,7 +8,7 @@ use super::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::arithmetic::{eval_polynomial, kate_division, CurveAffine, FieldExt};
|
use crate::arithmetic::{eval_polynomial, kate_division, CurveAffine, FieldExt};
|
||||||
use crate::transcript::{ChallengeSpace, TranscriptWrite};
|
use crate::transcript::{EncodedChallenge, TranscriptWrite};
|
||||||
|
|
||||||
use ff::Field;
|
use ff::Field;
|
||||||
use group::Curve;
|
use group::Curve;
|
||||||
|
@ -24,7 +24,14 @@ struct CommitmentData<C: CurveAffine> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a multi-opening proof
|
/// Create a multi-opening proof
|
||||||
pub fn create_proof<'a, I, C: CurveAffine, S: ChallengeSpace<C>, T: TranscriptWrite<C, S>>(
|
pub fn create_proof<
|
||||||
|
'a,
|
||||||
|
I,
|
||||||
|
IN,
|
||||||
|
C: CurveAffine,
|
||||||
|
E: EncodedChallenge<C, IN>,
|
||||||
|
T: TranscriptWrite<C, IN, E>,
|
||||||
|
>(
|
||||||
params: &Params<C>,
|
params: &Params<C>,
|
||||||
transcript: &mut T,
|
transcript: &mut T,
|
||||||
queries: I,
|
queries: I,
|
||||||
|
|
|
@ -9,7 +9,7 @@ use super::{
|
||||||
VerifierQuery,
|
VerifierQuery,
|
||||||
};
|
};
|
||||||
use crate::arithmetic::{eval_polynomial, lagrange_interpolate, CurveAffine, FieldExt};
|
use crate::arithmetic::{eval_polynomial, lagrange_interpolate, CurveAffine, FieldExt};
|
||||||
use crate::transcript::{ChallengeSpace, TranscriptRead};
|
use crate::transcript::{EncodedChallenge, TranscriptRead};
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct CommitmentData<C: CurveAffine> {
|
struct CommitmentData<C: CurveAffine> {
|
||||||
set_index: usize,
|
set_index: usize,
|
||||||
|
@ -18,12 +18,20 @@ struct CommitmentData<C: CurveAffine> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Verify a multi-opening proof
|
/// Verify a multi-opening proof
|
||||||
pub fn verify_proof<'b, 'a: 'b, I, C: CurveAffine, S: ChallengeSpace<C>, T: TranscriptRead<C, S>>(
|
pub fn verify_proof<
|
||||||
|
'b,
|
||||||
|
'a: 'b,
|
||||||
|
I,
|
||||||
|
IN,
|
||||||
|
C: CurveAffine,
|
||||||
|
E: EncodedChallenge<C, IN>,
|
||||||
|
T: TranscriptRead<C, IN, E>,
|
||||||
|
>(
|
||||||
params: &'a Params<C>,
|
params: &'a Params<C>,
|
||||||
transcript: &mut T,
|
transcript: &mut T,
|
||||||
queries: I,
|
queries: I,
|
||||||
mut msm: MSM<'a, C>,
|
mut msm: MSM<'a, C>,
|
||||||
) -> Result<Guard<'a, C, S>, Error>
|
) -> Result<Guard<'a, C, IN, E>, Error>
|
||||||
where
|
where
|
||||||
I: IntoIterator<Item = VerifierQuery<'b, C>> + Clone,
|
I: IntoIterator<Item = VerifierQuery<'b, C>> + Clone,
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,14 +11,24 @@ use std::io::{self, Read, Write};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
/// Generic transcript view (from either the prover or verifier's perspective)
|
/// Generic transcript view (from either the prover or verifier's perspective)
|
||||||
pub trait Transcript<C: CurveAffine, S: ChallengeSpace<C>> {
|
pub trait Transcript<C: CurveAffine, I, E: EncodedChallenge<C, I>> {
|
||||||
/// Squeeze a verifier challenge from the transcript. The length of the
|
/// Squeeze an encoded verifier challenge from the transcript.
|
||||||
/// challenge is determined by the `ChallengeSpace`.
|
fn squeeze_challenge(&mut self) -> E;
|
||||||
fn squeeze_challenge(&mut self) -> S::Challenge;
|
|
||||||
|
|
||||||
/// Squeeze a challenge (in the scalar field) from the transcript.
|
/// Squeeze a typed challenge (in the scalar field) from the transcript.
|
||||||
fn squeeze_challenge_scalar<T>(&mut self) -> ChallengeScalar<C, T> {
|
fn squeeze_challenge_scalar<T>(&mut self) -> ChallengeScalar<C, T> {
|
||||||
S::to_challenge_scalar(self.squeeze_challenge())
|
ChallengeScalar {
|
||||||
|
inner: E::get_scalar(&self.squeeze_challenge()),
|
||||||
|
_marker: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Cast an encoded challenge as a typed `ChallengeScalar`.
|
||||||
|
fn as_challenge_scalar<T>(challenge: &E) -> ChallengeScalar<C, T> {
|
||||||
|
ChallengeScalar {
|
||||||
|
inner: E::get_scalar(challenge),
|
||||||
|
_marker: PhantomData,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Writing the point to the transcript without writing it to the proof,
|
/// Writing the point to the transcript without writing it to the proof,
|
||||||
|
@ -32,7 +42,9 @@ pub trait Transcript<C: CurveAffine, S: ChallengeSpace<C>> {
|
||||||
|
|
||||||
/// Transcript view from the perspective of a verifier that has access to an
|
/// Transcript view from the perspective of a verifier that has access to an
|
||||||
/// input stream of data from the prover to the verifier.
|
/// input stream of data from the prover to the verifier.
|
||||||
pub trait TranscriptRead<C: CurveAffine, S: ChallengeSpace<C>>: Transcript<C, S> {
|
pub trait TranscriptRead<C: CurveAffine, I, E: EncodedChallenge<C, I>>:
|
||||||
|
Transcript<C, I, E>
|
||||||
|
{
|
||||||
/// Read a curve point from the prover.
|
/// Read a curve point from the prover.
|
||||||
fn read_point(&mut self) -> io::Result<C>;
|
fn read_point(&mut self) -> io::Result<C>;
|
||||||
|
|
||||||
|
@ -42,7 +54,9 @@ pub trait TranscriptRead<C: CurveAffine, S: ChallengeSpace<C>>: Transcript<C, S>
|
||||||
|
|
||||||
/// Transcript view from the perspective of a prover that has access to an
|
/// Transcript view from the perspective of a prover that has access to an
|
||||||
/// output stream of messages from the prover to the verifier.
|
/// output stream of messages from the prover to the verifier.
|
||||||
pub trait TranscriptWrite<C: CurveAffine, S: ChallengeSpace<C>>: Transcript<C, S> {
|
pub trait TranscriptWrite<C: CurveAffine, I, E: EncodedChallenge<C, I>>:
|
||||||
|
Transcript<C, I, E>
|
||||||
|
{
|
||||||
/// Write a curve point to the proof and the transcript.
|
/// Write a curve point to the proof and the transcript.
|
||||||
fn write_point(&mut self, point: C) -> io::Result<()>;
|
fn write_point(&mut self, point: C) -> io::Result<()>;
|
||||||
|
|
||||||
|
@ -52,14 +66,14 @@ pub trait TranscriptWrite<C: CurveAffine, S: ChallengeSpace<C>>: Transcript<C, S
|
||||||
|
|
||||||
/// We will replace BLAKE2b with an algebraic hash function in a later version.
|
/// We will replace BLAKE2b with an algebraic hash function in a later version.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Blake2bRead<R: Read, C: CurveAffine, S: ChallengeSpace<C>> {
|
pub struct Blake2bRead<R: Read, C: CurveAffine, E: EncodedChallenge<C, [u8; 64]>> {
|
||||||
state: Blake2bState,
|
state: Blake2bState,
|
||||||
reader: R,
|
reader: R,
|
||||||
_marker: PhantomData<C>,
|
_marker: PhantomData<C>,
|
||||||
_marker_s: PhantomData<S>,
|
_marker_e: PhantomData<E>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: Read, C: CurveAffine, S: ChallengeSpace<C>> Blake2bRead<R, C, S> {
|
impl<R: Read, C: CurveAffine, E: EncodedChallenge<C, [u8; 64]>> Blake2bRead<R, C, E> {
|
||||||
/// Initialize a transcript given an input buffer and a key.
|
/// Initialize a transcript given an input buffer and a key.
|
||||||
pub fn init(reader: R) -> Self {
|
pub fn init(reader: R) -> Self {
|
||||||
Blake2bRead {
|
Blake2bRead {
|
||||||
|
@ -69,12 +83,14 @@ impl<R: Read, C: CurveAffine, S: ChallengeSpace<C>> Blake2bRead<R, C, S> {
|
||||||
.to_state(),
|
.to_state(),
|
||||||
reader,
|
reader,
|
||||||
_marker: PhantomData,
|
_marker: PhantomData,
|
||||||
_marker_s: PhantomData,
|
_marker_e: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: Read, C: CurveAffine, S: ChallengeSpace<C>> TranscriptRead<C, S> for Blake2bRead<R, C, S> {
|
impl<R: Read, C: CurveAffine, E: EncodedChallenge<C, [u8; 64]>> TranscriptRead<C, [u8; 64], E>
|
||||||
|
for Blake2bRead<R, C, E>
|
||||||
|
{
|
||||||
fn read_point(&mut self) -> io::Result<C> {
|
fn read_point(&mut self) -> io::Result<C> {
|
||||||
let mut compressed = C::Repr::default();
|
let mut compressed = C::Repr::default();
|
||||||
self.reader.read_exact(compressed.as_mut())?;
|
self.reader.read_exact(compressed.as_mut())?;
|
||||||
|
@ -101,14 +117,14 @@ impl<R: Read, C: CurveAffine, S: ChallengeSpace<C>> TranscriptRead<C, S> for Bla
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: Read, C: CurveAffine, S: ChallengeSpace<C>> Transcript<C, S> for Blake2bRead<R, C, S> {
|
impl<R: Read, C: CurveAffine, E: EncodedChallenge<C, [u8; 64]>> Transcript<C, [u8; 64], E>
|
||||||
fn squeeze_challenge(&mut self) -> S::Challenge {
|
for Blake2bRead<R, C, E>
|
||||||
|
{
|
||||||
|
fn squeeze_challenge(&mut self) -> E {
|
||||||
let hasher = self.state.clone();
|
let hasher = self.state.clone();
|
||||||
let mut result: [u8; 64] = hasher.finalize().as_bytes().try_into().unwrap();
|
let result: [u8; 64] = hasher.finalize().as_bytes().try_into().unwrap();
|
||||||
result[S::NUM_BYTES - 1] &= S::BYTE_MASK;
|
|
||||||
// self.state.update(&result[..S::NUM_BYTES]);
|
|
||||||
self.state.update(&result[..]);
|
self.state.update(&result[..]);
|
||||||
S::Challenge::new(&result[..S::NUM_BYTES])
|
E::new(&result)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn common_point(&mut self, point: C) -> io::Result<()> {
|
fn common_point(&mut self, point: C) -> io::Result<()> {
|
||||||
|
@ -133,14 +149,14 @@ impl<R: Read, C: CurveAffine, S: ChallengeSpace<C>> Transcript<C, S> for Blake2b
|
||||||
|
|
||||||
/// We will replace BLAKE2b with an algebraic hash function in a later version.
|
/// We will replace BLAKE2b with an algebraic hash function in a later version.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Blake2bWrite<W: Write, C: CurveAffine, S: ChallengeSpace<C>> {
|
pub struct Blake2bWrite<W: Write, C: CurveAffine, E: EncodedChallenge<C, [u8; 64]>> {
|
||||||
state: Blake2bState,
|
state: Blake2bState,
|
||||||
writer: W,
|
writer: W,
|
||||||
_marker: PhantomData<C>,
|
_marker: PhantomData<C>,
|
||||||
_marker_s: PhantomData<S>,
|
_marker_e: PhantomData<E>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<W: Write, C: CurveAffine, S: ChallengeSpace<C>> Blake2bWrite<W, C, S> {
|
impl<W: Write, C: CurveAffine, E: EncodedChallenge<C, [u8; 64]>> Blake2bWrite<W, C, E> {
|
||||||
/// Initialize a transcript given an output buffer and a key.
|
/// Initialize a transcript given an output buffer and a key.
|
||||||
pub fn init(writer: W) -> Self {
|
pub fn init(writer: W) -> Self {
|
||||||
Blake2bWrite {
|
Blake2bWrite {
|
||||||
|
@ -150,7 +166,7 @@ impl<W: Write, C: CurveAffine, S: ChallengeSpace<C>> Blake2bWrite<W, C, S> {
|
||||||
.to_state(),
|
.to_state(),
|
||||||
writer,
|
writer,
|
||||||
_marker: PhantomData,
|
_marker: PhantomData,
|
||||||
_marker_s: PhantomData,
|
_marker_e: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,8 +177,8 @@ impl<W: Write, C: CurveAffine, S: ChallengeSpace<C>> Blake2bWrite<W, C, S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<W: Write, C: CurveAffine, S: ChallengeSpace<C>> TranscriptWrite<C, S>
|
impl<W: Write, C: CurveAffine, E: EncodedChallenge<C, [u8; 64]>> TranscriptWrite<C, [u8; 64], E>
|
||||||
for Blake2bWrite<W, C, S>
|
for Blake2bWrite<W, C, E>
|
||||||
{
|
{
|
||||||
fn write_point(&mut self, point: C) -> io::Result<()> {
|
fn write_point(&mut self, point: C) -> io::Result<()> {
|
||||||
self.common_point(point)?;
|
self.common_point(point)?;
|
||||||
|
@ -176,14 +192,14 @@ impl<W: Write, C: CurveAffine, S: ChallengeSpace<C>> TranscriptWrite<C, S>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<W: Write, C: CurveAffine, S: ChallengeSpace<C>> Transcript<C, S> for Blake2bWrite<W, C, S> {
|
impl<W: Write, C: CurveAffine, E: EncodedChallenge<C, [u8; 64]>> Transcript<C, [u8; 64], E>
|
||||||
fn squeeze_challenge(&mut self) -> S::Challenge {
|
for Blake2bWrite<W, C, E>
|
||||||
|
{
|
||||||
|
fn squeeze_challenge(&mut self) -> E {
|
||||||
let hasher = self.state.clone();
|
let hasher = self.state.clone();
|
||||||
let mut result: [u8; 64] = hasher.finalize().as_bytes().try_into().unwrap();
|
let result: [u8; 64] = hasher.finalize().as_bytes().try_into().unwrap();
|
||||||
result[S::NUM_BYTES - 1] &= S::BYTE_MASK;
|
|
||||||
// self.state.update(&result[..S::NUM_BYTES]);
|
|
||||||
self.state.update(&result[..]);
|
self.state.update(&result[..]);
|
||||||
S::Challenge::new(&result[..S::NUM_BYTES])
|
E::new(&result)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn common_point(&mut self, point: C) -> io::Result<()> {
|
fn common_point(&mut self, point: C) -> io::Result<()> {
|
||||||
|
@ -212,42 +228,6 @@ pub trait Challenge: Copy + Clone + std::fmt::Debug {
|
||||||
fn new(challenge: &[u8]) -> Self;
|
fn new(challenge: &[u8]) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is a 16-byte verifier challenge.
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
|
||||||
pub struct Challenge16(pub(crate) [u8; 16]);
|
|
||||||
|
|
||||||
impl Challenge for Challenge16 {
|
|
||||||
fn new(challenge: &[u8]) -> Self {
|
|
||||||
Self(challenge.try_into().unwrap())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::ops::Deref for Challenge16 {
|
|
||||||
type Target = [u8; 16];
|
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
&self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This is a 64-byte verifier challenge.
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
|
||||||
pub struct Challenge64(pub(crate) [u8; 64]);
|
|
||||||
|
|
||||||
impl Challenge for Challenge64 {
|
|
||||||
fn new(challenge: &[u8]) -> Self {
|
|
||||||
Self(challenge.try_into().unwrap())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::ops::Deref for Challenge64 {
|
|
||||||
type Target = [u8; 64];
|
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
&self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The scalar representation of a verifier challenge.
|
/// The scalar representation of a verifier challenge.
|
||||||
///
|
///
|
||||||
/// The `Type` type can be used to scope the challenge to a specific context, or
|
/// The `Type` type can be used to scope the challenge to a specific context, or
|
||||||
|
@ -266,42 +246,41 @@ impl<C: CurveAffine, T> std::ops::Deref for ChallengeScalar<C, T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The challenge space used to sample a scalar from a 512-bit challenge.
|
/// `EncodedChallenge<C, I>` defines a challenge encoding where `I` is the input
|
||||||
/// This protocol supports implementations for `ChallengeScalarEndo`, which
|
/// that is used to derive the challenge encoding and `get_challenge` obtains
|
||||||
/// uses an endomorphism, and `ChallengeScalarFull`, which samples the
|
/// the _real_ `C::Scalar` that the challenge encoding represents.
|
||||||
/// full-width field.
|
pub trait EncodedChallenge<C: CurveAffine, I> {
|
||||||
pub trait ChallengeSpace<C: CurveAffine>: Copy + Clone + std::fmt::Debug {
|
/// Get an encoded challenge from a given input challenge.
|
||||||
/// TODO
|
fn new(challenge_input: &I) -> Self;
|
||||||
const NUM_BYTES: usize;
|
|
||||||
/// TODO
|
|
||||||
const BYTE_MASK: u8;
|
|
||||||
/// TODO
|
|
||||||
type Challenge: Challenge;
|
|
||||||
|
|
||||||
/// Derive a scalar from a challenge in a certain challenge space.
|
/// Get a scalar field element from an encoded challenge.
|
||||||
fn to_challenge_scalar<T>(challenge: Self::Challenge) -> ChallengeScalar<C, T>;
|
fn get_scalar(challenge: &Self) -> C::Scalar;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The scalar challenge space that applies the mapping of Algorithm 1 from the
|
/// The scalar challenge space that applies the mapping of Algorithm 1 from the
|
||||||
/// [Halo](https://eprint.iacr.org/2019/1021) paper.
|
/// [Halo](https://eprint.iacr.org/2019/1021) paper.
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub struct ChallengeScalarEndo<C: CurveAffine> {
|
pub struct Challenge128(u128);
|
||||||
_marker: PhantomData<C>,
|
|
||||||
|
impl std::ops::Deref for Challenge128 {
|
||||||
|
type Target = u128;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: CurveAffine> ChallengeSpace<C> for ChallengeScalarEndo<C> {
|
impl<C: CurveAffine> EncodedChallenge<C, C::Base> for Challenge128 {
|
||||||
const NUM_BYTES: usize = 16;
|
fn new(challenge_input: &C::Base) -> Self {
|
||||||
const BYTE_MASK: u8 = 0b11111111;
|
Challenge128(challenge_input.get_lower_128())
|
||||||
type Challenge = Challenge16;
|
}
|
||||||
|
|
||||||
fn to_challenge_scalar<T>(challenge: Self::Challenge) -> ChallengeScalar<C, T> {
|
fn get_scalar(challenge: &Self) -> C::Scalar {
|
||||||
let mut acc = (C::Scalar::ZETA + &C::Scalar::one()).double();
|
let mut acc = (C::Scalar::ZETA + &C::Scalar::one()).double();
|
||||||
|
|
||||||
let challenge: u128 = u128::from_le_bytes(challenge.0);
|
|
||||||
|
|
||||||
for i in (0..64).rev() {
|
for i in (0..64).rev() {
|
||||||
let should_negate = ((challenge >> ((i << 1) + 1)) & 1) == 1;
|
let should_negate = ((challenge.0 >> ((i << 1) + 1)) & 1) == 1;
|
||||||
let should_endo = ((challenge >> (i << 1)) & 1) == 1;
|
let should_endo = ((challenge.0 >> (i << 1)) & 1) == 1;
|
||||||
|
|
||||||
let q = if should_negate {
|
let q = if should_negate {
|
||||||
-C::Scalar::one()
|
-C::Scalar::one()
|
||||||
|
@ -312,40 +291,49 @@ impl<C: CurveAffine> ChallengeSpace<C> for ChallengeScalarEndo<C> {
|
||||||
acc = acc + &q + &acc;
|
acc = acc + &q + &acc;
|
||||||
}
|
}
|
||||||
|
|
||||||
ChallengeScalar {
|
acc
|
||||||
inner: acc,
|
|
||||||
_marker: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The scalar challenge space that samples from the full-width field.
|
/// The scalar challenge space that samples from the full-width field.
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub struct ChallengeScalarFull<C: CurveAffine> {
|
pub struct Challenge255([u8; 32]);
|
||||||
_marker: PhantomData<C>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<C: CurveAffine> ChallengeSpace<C> for ChallengeScalarFull<C> {
|
impl std::ops::Deref for Challenge255 {
|
||||||
const NUM_BYTES: usize = 64;
|
type Target = [u8; 32];
|
||||||
const BYTE_MASK: u8 = 0b111111;
|
|
||||||
type Challenge = Challenge64;
|
|
||||||
|
|
||||||
fn to_challenge_scalar<T>(challenge: Self::Challenge) -> ChallengeScalar<C, T> {
|
fn deref(&self) -> &Self::Target {
|
||||||
ChallengeScalar {
|
&self.0
|
||||||
inner: C::Scalar::from_bytes_wide(&challenge.0),
|
|
||||||
_marker: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn read_n_points<C: CurveAffine, S: ChallengeSpace<C>, T: TranscriptRead<C, S>>(
|
impl<C: CurveAffine> EncodedChallenge<C, [u8; 64]> for Challenge255 {
|
||||||
|
fn new(challenge_input: &[u8; 64]) -> Self {
|
||||||
|
Challenge255(C::Scalar::from_bytes_wide(challenge_input).to_bytes())
|
||||||
|
}
|
||||||
|
fn get_scalar(challenge: &Self) -> C::Scalar {
|
||||||
|
C::Scalar::from_bytes(&challenge.0).unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn read_n_points<
|
||||||
|
C: CurveAffine,
|
||||||
|
I,
|
||||||
|
E: EncodedChallenge<C, I>,
|
||||||
|
T: TranscriptRead<C, I, E>,
|
||||||
|
>(
|
||||||
transcript: &mut T,
|
transcript: &mut T,
|
||||||
n: usize,
|
n: usize,
|
||||||
) -> io::Result<Vec<C>> {
|
) -> io::Result<Vec<C>> {
|
||||||
(0..n).map(|_| transcript.read_point()).collect()
|
(0..n).map(|_| transcript.read_point()).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn read_n_scalars<C: CurveAffine, S: ChallengeSpace<C>, T: TranscriptRead<C, S>>(
|
pub(crate) fn read_n_scalars<
|
||||||
|
C: CurveAffine,
|
||||||
|
I,
|
||||||
|
E: EncodedChallenge<C, I>,
|
||||||
|
T: TranscriptRead<C, I, E>,
|
||||||
|
>(
|
||||||
transcript: &mut T,
|
transcript: &mut T,
|
||||||
n: usize,
|
n: usize,
|
||||||
) -> io::Result<Vec<C::Scalar>> {
|
) -> io::Result<Vec<C::Scalar>> {
|
||||||
|
|
|
@ -13,7 +13,7 @@ use halo2::poly::{
|
||||||
commitment::{Blind, Params},
|
commitment::{Blind, Params},
|
||||||
Rotation,
|
Rotation,
|
||||||
};
|
};
|
||||||
use halo2::transcript::{Blake2bRead, Blake2bWrite, ChallengeScalarEndo};
|
use halo2::transcript::{Blake2bRead, Blake2bWrite, Challenge255};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -397,7 +397,7 @@ fn plonk_api() {
|
||||||
assert_eq!(prover.verify(), Ok(()));
|
assert_eq!(prover.verify(), Ok(()));
|
||||||
|
|
||||||
for _ in 0..10 {
|
for _ in 0..10 {
|
||||||
let mut transcript = Blake2bWrite::<_, _, ChallengeScalarEndo<EqAffine>>::init(vec![]);
|
let mut transcript = Blake2bWrite::<_, _, Challenge255>::init(vec![]);
|
||||||
// Create a proof
|
// Create a proof
|
||||||
create_proof(
|
create_proof(
|
||||||
¶ms,
|
¶ms,
|
||||||
|
@ -412,7 +412,7 @@ fn plonk_api() {
|
||||||
let pubinput_slice = &[pubinput];
|
let pubinput_slice = &[pubinput];
|
||||||
let pubinput_slice_copy = &[pubinput];
|
let pubinput_slice_copy = &[pubinput];
|
||||||
let msm = params.empty_msm();
|
let msm = params.empty_msm();
|
||||||
let mut transcript = Blake2bRead::<_, _, ChallengeScalarEndo<EqAffine>>::init(&proof[..]);
|
let mut transcript = Blake2bRead::<_, _, Challenge255>::init(&proof[..]);
|
||||||
let guard = verify_proof(
|
let guard = verify_proof(
|
||||||
¶ms,
|
¶ms,
|
||||||
pk.get_vk(),
|
pk.get_vk(),
|
||||||
|
@ -432,7 +432,7 @@ fn plonk_api() {
|
||||||
}
|
}
|
||||||
let msm = guard.clone().use_challenges();
|
let msm = guard.clone().use_challenges();
|
||||||
assert!(msm.clone().eval());
|
assert!(msm.clone().eval());
|
||||||
let mut transcript = Blake2bRead::<_, _, ChallengeScalarEndo<EqAffine>>::init(&proof[..]);
|
let mut transcript = Blake2bRead::<_, _, Challenge255>::init(&proof[..]);
|
||||||
let mut vk_buffer = vec![];
|
let mut vk_buffer = vec![];
|
||||||
pk.get_vk().write(&mut vk_buffer).unwrap();
|
pk.get_vk().write(&mut vk_buffer).unwrap();
|
||||||
let vk = VerifyingKey::<EqAffine>::read::<_, MyCircuit<Fp>>(&mut &vk_buffer[..], ¶ms)
|
let vk = VerifyingKey::<EqAffine>::read::<_, MyCircuit<Fp>>(&mut &vk_buffer[..], ¶ms)
|
||||||
|
|
Loading…
Reference in New Issue