Fix: get zkevm sha256 working (#12)

* save wip

* Feat: get zkevmsha256 working WIP

* Get sha256 bit circuit to pass mockprover

* Add readme issues
This commit is contained in:
Richard Liang
2023-10-18 07:00:47 +08:00
committed by GitHub
parent 54b17be099
commit e90cb3bea7
6 changed files with 313 additions and 524 deletions

View File

@@ -59,8 +59,7 @@ cargo test
## Issues
Current issues and todos with the library. We welcome any contributions!
1. Currently, there is an issue with aggregating vanilla ZKEVM SHA256 due to public instances not being exposed properly. See `sha256-bit-circuit.rs`. Therefore, we have to use an unoptimized sha256 library that is written entirely in halo2-lib v4
2. Script to download TLS certs doesn't match manually inspecting the certs and downloading
3. Doesn't support other certificate chaining standards, such as ECDSA and SHA3 yet
4. Doesn't support CRL (certificate revocation lists yet)
5. RSA proving key runs into `SNARK proof failed to verify` using CLI for certain PEM files. It works fine in tests which is weird
1. Script to download TLS certs doesn't match manually inspecting the certs and downloading
2. Doesn't support other certificate chaining standards, such as ECDSA and SHA3 yet
3. Doesn't support CRL (certificate revocation lists yet)
4. For RSA and SHA256 circuits, Mock prover is satisfied, but cannot verify a real proof (we can create proof, but fails in vk). Is it something to do with my snark-verifier version?

View File

@@ -6,7 +6,7 @@ use std::env;
use halo2_base::{
halo2_proofs::halo2curves::bn256::Fr,
halo2_proofs::plonk::Circuit,
gates::circuit::{builder::BaseCircuitBuilder, CircuitBuilderStage, BaseCircuitParams},
gates::circuit::{builder::BaseCircuitBuilder, CircuitBuilderStage},
gates::flex_gate::MultiPhaseThreadBreakPoints,
utils::fs::gen_srs
};
@@ -231,7 +231,7 @@ async fn main() {
let (tbs, signature_bigint) = extract_tbs_and_sig(&verify_cert_path);
let public_key_modulus = extract_public_key(&issuer_cert_path);
let builder = create_default_rsa_circuit_with_instances(k as usize, tbs, public_key_modulus, signature_bigint);
let builder = create_default_rsa_circuit_with_instances(k as usize, tbs, public_key_modulus, signature_bigint, false, vec![vec![]]);
if Path::new(&pk_path).exists() {
match remove_file(&pk_path) {
@@ -274,10 +274,8 @@ async fn main() {
let (tbs, _) = extract_tbs_and_sig(&verify_cert_path);
let dummy_circuit = Sha256BitCircuit::new(
CircuitBuilderStage::Keygen,
BaseCircuitParams {k: k as usize, num_fixed: 1, num_advice_per_phase: vec![1, 0, 0], num_lookup_advice_per_phase: vec![0, 0, 0], lookup_bits: Some(0), num_instance_columns: 1},
Some(2usize.pow(k) - 109),
vec![tbs.to_vec()],
vec![tbs],
false
);
@@ -304,7 +302,7 @@ async fn main() {
let (tbs, signature_bigint) = extract_tbs_and_sig(&verify_cert_path);
let public_key_modulus = extract_public_key(&issuer_cert_path);
let builder = create_default_rsa_circuit_with_instances(k as usize, tbs, public_key_modulus, signature_bigint);
let builder = create_default_rsa_circuit_with_instances(k as usize, tbs, public_key_modulus, signature_bigint, true, vec![vec![]]);
let pk = read_pk::<BaseCircuitBuilder<Fr>>(Path::new(&pk_path), builder.params()).unwrap();
if Path::new(&proof_path).exists() {
@@ -349,16 +347,13 @@ async fn main() {
let params = gen_srs(k);
let (tbs, _) = extract_tbs_and_sig(&verify_cert_path);
let base_circuit_params = BaseCircuitParams {k: k as usize, num_fixed: 1, num_advice_per_phase: vec![1, 0, 0], num_lookup_advice_per_phase: vec![0, 0, 0], lookup_bits: Some(0), num_instance_columns: 1};
let sha256_bit_circuit = Sha256BitCircuit::new(
CircuitBuilderStage::Prover,
base_circuit_params.clone(),
Some(2usize.pow(k) - 109),
vec![tbs.to_vec()],
true
);
let pk = read_pk::<BaseCircuitBuilder<Fr>>(Path::new(&pk_path), base_circuit_params).unwrap();
let pk = read_pk::<Sha256BitCircuit<Fr>>(Path::new(&pk_path), ()).unwrap();
if Path::new(&proof_path).exists() {
match remove_file(&proof_path) {
Ok(_) => println!("File found, overwriting..."),

View File

@@ -1,6 +1,6 @@
use halo2_base::{
AssignedValue,
halo2_proofs::halo2curves::bn256::Fr,
halo2_proofs::{halo2curves::bn256::{Fr, G1Affine}, plonk::ProvingKey},
gates::{
circuit::builder::BaseCircuitBuilder,
GateInstructions
@@ -17,7 +17,7 @@ use snark_verifier_sdk::{
halo2::gen_snark_shplonk,
Snark,
};
use crate::sha256_bit_circuit::Sha256BitCircuit;
use sha2::{Digest, Sha256};
use std::fs::File;
use std::io::Read;
@@ -98,7 +98,9 @@ pub fn create_default_rsa_circuit_with_instances(
k: usize,
tbs: Vec<u8>,
public_key_modulus: BigUint,
signature_bigint: BigUint
signature_bigint: BigUint,
witness_gen_only: bool,
break_points: Vec<Vec<usize>>
) -> BaseCircuitBuilder<Fr> {
// Circuit inputs
let limb_bits = 64;
@@ -106,7 +108,13 @@ pub fn create_default_rsa_circuit_with_instances(
let exp_bits = 5; // UNUSED
let default_e = 65537_u32;
let mut builder = BaseCircuitBuilder::new(false);
let mut builder = {
if witness_gen_only {
BaseCircuitBuilder::new(witness_gen_only).use_break_points(break_points)
} else {
BaseCircuitBuilder::new(witness_gen_only)
}
};
// Set rows
builder.set_k(k);
builder.set_lookup_bits(k - 1);
@@ -157,6 +165,7 @@ pub fn create_default_rsa_circuit_with_instances(
// Insert input hash as public instance for circuit
hashed_bytes.reverse();
builder.assigned_instances[0].extend(hashed_bytes);
println!("Assigned instances: {:?}", builder.assigned_instances[0]);
let circuit_params = builder.calculate_params(Some(10));
println!("Circuit params: {:?}", circuit_params);
@@ -190,12 +199,48 @@ pub fn create_default_unoptimized_sha256_circuit_with_instances(
builder.use_params(circuit_params)
}
pub fn generate_rsa_pk(verify_cert_path: &str, issuer_cert_path: &str, k: usize) -> (ProvingKey<G1Affine>, Vec<Vec<usize>>) {
let (tbs, signature_bigint) = extract_tbs_and_sig(verify_cert_path);
let public_key_modulus = extract_public_key(issuer_cert_path);
let builder = create_default_rsa_circuit_with_instances(k, tbs, public_key_modulus, signature_bigint, false, vec![vec![]]);
// Generate params
println!("Generate params");
let params = gen_srs(k as u32);
// println!("Generating proving key");
let pk = gen_pk(&params, &builder, None);
(pk, builder.break_points())
}
pub fn generate_rsa_proof(verify_cert_path: &str, issuer_cert_path: &str, k: usize, pk: ProvingKey<G1Affine>, break_points: Vec<Vec<usize>>) -> Snark {
let (tbs, signature_bigint) = extract_tbs_and_sig(verify_cert_path);
let public_key_modulus = extract_public_key(issuer_cert_path);
let builder = create_default_rsa_circuit_with_instances(k, tbs, public_key_modulus, signature_bigint, true, break_points);
// Generate params
println!("Generate params");
let params = gen_srs(k as u32);
// Generate proof
println!("Generating proof");
// TODO: very weird that passes mockprover but fails on real snark proof
// use halo2_base::halo2_proofs::dev::MockProver;
// MockProver::run(k as u32, &builder, builder.instances()).unwrap().assert_satisfied();
gen_snark_shplonk(&params, &pk, builder, None::<&str>)
}
pub fn generate_rsa_circuit_with_instances(verify_cert_path: &str, issuer_cert_path: &str, k: usize) -> Snark {
let (tbs, signature_bigint) = extract_tbs_and_sig(verify_cert_path);
let public_key_modulus = extract_public_key(issuer_cert_path);
let builder = create_default_rsa_circuit_with_instances(k, tbs, public_key_modulus, signature_bigint);
let builder = create_default_rsa_circuit_with_instances(k, tbs, public_key_modulus, signature_bigint, false, vec![vec![]]);
// Generate params
println!("Generate params");
@@ -224,4 +269,42 @@ pub fn generate_unoptimized_sha256_circuit_with_instances(verify_cert_path: &str
// Generate proof
println!("Generating proof");
gen_snark_shplonk(&params, &pk, builder, None::<&str>)
}
}
pub fn generate_zkevm_sha256_circuit(verify_cert_path: &str, k: usize) -> Snark {
let (tbs, _) = extract_tbs_and_sig(verify_cert_path);
// Generate params
println!("Generate params");
let params = gen_srs(k as u32);
// println!("Generating proving key");
let mut dummy_circuit = Sha256BitCircuit::new(
Some(2usize.pow(k as u32) - 109),
vec![tbs.to_vec()],
false
);
// use halo2_base::halo2_proofs::halo2curves::ff::PrimeField;
// dummy_circuit.set_instances(vec![
// Fr::from_u128(0x00000000000000000000000000000000eeb16b6a466d78243f0210594c79e2ea),
// Fr::from_u128(0x000000000000000000000000000000005773a131a99b9c98158c743ebd7e521a)
// ]);
let pk = gen_pk(&params, &dummy_circuit, None);
// Generate proof
println!("Generating proof");
let mut sha256_bit_circuit = Sha256BitCircuit::new(
Some(2usize.pow(k as u32) - 109),
vec![tbs.to_vec()],
true
);
// sha256_bit_circuit.set_instances(vec![
// Fr::from_u128(0x00000000000000000000000000000000eeb16b6a466d78243f0210594c79e2ea),
// Fr::from_u128(0x000000000000000000000000000000005773a131a99b9c98158c743ebd7e521a)
// ]);
// TODO: why is mockprover working but gen_snark_shplonk fails with `SNARK proof failed to verify`
// use halo2_base::halo2_proofs::dev::MockProver;
// use snark_verifier_sdk::CircuitExt;
// MockProver::run(k as u32, &sha256_bit_circuit, sha256_bit_circuit.instances()).unwrap().assert_satisfied();
// print!("SHA256 bit circuit mock prover works");
gen_snark_shplonk(&params, &pk, sha256_bit_circuit, None::<&str>)
}

View File

@@ -48,7 +48,6 @@ impl X509VerifierAggregationCircuit {
universality,
);
// TODO: zkevm SHA256 vanilla snarks don't expose instances so this custom aggregation circuit doesn't work. Need to debug
let snark_0_instances = aggregation_circuit.previous_instances()[0].clone();
let snark_1_instances = aggregation_circuit.previous_instances()[1].clone();
let snark_2_instances = aggregation_circuit.previous_instances()[2].clone();
@@ -62,6 +61,8 @@ impl X509VerifierAggregationCircuit {
aggregation_circuit.builder.pool(0).threads[0].constrain_equal(x, y);
}).collect_vec();
// TODO: link cert pairs with each other
Self {
aggregation_circuit
}

View File

@@ -1,6 +1,3 @@
use halo2_base::gates::circuit::BaseCircuitParams;
use halo2_base::gates::circuit::{builder::BaseCircuitBuilder, CircuitBuilderStage};
// Generate Sha256BitCircuit
use zkevm_hashes::util::eth_types::Field;
use std::marker::PhantomData;
use zkevm_hashes::sha256::vanilla::{
@@ -10,7 +7,6 @@ use zkevm_hashes::sha256::vanilla::{
};
use halo2_base::halo2_proofs::{
circuit::SimpleFloorPlanner,
halo2curves::bn256::Fr,
plonk::Circuit,
};
use halo2_base::{
@@ -24,7 +20,6 @@ use halo2_base::{
},
};
use sha2::{Digest, Sha256};
use std::cell::RefCell;
use snark_verifier_sdk::CircuitExt;
use itertools::Itertools;
@@ -38,8 +33,8 @@ pub struct Sha256BitCircuitConfig<F: Field> {
#[derive(Default)]
pub struct Sha256BitCircuit<F: Field> {
inputs: Vec<Vec<u8>>,
builder: RefCell<BaseCircuitBuilder<F>>,
num_rows: Option<usize>,
assigned_instances: Vec<Vec<F>>,
witness_gen_only: bool,
_marker: PhantomData<F>,
}
@@ -75,7 +70,6 @@ impl<F: Field> Circuit<F> for Sha256BitCircuit<F> {
self.num_rows.map(get_sha2_capacity),
);
println!("Witness generation time: {:?}", start.elapsed());
// Find the block where the final output is
let mut final_block = blocks[0].clone();
if self.witness_gen_only {
@@ -93,33 +87,25 @@ impl<F: Field> Circuit<F> for Sha256BitCircuit<F> {
}
}
}
let builder = self.builder.borrow_mut();
let mut copy_manager = builder.core().copy_manager.lock().unwrap();
let result = [
final_block.is_final().clone(),
final_block.output().lo().clone(),
final_block.output().hi().clone(),
final_block.length().clone(),
].iter().map(|x| copy_manager.load_external_assigned(x.clone())).collect_vec();
{
println!("Num advice columns: 18"); // fixed at 18
println!("Num rows: {:?}", self.num_rows);
}
];
{
println!("Num rows: {:?}", self.num_rows);
}
Ok(result)
},
)?;
Ok(result)
},
)?;
// TODO: How do you expose these instances publicly?
let builder = &mut self.builder.borrow_mut();
builder.assigned_instances[0].extend(result);
println!("assigned_instances: {:?}", builder.assigned_instances);
// TODO: this makes the proof fail
// builder.assign_instances(&[config.instance], layouter);
if !self.witness_gen_only {
// expose public instances
let mut layouter = layouter.namespace(|| "expose");
layouter.constrain_instance(result[0].cell(), config.instance, 0);
layouter.constrain_instance(result[1].cell(), config.instance, 1);
}
Ok(())
}
@@ -128,16 +114,18 @@ impl<F: Field> Circuit<F> for Sha256BitCircuit<F> {
impl<F: Field> Sha256BitCircuit<F> {
/// Creates a new circuit instance
pub fn new(
stage: CircuitBuilderStage,
config_params: BaseCircuitParams,
num_rows: Option<usize>,
inputs: Vec<Vec<u8>>,
witness_gen_only: bool
) -> Self {
println!("config_params: {:?}", config_params.clone());
let builder = BaseCircuitBuilder::from_stage(stage).use_params(config_params);
Sha256BitCircuit { num_rows, inputs, witness_gen_only, assigned_instances: vec![vec![]], _marker: PhantomData }
}
Sha256BitCircuit { num_rows, inputs, witness_gen_only, builder: RefCell::new(builder), _marker: PhantomData }
pub fn set_instances(
&mut self,
instances: Vec<F>,
) {
self.assigned_instances[0].extend(instances);
}
fn verify_output(&self, assigned_blocks: &[AssignedSha256Block<F>]) {
@@ -194,16 +182,12 @@ impl<F: Field> Sha256BitCircuit<F> {
}
impl CircuitExt<Fr> for Sha256BitCircuit<Fr> {
impl<F: Field> CircuitExt<F> for Sha256BitCircuit<F> {
fn num_instance(&self) -> Vec<usize> {
let a = &mut self.builder.borrow_mut().assigned_instances;
a.iter().map(|instances| instances.len()).collect()
self.assigned_instances.iter().map(|instances| instances.len()).collect_vec()
}
fn instances(&self) -> Vec<Vec<Fr>> {
let a = &mut self.builder.borrow_mut().assigned_instances;
a.iter().map(|x| {
x.iter().map(|y| *y.value()).collect_vec()
}).collect_vec()
fn instances(&self) -> Vec<Vec<F>> {
self.assigned_instances.clone()
}
}
}

View File

@@ -1,485 +1,212 @@
use halo2_base::{
QuantumCell::{Existing, Constant},
halo2_proofs::halo2curves::bn256::Fr,
gates::{
circuit::{builder::BaseCircuitBuilder, CircuitBuilderStage, BaseCircuitParams},
GateInstructions
},
utils::fs::gen_srs
};
use halo2_rsa::{
BigUintConfig, BigUintInstructions, RSAConfig, RSAInstructions, RSAPubE, RSAPublicKey, RSASignature,
};
use snark_verifier_sdk::{
SHPLONK,
gen_pk,
halo2::{aggregation::{AggregationConfigParams, VerifierUniversality, AggregationCircuit}, gen_snark_shplonk},
Snark, CircuitExt,
};
use crate::sha256_bit_circuit::Sha256BitCircuit;
use sha2::{Digest, Sha256};
use std::fs::File;
use std::io::Read;
use std::vec;
use x509_parser::pem::parse_x509_pem;
use x509_parser::public_key::PublicKey;
// use halo2_base::{
// gates::circuit::CircuitBuilderStage,
// utils::fs::gen_srs
// };
// use snark_verifier_sdk::{
// SHPLONK,
// gen_pk,
// halo2::{aggregation::{AggregationConfigParams, VerifierUniversality, AggregationCircuit}, gen_snark_shplonk},
// };
// use crate::helpers::*;
// use std::vec;
use num_bigint::BigUint;
use itertools::Itertools;
// #[test]
// fn test_aggregation_split_zkevm_sha256_rsa1() {
// println!("Generating dummy snark");
// let snark1 = generate_zkevm_sha256_circuit(
// "./certs/example_cert_3.pem",
// 11
// );
// let snark2 = generate_rsa_circuit_with_instances(
// "./certs/example_cert_3.pem",
// "./certs/example_cert_2.pem",
// 16
// );
fn generate_rsa_circuit(verify_cert_path: &str, issuer_cert_path: &str, k: usize) -> Snark {
// Read the PEM certificate from a file
let mut cert_file = File::open(verify_cert_path).expect("Failed to open PEM file");
let mut cert_pem_buffer = Vec::new();
cert_file.read_to_end(&mut cert_pem_buffer).expect("Failed to read PEM file");
// // Create an aggregation circuit using the snark
// let agg_k = 20;
// let agg_lookup_bits = agg_k - 1;
// let agg_params = gen_srs(agg_k as u32);
// let mut agg_circuit = AggregationCircuit::new::<SHPLONK>(
// CircuitBuilderStage::Keygen,
// AggregationConfigParams {degree: agg_k, lookup_bits: agg_lookup_bits as usize, ..Default::default()},
// &agg_params,
// vec![snark1.clone(), snark2.clone()],
// VerifierUniversality::Full
// );
// Parse the PEM certificate using x509-parser
let cert_pem = parse_x509_pem(&cert_pem_buffer).expect("Failed to parse cert 3 PEM").1;
let cert = cert_pem.parse_x509().expect("Failed to parse PEM certificate");
// println!("Aggregation circuit calculating params");
// let agg_config = agg_circuit.calculate_params(Some(10));
// Extract the TBS (To-Be-Signed) data from the certificate 3
let tbs = cert.tbs_certificate.as_ref();
// println!("TBS (To-Be-Signed): {:x?}", tbs);
// Extract the signature from cert 3
let signature_bytes = &cert.signature_value;
let signature_bigint = BigUint::from_bytes_be(&signature_bytes.data);
// println!("Signature: {:?}", signature_bigint);
let mut issuer_cert_file = File::open(issuer_cert_path).expect("Failed to open cert 2PEM file");
let mut issuer_cert_pem_buffer = Vec::new();
issuer_cert_file.read_to_end(&mut issuer_cert_pem_buffer).expect("Failed to read cert 2 PEM file");
// Parse the PEM certificate using x509-parser
let issuer_cert_pem = parse_x509_pem(&issuer_cert_pem_buffer).expect("Failed to parse cert 3 PEM").1;
let issuer_cert = issuer_cert_pem.parse_x509().expect("Failed to parse PEM certificate");
// // let start0 = start_timer!(|| "gen vk & pk");
// println!("Aggregation circuit generating pk");
// let pk = gen_pk(&agg_params, &agg_circuit, None);
// Extract the public key of cert 2
let public_key_modulus = match issuer_cert.public_key().parsed().unwrap() {
PublicKey::RSA(pub_key) => {
let modulus = BigUint::from_bytes_be(pub_key.modulus);
// println!("Public Key modulus: {:?}", modulus);
modulus
},
_ => panic!("Failed to grab modulus. Not RSA")
};
// let break_points = agg_circuit.break_points();
// Circuit inputs
let limb_bits = 64;
let default_bits = 2048;
let exp_bits = 5;
let default_e = 65537 as u32;
// // std::fs::remove_file(Path::new("examples/agg.pk")).ok();
// // let _pk = gen_pk(&params, &agg_circuit, Some(Path::new("examples/agg.pk")));
// // end_timer!(start0);
// // let pk = read_pk::<AggregationCircuit>(Path::new("examples/agg.pk"), agg_config).unwrap();
// // std::fs::remove_file(Path::new("examples/agg.pk")).ok();
// // let break_points = agg_circuit.break_points();
let mut builder = BaseCircuitBuilder::new(false);
// Set rows
builder.set_k(k);
builder.set_lookup_bits(k - 1);
builder.set_instance_columns(1);
// let agg_circuit = AggregationCircuit::new::<SHPLONK>(
// CircuitBuilderStage::Prover,
// agg_config,
// &agg_params,
// vec![snark1, snark2],
// VerifierUniversality::Full,
// ).use_break_points(break_points.clone());
let range = builder.range_chip();
let ctx = builder.main(0);
// println!("Generating aggregation snark");
// let _agg_snark = gen_snark_shplonk(&agg_params, &pk, agg_circuit, None::<&str>);
// println!("Aggregation snark success");
// }
let bigint_chip = BigUintConfig::construct(range.clone(), limb_bits);
let rsa_chip = RSAConfig::construct(bigint_chip.clone(), default_bits, exp_bits);
// #[test]
// fn test_aggregation_split_zkevm_sha256_rsa2() {
// println!("Generating dummy snark");
// let snark1 = generate_zkevm_sha256_circuit(
// "./certs/example_cert_2.pem",
// 11
// );
// let snark2 = generate_rsa_circuit_with_instances(
// "./certs/example_cert_2.pem",
// "./certs/example_cert_1.pem",
// 16
// );
// Hash in pure Rust vs in-circuit
let hashed_tbs = Sha256::digest(tbs);
let mut hashed_bytes = hashed_tbs.iter().map(|limb| ctx.load_witness(Fr::from(*limb as u64))).collect_vec();
hashed_bytes.reverse();
let bytes_bits = hashed_bytes.len() * 8;
let limb_bits = bigint_chip.limb_bits();
let limb_bytes = limb_bits / 8;
let mut hashed_u64s = vec![];
let bases = (0..limb_bytes)
.map(|i| Fr::from(1u64 << (8 * i)))
.map(Constant)
.collect_vec();
for i in 0..(bytes_bits / limb_bits) {
let left = hashed_bytes[limb_bytes * i..limb_bytes * (i + 1)]
.iter()
.map(|x| Existing(*x))
.collect_vec();
let sum = bigint_chip.gate().inner_product(ctx, left, bases.clone());
hashed_u64s.push(sum);
}
// // Create an aggregation circuit using the snark
// let agg_k = 20;
// let agg_lookup_bits = agg_k - 1;
// let agg_params = gen_srs(agg_k as u32);
// let mut agg_circuit = AggregationCircuit::new::<SHPLONK>(
// CircuitBuilderStage::Keygen,
// AggregationConfigParams {degree: agg_k, lookup_bits: agg_lookup_bits as usize, ..Default::default()},
// &agg_params,
// vec![snark1.clone(), snark2.clone()],
// VerifierUniversality::Full
// );
// Generate values to be fed into the circuit (Pure Rust)
// Verify Cert
let e_fix = RSAPubE::Fix(BigUint::from(default_e));
let public_key = RSAPublicKey::new(public_key_modulus.clone(), e_fix); // cloning might be slow
let public_key = rsa_chip.assign_public_key(ctx, public_key).unwrap();
// println!("Aggregation circuit calculating params");
// let agg_config = agg_circuit.calculate_params(Some(10));
let signature = RSASignature::new(signature_bigint.clone()); // cloning might be slow
let signature = rsa_chip.assign_signature(ctx, signature).unwrap();
let is_valid = rsa_chip.verify_pkcs1v15_signature(ctx, &public_key, &hashed_u64s, &signature).unwrap();
rsa_chip.biguint_config()
.gate()
.assert_is_const(ctx, &is_valid, &Fr::one());
// let x = ctx.load_witness(Fr::from(14));
// range.gate().add(ctx, x, x);
let circuit_params = builder.calculate_params(Some(10));
println!("Circuit params: {:?}", circuit_params);
let builder = builder.use_params(circuit_params);
// Generate params
println!("Generate params");
let params = gen_srs(k as u32);
// // let start0 = start_timer!(|| "gen vk & pk");
// println!("Aggregation circuit generating pk");
// let pk = gen_pk(&agg_params, &agg_circuit, None);
// println!("Generating proving key");
let pk = gen_pk(&params, &builder, None);
// let break_points = agg_circuit.break_points();
// Generate proof
println!("Generating proof");
gen_snark_shplonk(&params, &pk, builder, None::<&str>)
}
// // std::fs::remove_file(Path::new("examples/agg.pk")).ok();
// // let _pk = gen_pk(&params, &agg_circuit, Some(Path::new("examples/agg.pk")));
// // end_timer!(start0);
// // let pk = read_pk::<AggregationCircuit>(Path::new("examples/agg.pk"), agg_config).unwrap();
// // std::fs::remove_file(Path::new("examples/agg.pk")).ok();
// // let break_points = agg_circuit.break_points();
fn generate_zkevm_sha256_circuit(verify_cert_path: &str, issuer_cert_path: &str, k: usize) -> Snark {
// Read the PEM certificate from a file
let mut cert_file = File::open(verify_cert_path).expect("Failed to open PEM file");
let mut cert_pem_buffer = Vec::new();
cert_file.read_to_end(&mut cert_pem_buffer).expect("Failed to read PEM file");
// let agg_circuit = AggregationCircuit::new::<SHPLONK>(
// CircuitBuilderStage::Prover,
// agg_config,
// &agg_params,
// vec![snark1, snark2],
// VerifierUniversality::Full,
// ).use_break_points(break_points.clone());
// Parse the PEM certificate using x509-parser
let cert_pem = parse_x509_pem(&cert_pem_buffer).expect("Failed to parse cert 3 PEM").1;
let cert = cert_pem.parse_x509().expect("Failed to parse PEM certificate");
// println!("Generating aggregation snark");
// let _agg_snark = gen_snark_shplonk(&agg_params, &pk, agg_circuit, None::<&str>);
// println!("Aggregation snark success");
// }
// Extract the TBS (To-Be-Signed) data from the certificate 3
let tbs = cert.tbs_certificate.as_ref();
println!("TBS (To-Be-Signed) Length: {:x?}", tbs.len().to_string());
// #[test]
// fn test_aggregation_split_zkevm_sha256_rsa3() {
// println!("Generating dummy snark");
// let (rsa_pk, break_points) = generate_rsa_pk(
// "./certs/example_cert_3.pem",
// "./certs/example_cert_2.pem",
// 16
// );
// let snark1 = generate_zkevm_sha256_circuit(
// "./certs/example_cert_3.pem",
// 11
// );
// let snark2 = generate_rsa_proof(
// "./certs/cert_3.pem",
// "./certs/cert_2.pem",
// 16,
// rsa_pk.clone(),
// break_points.clone()
// );
// let snark3 = generate_zkevm_sha256_circuit(
// "./certs/example_cert_2.pem",
// 11
// );
// let snark4 = generate_rsa_proof(
// "./certs/cert_2.pem",
// "./certs/cert_1.pem",
// 16,
// rsa_pk.clone(),
// break_points.clone()
// );
let mut issuer_cert_file = File::open(issuer_cert_path).expect("Failed to open cert 2PEM file");
let mut issuer_cert_pem_buffer = Vec::new();
issuer_cert_file.read_to_end(&mut issuer_cert_pem_buffer).expect("Failed to read cert 2 PEM file");
// // Create an aggregation circuit using the snark
// let agg_k = 20;
// let agg_lookup_bits = agg_k - 1;
// let agg_params = gen_srs(agg_k as u32);
// let mut agg_circuit = AggregationCircuit::new::<SHPLONK>(
// CircuitBuilderStage::Keygen,
// AggregationConfigParams {degree: agg_k, lookup_bits: agg_lookup_bits as usize, ..Default::default()},
// &agg_params,
// vec![snark1.clone(), snark2.clone(), snark3.clone(), snark4.clone()],
// VerifierUniversality::Full
// );
// Generate params
println!("Generate params");
let params = gen_srs(k as u32);
// println!("Aggregation circuit calculating params");
// let agg_config = agg_circuit.calculate_params(Some(10));
// // let start0 = start_timer!(|| "gen vk & pk");
// println!("Aggregation circuit generating pk");
// let pk = gen_pk(&agg_params, &agg_circuit, None);
// println!("Generating proving key");
let dummy_circuit = Sha256BitCircuit::new(
CircuitBuilderStage::Keygen,
BaseCircuitParams {k, lookup_bits: Some(0), num_instance_columns: 1, ..Default::default()},
Some(2usize.pow(k as u32) - 109),
vec![],
false);
let pk = gen_pk(&params, &dummy_circuit, None);
// Generate proof
println!("Generating proof");
let sha256_bit_circuit = Sha256BitCircuit::new(
CircuitBuilderStage::Prover,
BaseCircuitParams {k, lookup_bits: Some(0), num_instance_columns: 1, ..Default::default()},
Some(2usize.pow(k as u32) - 109),
vec![tbs.to_vec()],
true
);
println!("num instance: {:?}", sha256_bit_circuit.num_instance());
gen_snark_shplonk(&params, &pk, sha256_bit_circuit, None::<&str>)
}
// let break_points = agg_circuit.break_points();
#[test]
fn test_two_level_aggregation_split_sha256_rsa() {
println!("Generating dummy snark");
let snark1 = generate_zkevm_sha256_circuit(
"./certs/example_cert_3.pem",
"./certs/example_cert_2.pem",
11
);
let snark2 = generate_rsa_circuit(
"./certs/example_cert_3.pem",
"./certs/example_cert_2.pem",
16
);
// // std::fs::remove_file(Path::new("examples/agg.pk")).ok();
// // let _pk = gen_pk(&params, &agg_circuit, Some(Path::new("examples/agg.pk")));
// // end_timer!(start0);
// // let pk = read_pk::<AggregationCircuit>(Path::new("examples/agg.pk"), agg_config).unwrap();
// // std::fs::remove_file(Path::new("examples/agg.pk")).ok();
// // let break_points = agg_circuit.break_points();
// Create an aggregation circuit using the snark
let agg_k_level_1 = 20;
let agg_lookup_bits_level_1 = agg_k_level_1 - 1;
let agg_params_level_1 = gen_srs(agg_k_level_1 as u32);
let mut agg_circuit_level_1 = AggregationCircuit::new::<SHPLONK>(
CircuitBuilderStage::Keygen,
AggregationConfigParams {degree: agg_k_level_1, lookup_bits: agg_lookup_bits_level_1 as usize, ..Default::default()},
&agg_params_level_1,
vec![snark1.clone(), snark2.clone()],
VerifierUniversality::Full
);
// let agg_circuit = AggregationCircuit::new::<SHPLONK>(
// CircuitBuilderStage::Prover,
// agg_config,
// &agg_params,
// vec![snark1, snark2, snark3, snark4],
// VerifierUniversality::Full,
// ).use_break_points(break_points.clone());
println!("Aggregation circuit calculating params");
let agg_config_level_1 = agg_circuit_level_1.calculate_params(Some(10));
// println!("Generating aggregation snark");
// let _agg_snark = gen_snark_shplonk(&agg_params, &pk, agg_circuit, None::<&str>);
// println!("Aggregation snark success");
// }
// let start0 = start_timer!(|| "gen vk & pk");
println!("Aggregation circuit generating pk");
let pk_level_1 = gen_pk(&agg_params_level_1, &agg_circuit_level_1, None);
let break_points_level_1 = agg_circuit_level_1.break_points();
// std::fs::remove_file(Path::new("examples/agg.pk")).ok();
// let _pk = gen_pk(&params, &agg_circuit_level_1, Some(Path::new("examples/agg.pk")));
// end_timer!(start0);
// let pk = read_pk::<AggregationCircuit>(Path::new("examples/agg.pk"), agg_config_level_1).unwrap();
// std::fs::remove_file(Path::new("examples/agg.pk")).ok();
// let break_points_level_1 = agg_circuit_level_1.break_points();
// #[test]
// fn test_generate_zkevm_sha256() {
// println!("Generating dummy snark");
// generate_zkevm_sha256_circuit(
// "./certs/example_cert_3.pem",
// 11
// );
// }
let agg_circuit1 = AggregationCircuit::new::<SHPLONK>(
CircuitBuilderStage::Prover,
agg_config_level_1,
&agg_params_level_1,
vec![snark1, snark2],
VerifierUniversality::Full,
).use_break_points(break_points_level_1.clone());
println!("Generating aggregation snark");
let agg_snark1 = gen_snark_shplonk(&agg_params_level_1, &pk_level_1, agg_circuit1, None::<&str>);
println!("Aggregation snark success");
// Create second aggregation snark
println!("Generating dummy snark");
let snark3 = generate_zkevm_sha256_circuit(
"./certs/example_cert_2.pem",
"./certs/example_cert_1.pem",
11
);
let snark4 = generate_rsa_circuit(
"./certs/example_cert_2.pem",
"./certs/example_cert_1.pem",
16
);
// std::fs::remove_file(Path::new("examples/agg.pk")).ok();
// let _pk = gen_pk(&params, &agg_circuit2, Some(Path::new("examples/agg.pk")));
// end_timer!(start0);
// let pk = read_pk::<AggregationCircuit>(Path::new("examples/agg.pk"), agg_config_level_1).unwrap();
// std::fs::remove_file(Path::new("examples/agg.pk")).ok();
// let break_points_level_1 = agg_circuit2.break_points();
let agg_circuit2 = AggregationCircuit::new::<SHPLONK>(
CircuitBuilderStage::Prover,
agg_config_level_1,
&agg_params_level_1,
vec![snark3, snark4],
VerifierUniversality::Full,
).use_break_points(break_points_level_1.clone());
println!("Generating aggregation snark");
let agg_snark2 = gen_snark_shplonk(&agg_params_level_1, &pk_level_1, agg_circuit2, None::<&str>);
println!("Aggregation snark success");
// Level 2 aggregation
// Create an aggregation circuit using the snark
let agg_k3 = 22;
let agg_lookup_bits3 = agg_k3 - 1;
let agg_params3 = gen_srs(agg_k3 as u32);
let mut agg_circuit3 = AggregationCircuit::new::<SHPLONK>(
CircuitBuilderStage::Keygen,
AggregationConfigParams {degree: agg_k3, lookup_bits: agg_lookup_bits3 as usize, ..Default::default()},
&agg_params3,
vec![agg_snark1.clone(), agg_snark2.clone()],
VerifierUniversality::Full
);
println!("Aggregation circuit calculating params");
let agg_config3 = agg_circuit3.calculate_params(Some(10));
// let start0 = start_timer!(|| "gen vk & pk");
println!("Aggregation circuit generating pk");
let pk3 = gen_pk(&agg_params3, &agg_circuit3, None);
let break_points3 = agg_circuit3.break_points();
// std::fs::remove_file(Path::new("examples/agg.pk")).ok();
// let _pk = gen_pk(&params, &agg_circuit2, Some(Path::new("examples/agg.pk")));
// end_timer!(start0);
// let pk = read_pk::<AggregationCircuit>(Path::new("examples/agg.pk"), agg_config3).unwrap();
// std::fs::remove_file(Path::new("examples/agg.pk")).ok();
// let break_points3 = agg_circuit2.break_points();
let agg_circuit3 = AggregationCircuit::new::<SHPLONK>(
CircuitBuilderStage::Prover,
agg_config3,
&agg_params3,
vec![agg_snark1, agg_snark2],
VerifierUniversality::Full,
).use_break_points(break_points3.clone());
println!("Generating aggregation snark");
let _agg_snark3 = gen_snark_shplonk(&agg_params3, &pk3, agg_circuit3, None::<&str>);
println!("Aggregation snark success");
}
#[test]
fn test_aggregation_split_zkevm_sha256_rsa1() {
println!("Generating dummy snark");
let snark1 = generate_zkevm_sha256_circuit(
"./certs/example_cert_3.pem",
"./certs/example_cert_2.pem",
13
);
let snark2 = generate_rsa_circuit(
"./certs/example_cert_3.pem",
"./certs/example_cert_2.pem",
16
);
// Create an aggregation circuit using the snark
let agg_k = 20;
let agg_lookup_bits = agg_k - 1;
let agg_params = gen_srs(agg_k as u32);
let mut agg_circuit = AggregationCircuit::new::<SHPLONK>(
CircuitBuilderStage::Keygen,
AggregationConfigParams {degree: agg_k, lookup_bits: agg_lookup_bits as usize, ..Default::default()},
&agg_params,
vec![snark1.clone(), snark2.clone()],
VerifierUniversality::Full
);
println!("Aggregation circuit calculating params");
let agg_config = agg_circuit.calculate_params(Some(10));
// let start0 = start_timer!(|| "gen vk & pk");
println!("Aggregation circuit generating pk");
let pk = gen_pk(&agg_params, &agg_circuit, None);
let break_points = agg_circuit.break_points();
// std::fs::remove_file(Path::new("examples/agg.pk")).ok();
// let _pk = gen_pk(&params, &agg_circuit, Some(Path::new("examples/agg.pk")));
// end_timer!(start0);
// let pk = read_pk::<AggregationCircuit>(Path::new("examples/agg.pk"), agg_config).unwrap();
// std::fs::remove_file(Path::new("examples/agg.pk")).ok();
// let break_points = agg_circuit.break_points();
let agg_circuit = AggregationCircuit::new::<SHPLONK>(
CircuitBuilderStage::Prover,
agg_config,
&agg_params,
vec![snark1, snark2],
VerifierUniversality::Full,
).use_break_points(break_points.clone());
println!("Generating aggregation snark");
let _agg_snark = gen_snark_shplonk(&agg_params, &pk, agg_circuit, None::<&str>);
println!("Aggregation snark success");
}
#[test]
fn test_aggregation_split_zkevm_sha256_rsa2() {
println!("Generating dummy snark");
let snark1 = generate_zkevm_sha256_circuit(
"./certs/example_cert_2.pem",
"./certs/example_cert_1.pem",
13
);
let snark2 = generate_rsa_circuit(
"./certs/example_cert_2.pem",
"./certs/example_cert_1.pem",
16
);
// Create an aggregation circuit using the snark
let agg_k = 20;
let agg_lookup_bits = agg_k - 1;
let agg_params = gen_srs(agg_k as u32);
let mut agg_circuit = AggregationCircuit::new::<SHPLONK>(
CircuitBuilderStage::Keygen,
AggregationConfigParams {degree: agg_k, lookup_bits: agg_lookup_bits as usize, ..Default::default()},
&agg_params,
vec![snark1.clone(), snark2.clone()],
VerifierUniversality::Full
);
println!("Aggregation circuit calculating params");
let agg_config = agg_circuit.calculate_params(Some(10));
// let start0 = start_timer!(|| "gen vk & pk");
println!("Aggregation circuit generating pk");
let pk = gen_pk(&agg_params, &agg_circuit, None);
let break_points = agg_circuit.break_points();
// std::fs::remove_file(Path::new("examples/agg.pk")).ok();
// let _pk = gen_pk(&params, &agg_circuit, Some(Path::new("examples/agg.pk")));
// end_timer!(start0);
// let pk = read_pk::<AggregationCircuit>(Path::new("examples/agg.pk"), agg_config).unwrap();
// std::fs::remove_file(Path::new("examples/agg.pk")).ok();
// let break_points = agg_circuit.break_points();
let agg_circuit = AggregationCircuit::new::<SHPLONK>(
CircuitBuilderStage::Prover,
agg_config,
&agg_params,
vec![snark1, snark2],
VerifierUniversality::Full,
).use_break_points(break_points.clone());
println!("Generating aggregation snark");
let _agg_snark = gen_snark_shplonk(&agg_params, &pk, agg_circuit, None::<&str>);
println!("Aggregation snark success");
}
#[test]
fn test_aggregation_split_zkevm_sha256_rsa3() {
println!("Generating dummy snark");
let snark1 = generate_zkevm_sha256_circuit(
"./certs/example_cert_3.pem",
"./certs/example_cert_2.pem",
11
);
let snark2 = generate_rsa_circuit(
"./certs/example_cert_3.pem",
"./certs/example_cert_2.pem",
16
);
let snark3 = generate_zkevm_sha256_circuit(
"./certs/example_cert_2.pem",
"./certs/example_cert_1.pem",
11
);
let snark4 = generate_rsa_circuit(
"./certs/example_cert_2.pem",
"./certs/example_cert_1.pem",
16
);
// Create an aggregation circuit using the snark
let agg_k = 20;
let agg_lookup_bits = agg_k - 1;
let agg_params = gen_srs(agg_k as u32);
let mut agg_circuit = AggregationCircuit::new::<SHPLONK>(
CircuitBuilderStage::Keygen,
AggregationConfigParams {degree: agg_k, lookup_bits: agg_lookup_bits as usize, ..Default::default()},
&agg_params,
vec![snark1.clone(), snark2.clone(), snark3.clone(), snark4.clone()],
VerifierUniversality::Full
);
println!("Aggregation circuit calculating params");
let agg_config = agg_circuit.calculate_params(Some(10));
// let start0 = start_timer!(|| "gen vk & pk");
println!("Aggregation circuit generating pk");
let pk = gen_pk(&agg_params, &agg_circuit, None);
let break_points = agg_circuit.break_points();
// std::fs::remove_file(Path::new("examples/agg.pk")).ok();
// let _pk = gen_pk(&params, &agg_circuit, Some(Path::new("examples/agg.pk")));
// end_timer!(start0);
// let pk = read_pk::<AggregationCircuit>(Path::new("examples/agg.pk"), agg_config).unwrap();
// std::fs::remove_file(Path::new("examples/agg.pk")).ok();
// let break_points = agg_circuit.break_points();
let agg_circuit = AggregationCircuit::new::<SHPLONK>(
CircuitBuilderStage::Prover,
agg_config,
&agg_params,
vec![snark1, snark2, snark3, snark4],
VerifierUniversality::Full,
).use_break_points(break_points.clone());
println!("Generating aggregation snark");
let _agg_snark = gen_snark_shplonk(&agg_params, &pk, agg_circuit, None::<&str>);
println!("Aggregation snark success");
}
// #[test]
// fn test_generate_rsa() {
// println!("Generating dummy snark");
// generate_rsa_circuit_with_instances(
// "./certs/example_cert_3.pem",
// "./certs/example_cert_2.pem",
// 16
// );
// }