use std::io::Read;
use anyhow::Result;
use axiom_codec::utils::reader::{read_curve_compressed, read_field_le, read_h256};
use axiom_eth::{
halo2_proofs::poly::kzg::commitment::ParamsKZG,
halo2curves::{
bn256::{Bn256, G1Affine},
CurveAffine,
},
snark_verifier::{
system::halo2::{compile, Config},
util::arithmetic::{root_of_unity, Domain},
verifier::plonk::PlonkProtocol,
},
snark_verifier_sdk::{halo2::aggregation::AggregationCircuit, CircuitExt},
};
use rand::{rngs::StdRng, SeedableRng};
use serde::{Deserialize, Serialize};
use super::{
default_circuit::{dummy_vk_from_metadata, DUMMY_K},
metadata::{decode_axiom_v2_circuit_metadata, AxiomV2CircuitMetadata},
};
#[derive(Clone, Debug, Serialize, Deserialize, Hash)]
pub struct OnchainVerifyingKey<C: CurveAffine> {
pub circuit_metadata: AxiomV2CircuitMetadata,
pub transcript_initial_state: C::Scalar,
pub preprocessed: Vec<C>,
}
impl<C: CurveAffine> OnchainVerifyingKey<C> {
pub fn read(reader: &mut impl Read) -> Result<Self>
where
C::Scalar: axiom_codec::Field,
{
let encoded_circuit_metadata = read_h256(reader)?;
let circuit_metadata = decode_axiom_v2_circuit_metadata(encoded_circuit_metadata)?;
let transcript_initial_state = read_field_le(reader)?;
let mut preprocessed = Vec::new();
while let Ok(point) = read_curve_compressed(reader) {
preprocessed.push(point);
}
Ok(OnchainVerifyingKey { circuit_metadata, preprocessed, transcript_initial_state })
}
}
impl OnchainVerifyingKey<G1Affine> {
pub fn into_plonk_protocol(self, k: usize) -> Result<PlonkProtocol<G1Affine>> {
let OnchainVerifyingKey { circuit_metadata, transcript_initial_state, preprocessed } = self;
let kzg_params = ParamsKZG::<Bn256>::setup(DUMMY_K, StdRng::seed_from_u64(0));
let dummy_vk = dummy_vk_from_metadata(&kzg_params, circuit_metadata.clone())?;
let num_instance = circuit_metadata.num_instance.iter().map(|x| *x as usize).collect();
let acc_indices = circuit_metadata
.is_aggregation
.then(|| AggregationCircuit::accumulator_indices().unwrap());
let mut protocol = compile(
&kzg_params,
&dummy_vk,
Config::kzg().with_num_instance(num_instance).with_accumulator_indices(acc_indices),
);
protocol.domain = Domain::new(k, root_of_unity(k));
protocol.domain_as_witness = None;
protocol.preprocessed = preprocessed;
protocol.transcript_initial_state = Some(transcript_initial_state);
protocol.instance_committing_key = None;
protocol.linearization = None;
Ok(protocol)
}
}