mirror of https://github.com/zcash/halo2.git
306 lines
9.5 KiB
Rust
306 lines
9.5 KiB
Rust
#[cfg(test)]
|
|
mod test {
|
|
use crate::arithmetic::eval_polynomial;
|
|
use crate::plonk::Error;
|
|
use crate::poly::commitment::Blind;
|
|
use crate::poly::commitment::ParamsProver;
|
|
use crate::poly::{
|
|
commitment::{CommitmentScheme, Params, Prover, Verifier},
|
|
query::{ProverQuery, VerifierQuery},
|
|
strategy::VerificationStrategy,
|
|
EvaluationDomain,
|
|
};
|
|
use crate::transcript::{
|
|
Blake2bRead, Blake2bWrite, Challenge255, EncodedChallenge, Keccak256Read, Keccak256Write,
|
|
TranscriptReadBuffer, TranscriptWriterBuffer,
|
|
};
|
|
use group::Curve;
|
|
use halo2_middleware::ff::WithSmallOrderMulGroup;
|
|
use halo2_middleware::zal::{impls::H2cEngine, traits::MsmAccel};
|
|
use rand_core::OsRng;
|
|
|
|
#[test]
|
|
fn test_roundtrip_ipa() {
|
|
use crate::poly::ipa::commitment::{IPACommitmentScheme, ParamsIPA};
|
|
use crate::poly::ipa::multiopen::{ProverIPA, VerifierIPA};
|
|
use crate::poly::ipa::strategy::AccumulatorStrategy;
|
|
use halo2curves::pasta::EqAffine;
|
|
|
|
const K: u32 = 4;
|
|
|
|
let engine = H2cEngine::new();
|
|
let params = ParamsIPA::<EqAffine>::new(K);
|
|
|
|
let proof = create_proof::<
|
|
IPACommitmentScheme<EqAffine>,
|
|
ProverIPA<_>,
|
|
_,
|
|
Blake2bWrite<_, _, Challenge255<_>>,
|
|
>(&engine, ¶ms);
|
|
|
|
let verifier_params = params.verifier_params();
|
|
|
|
verify::<
|
|
IPACommitmentScheme<EqAffine>,
|
|
VerifierIPA<_>,
|
|
_,
|
|
Blake2bRead<_, _, Challenge255<_>>,
|
|
AccumulatorStrategy<_>,
|
|
>(verifier_params, &proof[..], false);
|
|
|
|
verify::<
|
|
IPACommitmentScheme<EqAffine>,
|
|
VerifierIPA<_>,
|
|
_,
|
|
Blake2bRead<_, _, Challenge255<_>>,
|
|
AccumulatorStrategy<_>,
|
|
>(verifier_params, &proof[..], true);
|
|
}
|
|
|
|
#[test]
|
|
fn test_roundtrip_ipa_keccak() {
|
|
use crate::poly::ipa::commitment::{IPACommitmentScheme, ParamsIPA};
|
|
use crate::poly::ipa::multiopen::{ProverIPA, VerifierIPA};
|
|
use crate::poly::ipa::strategy::AccumulatorStrategy;
|
|
use halo2curves::pasta::EqAffine;
|
|
|
|
const K: u32 = 4;
|
|
|
|
let engine = H2cEngine::new();
|
|
let params = ParamsIPA::<EqAffine>::new(K);
|
|
|
|
let proof = create_proof::<
|
|
IPACommitmentScheme<EqAffine>,
|
|
ProverIPA<_>,
|
|
_,
|
|
Keccak256Write<_, _, Challenge255<_>>,
|
|
>(&engine, ¶ms);
|
|
|
|
let verifier_params = params.verifier_params();
|
|
|
|
verify::<
|
|
IPACommitmentScheme<EqAffine>,
|
|
VerifierIPA<_>,
|
|
_,
|
|
Keccak256Read<_, _, Challenge255<_>>,
|
|
AccumulatorStrategy<_>,
|
|
>(verifier_params, &proof[..], false);
|
|
|
|
verify::<
|
|
IPACommitmentScheme<EqAffine>,
|
|
VerifierIPA<_>,
|
|
_,
|
|
Keccak256Read<_, _, Challenge255<_>>,
|
|
AccumulatorStrategy<_>,
|
|
>(verifier_params, &proof[..], true);
|
|
}
|
|
|
|
#[test]
|
|
fn test_roundtrip_gwc() {
|
|
use crate::poly::kzg::commitment::{KZGCommitmentScheme, ParamsKZG};
|
|
use crate::poly::kzg::multiopen::{ProverGWC, VerifierGWC};
|
|
use crate::poly::kzg::strategy::AccumulatorStrategy;
|
|
use halo2curves::bn256::Bn256;
|
|
|
|
const K: u32 = 4;
|
|
|
|
let engine = H2cEngine::new();
|
|
let params = ParamsKZG::<Bn256>::new(K);
|
|
|
|
let proof = create_proof::<_, ProverGWC<_>, _, Blake2bWrite<_, _, Challenge255<_>>>(
|
|
&engine, ¶ms,
|
|
);
|
|
|
|
let verifier_params = params.verifier_params();
|
|
|
|
verify::<_, VerifierGWC<_>, _, Blake2bRead<_, _, Challenge255<_>>, AccumulatorStrategy<_>>(
|
|
verifier_params,
|
|
&proof[..],
|
|
false,
|
|
);
|
|
|
|
verify::<
|
|
KZGCommitmentScheme<Bn256>,
|
|
VerifierGWC<_>,
|
|
_,
|
|
Blake2bRead<_, _, Challenge255<_>>,
|
|
AccumulatorStrategy<_>,
|
|
>(verifier_params, &proof[..], true);
|
|
}
|
|
|
|
#[test]
|
|
fn test_roundtrip_shplonk() {
|
|
use crate::poly::kzg::commitment::{KZGCommitmentScheme, ParamsKZG};
|
|
use crate::poly::kzg::multiopen::{ProverSHPLONK, VerifierSHPLONK};
|
|
use crate::poly::kzg::strategy::AccumulatorStrategy;
|
|
use halo2curves::bn256::Bn256;
|
|
|
|
const K: u32 = 4;
|
|
|
|
let engine = H2cEngine::new();
|
|
let params = ParamsKZG::<Bn256>::new(K);
|
|
|
|
let proof = create_proof::<
|
|
KZGCommitmentScheme<Bn256>,
|
|
ProverSHPLONK<_>,
|
|
_,
|
|
Blake2bWrite<_, _, Challenge255<_>>,
|
|
>(&engine, ¶ms);
|
|
|
|
let verifier_params = params.verifier_params();
|
|
|
|
verify::<
|
|
KZGCommitmentScheme<Bn256>,
|
|
VerifierSHPLONK<_>,
|
|
_,
|
|
Blake2bRead<_, _, Challenge255<_>>,
|
|
AccumulatorStrategy<_>,
|
|
>(verifier_params, &proof[..], false);
|
|
|
|
verify::<
|
|
KZGCommitmentScheme<Bn256>,
|
|
VerifierSHPLONK<_>,
|
|
_,
|
|
Blake2bRead<_, _, Challenge255<_>>,
|
|
AccumulatorStrategy<_>,
|
|
>(verifier_params, &proof[..], true);
|
|
}
|
|
|
|
fn verify<
|
|
'a,
|
|
'params,
|
|
Scheme: CommitmentScheme,
|
|
V: Verifier<'params, Scheme>,
|
|
E: EncodedChallenge<Scheme::Curve>,
|
|
T: TranscriptReadBuffer<&'a [u8], Scheme::Curve, E>,
|
|
Strategy: VerificationStrategy<'params, Scheme, V, Output = Strategy>,
|
|
>(
|
|
params: &'params Scheme::ParamsVerifier,
|
|
proof: &'a [u8],
|
|
should_fail: bool,
|
|
) {
|
|
let verifier = V::new(params);
|
|
|
|
let mut transcript = T::init(proof);
|
|
|
|
let a = transcript.read_point().unwrap();
|
|
let b = transcript.read_point().unwrap();
|
|
let c = transcript.read_point().unwrap();
|
|
|
|
let x = transcript.squeeze_challenge();
|
|
let y = transcript.squeeze_challenge();
|
|
|
|
let avx = transcript.read_scalar().unwrap();
|
|
let bvx = transcript.read_scalar().unwrap();
|
|
let cvy = transcript.read_scalar().unwrap();
|
|
|
|
let valid_queries = std::iter::empty()
|
|
.chain(Some(VerifierQuery::new_commitment(&a, x.get_scalar(), avx)))
|
|
.chain(Some(VerifierQuery::new_commitment(&b, x.get_scalar(), bvx)))
|
|
.chain(Some(VerifierQuery::new_commitment(&c, y.get_scalar(), cvy)));
|
|
|
|
let invalid_queries = std::iter::empty()
|
|
.chain(Some(VerifierQuery::new_commitment(&a, x.get_scalar(), avx)))
|
|
.chain(Some(VerifierQuery::new_commitment(&b, x.get_scalar(), avx)))
|
|
.chain(Some(VerifierQuery::new_commitment(&c, y.get_scalar(), cvy)));
|
|
|
|
let queries = if should_fail {
|
|
invalid_queries.clone()
|
|
} else {
|
|
valid_queries.clone()
|
|
};
|
|
|
|
{
|
|
let strategy = Strategy::new(params);
|
|
let strategy = strategy
|
|
.process(|msm_accumulator| {
|
|
verifier
|
|
.verify_proof(&mut transcript, queries.clone(), msm_accumulator)
|
|
.map_err(|_| Error::Opening)
|
|
})
|
|
.unwrap();
|
|
|
|
assert_eq!(strategy.finalize(), !should_fail);
|
|
}
|
|
}
|
|
|
|
fn create_proof<
|
|
'params,
|
|
Scheme: CommitmentScheme,
|
|
P: Prover<'params, Scheme>,
|
|
E: EncodedChallenge<Scheme::Curve>,
|
|
T: TranscriptWriterBuffer<Vec<u8>, Scheme::Curve, E>,
|
|
>(
|
|
engine: &impl MsmAccel<Scheme::Curve>,
|
|
params: &'params Scheme::ParamsProver,
|
|
) -> Vec<u8>
|
|
where
|
|
Scheme::Scalar: WithSmallOrderMulGroup<3>,
|
|
{
|
|
let domain = EvaluationDomain::new(1, params.k());
|
|
|
|
let mut ax = domain.empty_coeff();
|
|
for (i, a) in ax.iter_mut().enumerate() {
|
|
*a = <<Scheme as CommitmentScheme>::Scalar>::from(10 + i as u64);
|
|
}
|
|
|
|
let mut bx = domain.empty_coeff();
|
|
for (i, a) in bx.iter_mut().enumerate() {
|
|
*a = <<Scheme as CommitmentScheme>::Scalar>::from(100 + i as u64);
|
|
}
|
|
|
|
let mut cx = domain.empty_coeff();
|
|
for (i, a) in cx.iter_mut().enumerate() {
|
|
*a = <<Scheme as CommitmentScheme>::Scalar>::from(100 + i as u64);
|
|
}
|
|
|
|
let mut transcript = T::init(vec![]);
|
|
|
|
let blind = Blind::new(&mut OsRng);
|
|
let a = params.commit(engine, &ax, blind).to_affine();
|
|
let b = params.commit(engine, &bx, blind).to_affine();
|
|
let c = params.commit(engine, &cx, blind).to_affine();
|
|
|
|
transcript.write_point(a).unwrap();
|
|
transcript.write_point(b).unwrap();
|
|
transcript.write_point(c).unwrap();
|
|
|
|
let x = transcript.squeeze_challenge();
|
|
let y = transcript.squeeze_challenge();
|
|
|
|
let avx = eval_polynomial(&ax, x.get_scalar());
|
|
let bvx = eval_polynomial(&bx, x.get_scalar());
|
|
let cvy = eval_polynomial(&cx, y.get_scalar());
|
|
|
|
transcript.write_scalar(avx).unwrap();
|
|
transcript.write_scalar(bvx).unwrap();
|
|
transcript.write_scalar(cvy).unwrap();
|
|
|
|
let queries = [
|
|
ProverQuery {
|
|
point: x.get_scalar(),
|
|
poly: &ax,
|
|
blind,
|
|
},
|
|
ProverQuery {
|
|
point: x.get_scalar(),
|
|
poly: &bx,
|
|
blind,
|
|
},
|
|
ProverQuery {
|
|
point: y.get_scalar(),
|
|
poly: &cx,
|
|
blind,
|
|
},
|
|
]
|
|
.to_vec();
|
|
|
|
let prover = P::new(params);
|
|
prover
|
|
.create_proof(&mut OsRng, &mut transcript, queries)
|
|
.unwrap();
|
|
|
|
transcript.finalize()
|
|
}
|
|
}
|