Skip to content

Commit

Permalink
Merge pull request #106 from okx/feature/ruanpc/dump_circuit_in_proof
Browse files Browse the repository at this point in the history
Feature/ruanpc/dump circuit in proof
  • Loading branch information
RUAN0007 authored Oct 18, 2024
2 parents af78b3e + 5c2204b commit 341fc79
Show file tree
Hide file tree
Showing 9 changed files with 61 additions and 170 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ my_permanent_leveldb/
*level_db*/
*.json
*DS_Store
*tar
*.tar
/release/
*.zip
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ file_num=10
per_file_account_num=131072 # multiple of 1024, the batch size
# test data will be generated to ./test-data/user-data
rm -rf ./text-data/user-data
mkdir -p ./text-data/user-data
rm -rf ./test-data/user-data
mkdir -p ./test-data/user-data
python3 scripts/gen_test_data.py ${file_num} ${per_file_account_num}
```

Expand Down Expand Up @@ -64,7 +64,7 @@ cargo run --features zk-por-core/verifier --release --package zk-por-cli --bin z
- verify both the global proof and a user proof

Note:
1. The cmd will NOT rebuild the circuit. Instead, it directly uses and trusts the circuit in the proof file. So the verification is fast, but not as secure as above.
1. The cmd will NOT rebuild the circuit. Instead, it directly uses and trusts the circuit in the proof file. So the verification is fast, but a user needs to incur a weaker trust assumption.
2. The cmd will auto-detect sum_proof_data.json and *_inclusion_proof.json in the same directory of the binary for the verification.

```
Expand All @@ -77,9 +77,9 @@ cp $global_proof_path tmp/sum_proof_data.json
rm -rf tmp
```

- print circuit verifier data
- print commit hash
```
cargo run --release --package zk-por-cli --bin zk-por-cli print-root-circuit-verifier --proof-path ${global_proof_path}
cargo run --release --package zk-por-cli --bin zk-por-cli show-commit-hash
```

## cli tool
Expand Down
21 changes: 7 additions & 14 deletions crates/zk-por-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use zk_por_cli::{
checker::check_non_neg_user,
constant::{DEFAULT_USER_PROOF_FILE_PATTERN, GLOBAL_PROOF_FILENAME},
prover::prove,
verifier::{print_circuit_verifier_hex, verify_global, verify_user},
verifier::{verify_global, verify_user},
};
use zk_por_core::error::PoRError;

Expand All @@ -36,10 +36,6 @@ pub enum ZkPorCommands {
#[arg(short, long)]
cfg_path: String, // path to config file
},
PrintRootCircuitVerifier {
#[arg(short, long)]
proof_path: String,
},

VerifyGlobal {
#[arg(short, long)]
Expand Down Expand Up @@ -74,11 +70,6 @@ impl Execute for Option<ZkPorCommands> {
check_non_neg_user(prover_cfg)
}

Some(ZkPorCommands::PrintRootCircuitVerifier { proof_path }) => {
let global_proof_path = PathBuf::from_str(&proof_path).unwrap();
print_circuit_verifier_hex(global_proof_path)
}

Some(ZkPorCommands::VerifyGlobal { proof_path: global_proof_path }) => {
let global_proof_path = PathBuf::from_str(&global_proof_path).unwrap();
verify_global(global_proof_path, true, true)
Expand Down Expand Up @@ -135,13 +126,15 @@ impl Execute for Option<ZkPorCommands> {

fn main() {
let cli = Cli::parse();
let start = std::time::Instant::now();
let r = cli.command.execute();
let duration = start.elapsed();
println!("Execution result: {:?}, duration: {:?}", r, duration);

let is_prove_command =
matches!(cli.command, Some(ZkPorCommands::Prove { cfg_path: _, output_path: _ }));
if is_prove_command {
println!("Execution result: {:?}", r);
} else {
println!("Execution result: {:?}. Press Enter to quit...", r);
if !is_prove_command {
println!("Press Enter to quit...");
stdin().read_exact(&mut [0]).unwrap();
}
}
16 changes: 12 additions & 4 deletions crates/zk-por-cli/src/prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use super::constant::{
USER_PROOF_DIRNAME,
};
use indicatif::ProgressBar;
use plonky2::hash::hash_types::HashOut;
use plonky2::{hash::hash_types::HashOut, util::serialization::DefaultGateSerializer};
use plonky2_field::types::PrimeField64;
use rayon::{iter::ParallelIterator, prelude::*};

Expand All @@ -30,7 +30,7 @@ use zk_por_core::{
parser::{AccountParser, FileAccountReader, FileManager, FilesCfg},
recursive_prover::recursive_circuit::RecursiveTargets,
types::F,
CircuitConfigs, General, Info, Proof,
CircuitsInfo, General, Info, Proof,
};
use zk_por_tracing::{init_tracing, TraceConfig};

Expand Down Expand Up @@ -317,18 +317,26 @@ pub fn prove(cfg: ProverConfig, proof_output_path: PathBuf) -> Result<(), PoRErr

let root_vd_digest = circuit_registry.get_root_circuit().verifier_only.circuit_digest;

let root_circuit_verifier_data = circuit_registry.get_root_circuit().verifier_data();

let root_circuit_verifier_data_bytes = root_circuit_verifier_data
.to_bytes(&DefaultGateSerializer)
.expect("fail to serialize root circuit verifier data");
let root_circuit_verifier_data_hex_str = hex::encode(root_circuit_verifier_data_bytes);

let proof = Proof {
general: General {
round_num: cfg.prover.round_no,
recursion_branchout_num: RECURSION_BRANCHOUT_NUM,
batch_size: batch_size,
token_num: token_num,
},
root_vd_digest: root_vd_digest,
circuit_configs: Some(CircuitConfigs {
circuits_info: Some(CircuitsInfo {
batch_circuit_config: batch_circuit_config,
recursive_circuit_configs: recursive_circuit_configs,
root_verifier_data_hex: root_circuit_verifier_data_hex_str,
}),
root_vd_digest: root_vd_digest,
proof: root_proof,
};

Expand Down
88 changes: 32 additions & 56 deletions crates/zk-por-cli/src/verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,24 @@ use std::{fs::File, path::PathBuf};
use super::constant::RECURSION_BRANCHOUT_NUM;
use zk_por_core::{
circuit_config::{STANDARD_CONFIG, STANDARD_ZK_CONFIG},
circuit_registry::{precompiled_registry::get_verifier_for_round, registry::CircuitRegistry},
circuit_registry::registry::CircuitRegistry,
error::PoRError,
merkle_proof::MerkleProof,
recursive_prover::recursive_circuit::RecursiveTargets,
types::F,
types::{C, D, F},
Proof,
};

use plonky2::hash::hash_types::HashOut;
use plonky2::{hash::hash_types::HashOut, plonk::circuit_data::VerifierCircuitData};
use rayon::iter::ParallelIterator;

use glob::glob;
use std::io;

// some proof files may not contain the circuit_configs field, we hardcode the default config in this case.
fn default_circuit_configs() -> (CircuitConfig, Vec<CircuitConfig>) {
static ROOT_CIRCUIT_HEX_FOR_508787475: &str = "0100000000000000e3370d1646daebec7fa045ddf1cc918706777cb88875ea173623eff57b773bc68f62cdf279612bd8c095eb7bad5feaf5209df02981e0b88ef5b178862e00694ba296ce1215562eabcac32a3b9a5aae1dcf6422a739a392ffc1b87f102bdf523d8700000000000000500000000000000002000000000000006400000000000000020000000000000008000000000000000101030000000000000001000000000000001c00000000000000100000000104000000000000000500000000000000030000000000000001000000000000001c00000000000000100000000104000000000000000500000000000000040000000000000004000000000000000400000000000000040000000000000004000000000000001300000000000000010e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000001000000000000000100000000000000010000000000000001000000000000000200000000000000020000000000000003000000000000000000000000000000070000000000000007000000000000000c000000000000000c000000000000000e0000000000000008000000000000007b0000000000000005000000000000000600000000000000500000000000000001000000000000000700000000000000310000000000000057010000000000006109000000000000a74100000000000091cb010000000000f7900c0000000000c1f657000000000047bf670200000000f13ad61000000000979cdb75000000002148013903000000e7f8088f1600000051ce3ee99d00000037a4b76051040000817d05a5391e0000876e268393d30000b1050d9608c90500d7275b1a3c7f2800e1167eb8a47a1b0127a0720b815ac007116122508779423676a7f030b452d17b37949456f042b9627f0d105e94d410b3755e709212d075e52d95120188b038463a148207b9d38ceb908d8e3415cad970eddee56f9786f4157b18490f24aeaf9959abff6a00c3cd336eaffdec0355a06a00ccef7a1d5362eafa938e5cd445b068d40be687d0e8d1dcc6524ab7b95dbd096a43080314902d44e5d739158df03edd3de79494e193b80cab5212102b0b0c59ab4280702f4e546faad281134f234e0ba6c28c8829f7224f8852d9bb24c2f429b741f122024fb12500cc98f40f29d90700942db06f1ff036ff0b3fd10edc9080f653b9b86a04f683b74b110dee1eba9bfd11795b86d81642ea7d4f80adeb9fce61712c82c3715fa6a319378f5c1c9c8c72b381ea8ac644d819e88b69d16de1e9a958d3e2bf002a659d6cc733410526c446f8736acd240a5de8c92be99f01478b55853260620bf1ce4ea561a1b54f97a81e85ab69fb2d239ccea3b0e3e341f644a17ad4393ccdbbe2615acf94ab9c2233a678ab11b248f265884cb07be0fc9fc9b317d26128ea5f83e2a5beac1d679f972a8936b9d3d15b2525c07d10cbbc8205034170738d29932614c71128df22060e8c717c181af42a62d21a67abb8ac2cafbabbd1af10b938ca1122bcce790f8d8709000000000000000e00000000000000090000000b0000000c000000020000003f000000000000000400000004000000000000000e0000000100000000000000140000000000000000000000000000000f0000002000000000000000100000002b00000000000000010000000a00000000000000000000001400000000000000080000000d000000000000000500000042000000000000000e0000000400000000000000040000000000000002000000000000000d000000";

// The proof file at round 508787475 on Sept 16th 2024 does not contain the circuit_infos, we hardcode in this case.
fn circuit_configs_for_508787475() -> (CircuitConfig, Vec<CircuitConfig>) {
(STANDARD_CONFIG, vec![STANDARD_CONFIG, STANDARD_CONFIG, STANDARD_ZK_CONFIG])
}

Expand Down Expand Up @@ -116,29 +118,44 @@ pub fn verify_global(
let proof_file = File::open(&global_proof_path).unwrap();
let reader = std::io::BufReader::new(proof_file);

// Parse the JSON as Proof
let proof: Proof = from_reader(reader).unwrap();

if proof.general.recursion_branchout_num != RECURSION_BRANCHOUT_NUM {
panic!("The recursion_branchout_num is not configured to be equal to 64");
}
let round_num = proof.general.round_num;
let root_circuit_verifier_data = get_verifier_for_round(round_num);
let root_verifier_data_hex: String;
let (mut batch_circuit_config, mut recursive_circuit_configs) =
(CircuitConfig::default(), vec![]);
(_, _) = (batch_circuit_config, recursive_circuit_configs); // To quell the compiler, i.e., circuit configs are useless if not rebuilding the circuit.

if let Some(circuits_info) = proof.circuits_info {
(batch_circuit_config, recursive_circuit_configs) =
(circuits_info.batch_circuit_config, circuits_info.recursive_circuit_configs);
root_verifier_data_hex = circuits_info.root_verifier_data_hex;
// only round number 508787475 does not contain the circuit_infos field, we hardcode in this case.
} else if round_num == 508787475 {
(batch_circuit_config, recursive_circuit_configs) = circuit_configs_for_508787475();
root_verifier_data_hex = ROOT_CIRCUIT_HEX_FOR_508787475.to_string();
} else {
return Err(PoRError::InvalidProof);
}

let root_circuit_verifier_data_bytes = hex::decode(root_verifier_data_hex)
.expect("fail to decode root circuit verifier data hex string");

let root_circuit_verifier_data = VerifierCircuitData::<F, C, D>::from_bytes(
root_circuit_verifier_data_bytes,
&DefaultGateSerializer,
)
.expect("fail to parse root circuit verifier data");

let round_num = proof.general.round_num;
if check_circuit {
let token_num = proof.general.token_num;
let round_num = proof.general.round_num;
let batch_size = proof.general.batch_size;

// There are cases that the proof file does not contain the circuit_configs field, we hardcode the default config in this case.
let (mut batch_circuit_config, mut recursive_circuit_configs) = default_circuit_configs();

if let Some(circuit_configs) = &proof.circuit_configs {
recursive_circuit_configs = circuit_configs.recursive_circuit_configs.clone();
batch_circuit_config = circuit_configs.batch_circuit_config.clone();
}

if verbose {
println!(
"start to reconstruct the circuit with {} recursive levels for round {}",
Expand Down Expand Up @@ -192,44 +209,3 @@ pub fn verify_global(

result.map_err(|_| PoRError::InvalidProof)
}

pub fn print_circuit_verifier_hex(global_proof_path: PathBuf) -> Result<(), PoRError> {
let proof_file = File::open(&global_proof_path).unwrap();
let reader = std::io::BufReader::new(proof_file);
let proof: Proof = from_reader(reader).unwrap();

if proof.general.recursion_branchout_num != RECURSION_BRANCHOUT_NUM {
panic!("The recursion_branchout_num is not configured to be equal to 64");
}
let token_num = proof.general.token_num;
let batch_size = proof.general.batch_size;

let (mut batch_circuit_config, mut recursive_circuit_configs) = default_circuit_configs();

if let Some(circuit_configs) = &proof.circuit_configs {
recursive_circuit_configs = circuit_configs.recursive_circuit_configs.clone();
batch_circuit_config = circuit_configs.batch_circuit_config.clone();
}

let circuit_registry = CircuitRegistry::<RECURSION_BRANCHOUT_NUM>::init(
batch_size,
token_num,
batch_circuit_config,
recursive_circuit_configs,
);

let root_circuit = circuit_registry.get_root_circuit();

let verifier_data = root_circuit.verifier_data().clone();

let gate_serializer = DefaultGateSerializer;
let verifier_data_bytes = verifier_data.to_bytes(&gate_serializer).unwrap();

if proof.root_vd_digest != verifier_data.verifier_only.circuit_digest {
return Err(PoRError::CircuitMismatch);
}

println!("{}", hex::encode(verifier_data_bytes));

Ok(())
}
1 change: 0 additions & 1 deletion crates/zk-por-core/src/circuit_registry/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
pub mod precompiled_registry;
pub mod registry;
85 changes: 0 additions & 85 deletions crates/zk-por-core/src/circuit_registry/precompiled_registry.rs

This file was deleted.

5 changes: 3 additions & 2 deletions crates/zk-por-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,15 @@ pub struct Proof {
pub general: General,
pub root_vd_digest: HashOut<F>,
#[serde(default)] // some proof files may not have this field.
pub circuit_configs: Option<CircuitConfigs>,
pub circuits_info: Option<CircuitsInfo>,
pub proof: ProofWithPublicInputs<F, C, D>,
}

#[derive(Serialize, Deserialize)]
pub struct CircuitConfigs {
pub struct CircuitsInfo {
pub batch_circuit_config: CircuitConfig,
pub recursive_circuit_configs: Vec<CircuitConfig>,
pub root_verifier_data_hex: String,
}

#[derive(Serialize, Deserialize)]
Expand Down
2 changes: 0 additions & 2 deletions scripts/release/verifier/common.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
function build_and_package() {
mkdir -p validator/bin
TARGET=$1
rustup target add $TARGET
VERSION=$2
Expand All @@ -19,6 +18,5 @@ function build_and_package() {

zip ./zk_STARK_Validator_V2_${TARGET}_${VERSION}.zip ./zk_STARK_Validator_V2_${TARGET}_${VERSION}
rm ./zk_STARK_Validator_V2_${TARGET}_${VERSION}
mv ./zk_STARK_Validator_V2_${TARGET}_${VERSION}.zip validator/bin
unset COMMIT_HASH
}

0 comments on commit 341fc79

Please sign in to comment.