mirror of
https://github.com/logos-storage/proof-aggregation.git
synced 2026-01-03 06:13:11 +00:00
improve workflow bash script, and update readme
This commit is contained in:
parent
3c3de2b26d
commit
35ee544e68
1
workflow/.gitignore
vendored
Normal file → Executable file
1
workflow/.gitignore
vendored
Normal file → Executable file
@ -8,6 +8,7 @@ Cargo.lock
|
||||
# Profile-guided optimization
|
||||
/tmp
|
||||
pgo-data.profdata
|
||||
/output
|
||||
|
||||
# MacOS nuisances
|
||||
.DS_Store
|
||||
|
||||
122
workflow/README.md
Normal file → Executable file
122
workflow/README.md
Normal file → Executable file
@ -10,20 +10,10 @@ This crate can be used to:
|
||||
- Generate circuit input from **fake data** with given params.
|
||||
- Build the Plonky2 codex storage proof circuits.
|
||||
- Generate a proof with given proof input in JSON file.
|
||||
- Aggregate multiple proofs with 2-to-1 tree like aggregation to generate a final proof.
|
||||
- Aggregate multiple proofs with 2-to-1 tree like aggregation to generate a final proof (with optional compression).
|
||||
- Wrapping proof with BN254 Poseidon Hash.
|
||||
- Verify the proof.
|
||||
|
||||
## Code organization
|
||||
|
||||
- [`gen_input`](./src/bin/gen_input.rs) contains the main function to generate input with the given params as environment variables.
|
||||
|
||||
- [`build_circ`](./src/bin/build_circ.rs) contains the main function to build the storage proof (Sampling) circuits.
|
||||
|
||||
- [`prove`](./src/bin/prove.rs) contains the main function to generate a single proof.
|
||||
|
||||
- [`aggregate`](./src/bin/aggregate.rs) contains the main function to aggregate `k` (default = 4) proofs.
|
||||
|
||||
- [`verify`](./src/bin/verify) contains the main function to verify the storage proof (Sampling) proof.
|
||||
- Wrap the proof with Gnark-plonky2-verifier to get a final succinct Groth16 proof.
|
||||
|
||||
## Usage
|
||||
|
||||
@ -43,11 +33,13 @@ To ensure that the nightly toolchain is used when building this crate, you can s
|
||||
rustup override set nightly
|
||||
```
|
||||
|
||||
- Go 1.22+ (for the GNARK-based verifier)
|
||||
|
||||
### Generate Circuit Input
|
||||
The steps to generate circuit input with **fake data** are the following:
|
||||
|
||||
#### Step 1: Setting Up Parameters
|
||||
Parameters for generating the circuit input can be defined in [`params.sh`](scripts/params.sh).
|
||||
- Input params: parameters for generating the circuit input can be defined in [`params.sh`](scripts/params.sh).
|
||||
You can customize the test parameters by setting the following environment variables:
|
||||
|
||||
```bash
|
||||
@ -64,76 +56,54 @@ export NSLOTS=11 # Number of slots in the dataset
|
||||
export SLOTINDEX=3 # Which slot to prove (0..NSLOTS-1)
|
||||
export NCELLS=512 # Number of cells in this slot
|
||||
```
|
||||
|
||||
#### Step 2: Run the Script
|
||||
Once the params are set, you can run the script to generate the circuit input (with fake data).
|
||||
- Circuit parameters: Edit [`circ_params.sh`](./scripts/circ_params.sh) for:
|
||||
|
||||
```bash
|
||||
sudo bash ./scripts/gen_input.sh
|
||||
```
|
||||
export MAX_DEPTH=32 # maximum depth of the slot tree
|
||||
export MAX_LOG2_N_SLOTS=8 # Depth of the dataset tree = ceiling_log2(max_slots)
|
||||
export BLOCK_TREE_DEPTH=5 # depth of the mini tree (block tree)
|
||||
export N_FIELD_ELEMS_PER_CELL=272 # number of field elements per cell
|
||||
export N_SAMPLES=100 # number of samples to prove
|
||||
|
||||
### Build the Circuit
|
||||
To build the circuit and measure the time to build, you can simply run the script:
|
||||
export T=4 # number of proofs to aggregate
|
||||
```
|
||||
- GNARK-verifier params [`gnark_params.sh`](./scripts/gnark_params.sh):
|
||||
```bash
|
||||
sudo bash ./scripts/build_circuit.sh
|
||||
export CIRCUIT_DIR="$BASE_DIR/../output/wrap/verifier_data"
|
||||
export DATA_DIR="$BASE_DIR/../output/gnark_output"
|
||||
export PROOF_SYSTEM="groth16"
|
||||
export DUMMY="false"
|
||||
```
|
||||
To see the source code of how to build the circuit, see [`build_circ`](./src/bin/build_circ.rs).
|
||||
|
||||
### Generate the Proof
|
||||
After generating the circuit input (in a JSON file), you can run the circuits to generate the proofs.
|
||||
First make sure you have the circuit data and input from previous scripts then follow the steps:
|
||||
|
||||
#### Step 1: Setting Up Circuit Parameters
|
||||
Parameters for the circuit can be defined in [`circ_params.sh`](scripts/circ_params.sh).
|
||||
You can customize the test parameters by setting the following environment variables:
|
||||
#### Step 2: Run the Rust CLI
|
||||
All steps are unified under [`run_cli.sh`](./scripts/run_cli.sh) By default, it will run nothing until you specify the operations.
|
||||
```bash
|
||||
export MAX_DEPTH=32 # maximum depth of the slot tree
|
||||
export MAX_LOG2_N_SLOTS=8 # Depth of the dataset tree = ceiling_log2(max_slots)
|
||||
export BLOCK_TREE_DEPTH=5 # depth of the mini tree (block tree)
|
||||
export N_FIELD_ELEMS_PER_CELL=272 # number of field elements per cell
|
||||
export N_SAMPLES=100 # number of samples to prove
|
||||
# Show help and list all available flags
|
||||
./scripts/run_cli.sh -h
|
||||
|
||||
# Generate inputs, build, prove, aggregate, wrap & verify—all in one:
|
||||
./scripts/run_cli.sh --all
|
||||
|
||||
# Or pick individual operations:
|
||||
./scripts/run_cli.sh \
|
||||
--gen-input \
|
||||
--build \
|
||||
--prove \
|
||||
--aggregate \
|
||||
--wrap-tree \
|
||||
--verify-tree
|
||||
```
|
||||
|
||||
#### Step 2: Run the Script
|
||||
Once the params are set, you can run the script to generate the proof.
|
||||
You can also see the time taken to generate the proof.
|
||||
|
||||
#### Step 3: Go/GNARK CLI workflow
|
||||
To compile, prove, or verify wrapped Plonky2 circuits via GNARK, use:
|
||||
```bash
|
||||
sudo bash ./scripts/prove.sh
|
||||
./scripts/run_gnark_cli.sh -h
|
||||
|
||||
# run all steps (compile, prove, verify) with defaults:
|
||||
./scripts/run_gnark_cli.sh
|
||||
|
||||
# or individually:
|
||||
./scripts/run_gnark_cli.sh --compile
|
||||
./scripts/run_gnark_cli.sh --prove
|
||||
./scripts/run_gnark_cli.sh --verify
|
||||
```
|
||||
|
||||
### Verify the proof
|
||||
To verify the generated proof, run the following script.
|
||||
Make sure that you generate the circuit data and proof prior to this.
|
||||
|
||||
```bash
|
||||
sudo bash ./scripts/verify.sh
|
||||
```
|
||||
|
||||
### Build, Prove, and Verify
|
||||
To automate the whole process, you can run the following script
|
||||
the script builds the circuit, loads the JSON circuit input, generates the proof, and verifies it.
|
||||
It also shows the time taken for each step.
|
||||
Make sure that you generate the circuit input prior to this so that you have the [`JSON input file`](./input.json) and set the [`circ_params.sh`](scripts/circ_params.sh).
|
||||
|
||||
```bash
|
||||
sudo bash ./scripts/prove_and_verify.sh
|
||||
```
|
||||
This script simply runs all previous scripts.
|
||||
|
||||
### Aggregate K Proofs
|
||||
To do this, you can run the following script.
|
||||
Note that we don't actually generate `K` proofs but rather just clone the single generated proof which is enough for testing.
|
||||
Make sure a proof is already generated using the script for proving above.
|
||||
|
||||
```bash
|
||||
sudo bash ./scripts/aggregate.sh
|
||||
```
|
||||
|
||||
|
||||
or the following if you want to specify the number of proofs to be aggregated
|
||||
```bash
|
||||
sudo bash ./scripts/aggregate.sh -- "$K_VALUE"
|
||||
```
|
||||
|
||||
|
||||
|
||||
@ -1,14 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Source the parameters from the scripts directory
|
||||
source "params.sh"
|
||||
|
||||
# Change to the parent directory of the script
|
||||
cd "$(dirname "$0")/.." || { echo "Failed to change directory"; exit 1; }
|
||||
|
||||
# Build
|
||||
cargo build --release || { echo "prove.sh: cargo build failed"; exit 101; }
|
||||
|
||||
# Run the Rust executable
|
||||
K_VALUE=${1:-4}
|
||||
cargo run --bin aggregate --features "parallel" -- "$K_VALUE" || { echo "prove.sh: cargo run failed"; exit 102; }
|
||||
@ -1,14 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Source the parameters from the scripts directory
|
||||
source "params.sh"
|
||||
|
||||
# Change to the parent directory of the script
|
||||
cd "$(dirname "$0")/.." || { echo "Failed to change directory"; exit 1; }
|
||||
|
||||
# Build
|
||||
cargo build --release || { echo "build_circuit.sh: cargo build failed"; exit 101; }
|
||||
|
||||
# Run the Rust executable
|
||||
cargo run --bin build_circ --features "parallel" || { echo "build_circuit.sh: cargo run failed"; exit 102; }
|
||||
|
||||
@ -4,4 +4,6 @@ export MAX_DEPTH=32 # maximum depth of the slot tree
|
||||
export MAX_LOG2_N_SLOTS=8 # Depth of the dataset tree = ceiling_log2(max_slots)
|
||||
export BLOCK_TREE_DEPTH=5 # depth of the mini tree (block tree)
|
||||
export N_FIELD_ELEMS_PER_CELL=272 # number of field elements per cell
|
||||
export N_SAMPLES=100 # number of samples to prove
|
||||
export N_SAMPLES=100 # number of samples to prove
|
||||
|
||||
export T=4 # number of proofs to aggregate
|
||||
@ -1,13 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Source the parameters from params.sh
|
||||
source ./params.sh
|
||||
|
||||
# Change to the parent directory of the script
|
||||
cd "$(dirname "$0")/.." || { echo "Failed to change directory"; exit 1; }
|
||||
|
||||
# Build
|
||||
cargo build --release || { echo "gen_input.sh: cargo build failed"; exit 101; }
|
||||
|
||||
# Run the Rust executable
|
||||
cargo run --bin gen_input --features "parallel" || { echo "gen_input.sh: cargo run failed"; exit 102; }
|
||||
8
workflow/scripts/gnark_params.sh
Executable file
8
workflow/scripts/gnark_params.sh
Executable file
@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
# current dir
|
||||
BASE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
export CIRCUIT_DIR="$BASE_DIR/../output/wrap/verifier_data"
|
||||
export DATA_DIR="$BASE_DIR/../output/gnark_output"
|
||||
export PROOF_SYSTEM="groth16"
|
||||
export DUMMY="false"
|
||||
@ -1,13 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Source the parameters from params.sh
|
||||
source ./circ_params.sh
|
||||
|
||||
# Change to the parent directory of the script
|
||||
cd "$(dirname "$0")/.." || { echo "Failed to change directory"; exit 1; }
|
||||
|
||||
# Build
|
||||
cargo build --release || { echo "prove.sh: cargo build failed"; exit 101; }
|
||||
|
||||
# Run the Rust executable
|
||||
cargo run --bin prove --features "parallel" || { echo "prove.sh: cargo run failed"; exit 102; }
|
||||
@ -1,42 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Source the parameters
|
||||
source ./params.sh
|
||||
source ./circ_params.sh
|
||||
|
||||
# Change to the parent directory of the script
|
||||
cd "$(dirname "$0")/.." || { echo "Failed to change directory"; exit 1; }
|
||||
|
||||
# Build
|
||||
cargo build --release > /dev/null 2>&1 || { echo "prove_and_verify.sh: cargo build failed"; exit 101; }
|
||||
|
||||
# Run all steps
|
||||
echo "START"
|
||||
|
||||
echo "Generating Input"
|
||||
start=$(date +%s)
|
||||
cargo run --bin gen_input --features "parallel" > /dev/null 2>&1 || { echo "gen_input.sh: cargo run failed"; exit 102; }
|
||||
end=$(date +%s)
|
||||
echo "Generating Input took $((end - start)) seconds."
|
||||
|
||||
echo "Building the circuit"
|
||||
start=$(date +%s)
|
||||
cargo run --bin build_circ --features "parallel" > /dev/null 2>&1 || { echo "build_circuit.sh: cargo run failed"; exit 102; }
|
||||
end=$(date +%s)
|
||||
echo "Building the circuit took $((end - start)) seconds."
|
||||
|
||||
echo "Generating a proof"
|
||||
start=$(date +%s)
|
||||
cargo run --bin prove --features "parallel" > /dev/null 2>&1 || { echo "prove.sh: cargo run failed"; exit 102; }
|
||||
end=$(date +%s)
|
||||
echo "Generating a proof took $((end - start)) seconds."
|
||||
|
||||
echo "Verifying the proof"
|
||||
start=$(date +%s)
|
||||
cargo run --bin verify --features "parallel" > /dev/null 2>&1 || { echo "verify.sh: cargo run failed"; exit 102; }
|
||||
end=$(date +%s)
|
||||
echo "Verifying the proof took $((end - start)) seconds."
|
||||
|
||||
echo "DONE"
|
||||
|
||||
|
||||
98
workflow/scripts/run_cli.sh
Executable file
98
workflow/scripts/run_cli.sh
Executable file
@ -0,0 +1,98 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Load global and circuit-specific parameters
|
||||
source "$(dirname "$0")/params.sh"
|
||||
source "$(dirname "$0")/circ_params.sh"
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: $(basename "$0") [OPTIONS]
|
||||
|
||||
OPTIONS:
|
||||
--gen-input Generate witness inputs
|
||||
--build Compile/build the circuit
|
||||
--prove Run the prover
|
||||
--aggregate Aggregate proofs
|
||||
--aggregate-and-compress Aggregate proofs and compress
|
||||
--wrap-sampling Wrap sampling proof
|
||||
--wrap-tree Wrap tree proof
|
||||
--wrap-compress Wrap compressed-tree proof
|
||||
--verify-sampling Verify sampling proof
|
||||
--verify-tree Verify tree proof
|
||||
--verify-compressed Verify compressed-tree proof
|
||||
--verify-wrapped Verify wrapped proof
|
||||
--all Run the full pipeline in order
|
||||
-h, --help Show this help and exit
|
||||
EOF
|
||||
exit 1
|
||||
}
|
||||
|
||||
# operation flags
|
||||
DO_GEN=false DO_BUILD=false DO_PROVE=false DO_AGG=false DO_AGG_COMP=false
|
||||
DO_WRAP_SAMP=false DO_WRAP_TREE=false DO_WRAP_COMP=false
|
||||
DO_VER_SAMP=false DO_VER_TREE=false DO_VER_COMP=false DO_VER_WRAP=false
|
||||
|
||||
# parse args
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--gen-input) DO_GEN=true; shift ;;
|
||||
--build) DO_BUILD=true; shift ;;
|
||||
--prove) DO_PROVE=true; shift ;;
|
||||
--aggregate) DO_AGG=true; shift ;;
|
||||
--aggregate-and-compress) DO_AGG_COMP=true; shift ;;
|
||||
--wrap-sampling) DO_WRAP_SAMP=true; shift ;;
|
||||
--wrap-tree) DO_WRAP_TREE=true; shift ;;
|
||||
--wrap-compress) DO_WRAP_COMP=true; shift ;;
|
||||
--verify-sampling) DO_VER_SAMP=true; shift ;;
|
||||
--verify-tree) DO_VER_TREE=true; shift ;;
|
||||
--verify-compressed) DO_VER_COMP=true; shift ;;
|
||||
--verify-wrapped) DO_VER_WRAP=true; shift ;;
|
||||
--all)
|
||||
DO_GEN=true; DO_BUILD=true; DO_PROVE=true
|
||||
DO_AGG=true;
|
||||
DO_WRAP_TREE=true;
|
||||
DO_VER_SAMP=true; DO_VER_TREE=true; DO_VER_WRAP=true
|
||||
shift
|
||||
;;
|
||||
-h|--help) usage ;;
|
||||
*) echo "Unknown option: $1"; usage ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# If nothing selected, show help
|
||||
if ! $DO_GEN && ! $DO_BUILD && ! $DO_PROVE && ! $DO_AGG && ! $DO_AGG_COMP \
|
||||
&& ! $DO_WRAP_SAMP && ! $DO_WRAP_TREE && ! $DO_WRAP_COMP \
|
||||
&& ! $DO_VER_SAMP && ! $DO_VER_TREE && ! $DO_VER_COMP && ! $DO_VER_WRAP; then
|
||||
echo "No stages selected."
|
||||
usage
|
||||
fi
|
||||
|
||||
# Ensure the Rust binary is built
|
||||
echo "[build] Compiling Rust CLI…"
|
||||
cargo build --release --features parallel
|
||||
|
||||
# run a named subcommand
|
||||
run_cmd() {
|
||||
local name=$1
|
||||
local cmd=$2
|
||||
echo "[$name] Starting"
|
||||
echo "[run] $name"
|
||||
cargo run -q --release --features parallel -- $cmd #> /dev/null
|
||||
echo "[$name] Completed"
|
||||
}
|
||||
|
||||
$DO_GEN && run_cmd "GenInput" gen-input
|
||||
$DO_BUILD && run_cmd "Build" build
|
||||
$DO_PROVE && run_cmd "Prove" prove
|
||||
$DO_AGG && run_cmd "Aggregate" aggregate
|
||||
$DO_AGG_COMP && run_cmd "AggregateAndCompress" aggregate-and-compress
|
||||
$DO_WRAP_SAMP && run_cmd "WrapSampling" wrap
|
||||
$DO_WRAP_TREE && run_cmd "WrapTree" wrap-tree
|
||||
$DO_WRAP_COMP && run_cmd "WrapCompress" wrap-compress
|
||||
$DO_VER_SAMP && run_cmd "VerifySampling" verify
|
||||
$DO_VER_TREE && run_cmd "VerifyTree" verify-tree
|
||||
$DO_VER_COMP && run_cmd "VerifyCompressed" verify-compressed
|
||||
$DO_VER_WRAP && run_cmd "VerifyWrapped" verify-wrapped
|
||||
|
||||
echo "All requested steps done."
|
||||
31
workflow/scripts/run_gnark_cli.sh
Executable file
31
workflow/scripts/run_gnark_cli.sh
Executable file
@ -0,0 +1,31 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# script to invoke run_gnark_cli.sh
|
||||
|
||||
# path to this directory
|
||||
WRAPPER_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
# Path to run_gnark_cli.sh
|
||||
SCRIPT="$WRAPPER_DIR/../../gnark-wrapper/run_gnark_cli.sh"
|
||||
|
||||
if [[ ! -x "$SCRIPT" ]]; then
|
||||
echo "Error: Cannot find or execute run_gnark_cli.sh at $SCRIPT" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# params file in current working directory
|
||||
PARAMS_FILE="$(pwd)/gnark_params.sh"
|
||||
if [[ ! -f "$PARAMS_FILE" ]]; then
|
||||
echo "Error: params.sh not found in current directory ($PARAMS_FILE)" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Save CWD and switch into gnark-wrapper directory
|
||||
TARGET_DIR="$(dirname "$SCRIPT")"
|
||||
cd "$TARGET_DIR"
|
||||
|
||||
# Build and run the command
|
||||
cmd=("$SCRIPT" -P "$PARAMS_FILE" "$@")
|
||||
echo "Running in $TARGET_DIR: ${cmd[*]}"
|
||||
exec "${cmd[@]}"
|
||||
@ -1,13 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Source the parameters from params.sh
|
||||
source ./circ_params.sh
|
||||
|
||||
# Change to the parent directory of the script
|
||||
cd "$(dirname "$0")/.." || { echo "Failed to change directory"; exit 1; }
|
||||
|
||||
# Build
|
||||
cargo build --release || { echo "prove.sh: cargo build failed"; exit 101; }
|
||||
|
||||
# Run the Rust executable
|
||||
cargo run --bin verify --features "parallel" || { echo "prove.sh: cargo run failed"; exit 102; }
|
||||
76
workflow/src/aggregate.rs
Executable file
76
workflow/src/aggregate.rs
Executable file
@ -0,0 +1,76 @@
|
||||
use std::env;
|
||||
use std::time::Instant;
|
||||
use anyhow::{Context, Result};
|
||||
use plonky2::plonk::proof::ProofWithPublicInputs;
|
||||
use codex_plonky2_circuits::recursion::tree::TreeRecursion;
|
||||
use proof_input::params::{D, C, F, HF};
|
||||
use codex_plonky2_circuits::serialization::{export_proof_with_pi, export_verifier_circuit_data, import_proof_with_pi, import_verifier_circuit_data};
|
||||
use crate::file_paths::{SAMPLING_CIRC_BASE_PATH, TREE_CIRC_BASE_PATH, COMPRESS_CIRC_BASE_PATH};
|
||||
pub fn run(compress: bool) -> Result<()> {
|
||||
// load the parameters from environment variables
|
||||
const N: usize = 2;
|
||||
|
||||
// take k = "number of proofs" from env
|
||||
let t: usize = env::var("T")
|
||||
.context("T not set")?
|
||||
.parse::<usize>()
|
||||
.context("Invalid T")?;
|
||||
|
||||
match t {
|
||||
2 => run_tree::<N,2>(compress)?,
|
||||
4 => run_tree::<N, 4>(compress)?,
|
||||
8 => run_tree::<N, 8>(compress)?,
|
||||
16 => run_tree::<N, 16>(compress)?,
|
||||
32 => run_tree::<N, 32>(compress)?,
|
||||
64 => run_tree::<N, 64>(compress)?,
|
||||
128 => run_tree::<N, 128>(compress)?,
|
||||
256 => run_tree::<N, 256>(compress)?,
|
||||
512 => run_tree::<N, 512>(compress)?,
|
||||
1024 => run_tree::<N, 1024>(compress)?,
|
||||
other => panic!("unsupported proof count: {}", other),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn run_tree<const N: usize, const T: usize>(compress: bool) -> Result<()> {
|
||||
let circuit_path = SAMPLING_CIRC_BASE_PATH;
|
||||
// Read the proof
|
||||
let proof_with_pi = import_proof_with_pi::<F,C,D,_>(circuit_path)?;
|
||||
println!("Proof with public input imported from: {}", circuit_path);
|
||||
|
||||
// read the circuit data
|
||||
let verifier_data = import_verifier_circuit_data::<F,C,D,_>(circuit_path)?;
|
||||
println!("Verifier circuit data imported from: {}", circuit_path);
|
||||
|
||||
// duplicate the proof to get k proofs
|
||||
// this is just for testing - in real scenario we would need to load k proofs
|
||||
let proofs: Vec<ProofWithPublicInputs<F, C, D>> = (0..T).map(|_i| proof_with_pi.clone()).collect();
|
||||
|
||||
let start_time = Instant::now();
|
||||
let mut tree = TreeRecursion::<F,D,C,HF, N, T>::build_with_standard_config(verifier_data.clone()).unwrap();
|
||||
println!("build tree time: {:?}", start_time.elapsed());
|
||||
|
||||
let start_time = Instant::now();
|
||||
let tree_proof = if !compress {
|
||||
tree.prove_tree(&proofs)?
|
||||
} else { tree.prove_tree_and_compress(&proofs)? };
|
||||
println!("aggregate time: {:?}", start_time.elapsed());
|
||||
|
||||
//export the proof to json file
|
||||
let dis_path = if !compress {TREE_CIRC_BASE_PATH} else { COMPRESS_CIRC_BASE_PATH };
|
||||
export_proof_with_pi(&tree_proof, dis_path)?;
|
||||
println!("Tree proof written to: {}", dis_path);
|
||||
|
||||
let node_ver_data = tree.get_node_verifier_data();
|
||||
export_verifier_circuit_data(node_ver_data, TREE_CIRC_BASE_PATH)?;
|
||||
|
||||
let compression_ver_data = tree.get_compression_verifier_data();
|
||||
export_verifier_circuit_data(compression_ver_data, COMPRESS_CIRC_BASE_PATH)?;
|
||||
|
||||
let inner_pi: Vec<Vec<F>> = proofs.iter().map(|p| p.public_inputs.clone()).collect();
|
||||
|
||||
assert!(tree.verify_proof_and_public_input(tree_proof,inner_pi.clone(),compress).is_ok());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -1,59 +0,0 @@
|
||||
use std::env;
|
||||
use anyhow::Result;
|
||||
use plonky2::plonk::proof::ProofWithPublicInputs;
|
||||
use codex_plonky2_circuits::recursion::tree::TreeRecursion;
|
||||
use proof_input::params::{D, C, F, HF};
|
||||
use proof_input::serialization::file_paths::{PROOF_JSON, TREE_PROOF_JSON, VERIFIER_CIRC_DATA_JSON};
|
||||
use proof_input::serialization::json::{export_tree_proof_with_pi, import_proof_with_pi, import_verifier_circuit_data};
|
||||
|
||||
fn main() -> Result<()> {
|
||||
// load the parameters from environment variables
|
||||
const N: usize = 2;
|
||||
|
||||
// take k = "number of proofs" from env arguments; default to 4 if not there
|
||||
let args: Vec<String> = env::args().collect();
|
||||
let t: usize = args.get(1).and_then(|s| s.parse().ok()).unwrap_or(4);
|
||||
|
||||
match t {
|
||||
2 => run_tree::<N,2>()?,
|
||||
4 => run_tree::<N, 4>()?,
|
||||
8 => run_tree::<N, 8>()?,
|
||||
16 => run_tree::<N, 16>()?,
|
||||
32 => run_tree::<N, 32>()?,
|
||||
64 => run_tree::<N, 64>()?,
|
||||
128 => run_tree::<N, 128>()?,
|
||||
256 => run_tree::<N, 256>()?,
|
||||
512 => run_tree::<N, 512>()?,
|
||||
1024 => run_tree::<N, 1024>()?,
|
||||
other => panic!("unsupported proof count: {}", other),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn run_tree<const N: usize, const T: usize>() -> Result<()> {
|
||||
// Read the proof
|
||||
let proof_with_pi = import_proof_with_pi::<F,C,D>()?;
|
||||
println!("Proof with public input imported from: {}", PROOF_JSON);
|
||||
|
||||
// read the circuit data
|
||||
let verifier_data = import_verifier_circuit_data::<F,C,D>()?;
|
||||
println!("Verifier circuit data imported from: {}", VERIFIER_CIRC_DATA_JSON);
|
||||
|
||||
// duplicate the proof to get k proofs
|
||||
// this is just for testing - in real scenario we would need to load k proofs
|
||||
let proofs: Vec<ProofWithPublicInputs<F, C, D>> = (0..T).map(|_i| proof_with_pi.clone()).collect();
|
||||
|
||||
let mut tree = TreeRecursion::<F,D,C,HF, N, T>::build_with_standard_config(verifier_data.clone()).unwrap();
|
||||
|
||||
let tree_proof = tree.prove_tree_and_compress(&proofs).unwrap();
|
||||
//export the proof to json file
|
||||
export_tree_proof_with_pi(&tree_proof)?;
|
||||
println!("Tree proof written to: {}", TREE_PROOF_JSON);
|
||||
|
||||
let inner_pi: Vec<Vec<F>> = proofs.iter().map(|p| p.public_inputs.clone()).collect();
|
||||
|
||||
assert!(tree.verify_proof_and_public_input(tree_proof,inner_pi.clone(),false).is_ok());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -1,23 +0,0 @@
|
||||
use std::time::Instant;
|
||||
use anyhow::Result;
|
||||
use proof_input::params::{D, C, F};
|
||||
use proof_input::serialization::file_paths::{PROOF_JSON, VERIFIER_CIRC_DATA_JSON};
|
||||
use proof_input::serialization::json::{import_proof_with_pi, import_verifier_circuit_data};
|
||||
|
||||
fn main() -> Result<()> {
|
||||
|
||||
// read the circuit data
|
||||
let verifier_data = import_verifier_circuit_data::<F,C,D>()?;
|
||||
println!("Verifier circuit data imported from: {}", VERIFIER_CIRC_DATA_JSON);
|
||||
|
||||
// Read the proof
|
||||
let proof_with_pi = import_proof_with_pi::<F,C,D>()?;
|
||||
println!("Proof with public input imported from: {}", PROOF_JSON);
|
||||
|
||||
// verify the proof
|
||||
let start_time = Instant::now();
|
||||
assert!(verifier_data.verify(proof_with_pi).is_ok(), "proof is NOT VALID");
|
||||
println!("Verifying time: {:?}", start_time.elapsed());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
51
workflow/src/bn254_wrap.rs
Executable file
51
workflow/src/bn254_wrap.rs
Executable file
@ -0,0 +1,51 @@
|
||||
use std::time::Instant;
|
||||
use anyhow::Result;
|
||||
use codex_plonky2_circuits::bn254_wrapper::config::PoseidonBN254GoldilocksConfig;
|
||||
use codex_plonky2_circuits::bn254_wrapper::wrap::{WrapCircuit, WrapInput, WrappedOutput};
|
||||
use codex_plonky2_circuits::circuit_helper::Plonky2Circuit;
|
||||
use codex_plonky2_circuits::serialization::{export_verifier_circuit_data, import_proof_with_pi, import_verifier_circuit_data};
|
||||
use proof_input::params::{D, C, F};
|
||||
use crate::file_paths::WRAP_CIRC_BASE_PATH;
|
||||
|
||||
type OuterParameters = PoseidonBN254GoldilocksConfig;
|
||||
|
||||
pub fn run(circuit_path: &str) -> Result<()> {
|
||||
|
||||
// Read the proof
|
||||
let proof_with_pi = import_proof_with_pi::<F,C,D,_>(&circuit_path)?;
|
||||
println!("Proof with public input imported from: {}", &circuit_path);
|
||||
|
||||
// read the circuit data
|
||||
let verifier_data = import_verifier_circuit_data::<F,C,D,_>(&circuit_path)?;
|
||||
println!("Verifier circuit data imported from: {}", &circuit_path);
|
||||
|
||||
let wrapper = WrapCircuit::<F,D,C,OuterParameters>::new(verifier_data);
|
||||
let (targ, data) = wrapper.build_with_standard_config().unwrap();
|
||||
println!(
|
||||
"wrapper circuit degree: {}",
|
||||
data.common.degree_bits()
|
||||
);
|
||||
let verifier_data = data.verifier_data();
|
||||
let prover_data = data.prover_data();
|
||||
let wrap_input = WrapInput{
|
||||
inner_proof: proof_with_pi,
|
||||
};
|
||||
let start_time = Instant::now();
|
||||
let proof = wrapper.prove(&targ, &wrap_input,&prover_data).unwrap();
|
||||
println!("Wrap time: {:?}", start_time.elapsed());
|
||||
|
||||
let wrap_circ = WrappedOutput::<F, OuterParameters,D>{
|
||||
proof,
|
||||
common_data: verifier_data.common.clone(),
|
||||
verifier_data: verifier_data.verifier_only.clone(),
|
||||
};
|
||||
|
||||
// export the circuit data
|
||||
export_verifier_circuit_data::<F,OuterParameters,D, _>(verifier_data, WRAP_CIRC_BASE_PATH)?;
|
||||
println!("all data written to {}", WRAP_CIRC_BASE_PATH);
|
||||
|
||||
wrap_circ.save(WRAP_CIRC_BASE_PATH).unwrap();
|
||||
println!("Saved wrapped circuit");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
12
workflow/src/bin/build_circ.rs → workflow/src/build_circ.rs
Normal file → Executable file
12
workflow/src/bin/build_circ.rs → workflow/src/build_circ.rs
Normal file → Executable file
@ -2,12 +2,12 @@ use std::time::Instant;
|
||||
use anyhow::Result;
|
||||
use codex_plonky2_circuits::circuit_helper::Plonky2Circuit;
|
||||
use codex_plonky2_circuits::circuits::sample_cells::SampleCircuit;
|
||||
use proof_input::serialization::json::export_circuit_data;
|
||||
use codex_plonky2_circuits::serialization::export_circuit_data;
|
||||
use proof_input::params::Params;
|
||||
use proof_input::params::{D, C, F,HF};
|
||||
use proof_input::serialization::file_paths::{PROVER_CIRC_DATA_JSON, TARGETS_JSON, VERIFIER_CIRC_DATA_JSON};
|
||||
use crate::file_paths::SAMPLING_CIRC_BASE_PATH;
|
||||
|
||||
fn main() -> Result<()> {
|
||||
pub fn run() -> Result<()> {
|
||||
// Load the parameters from environment variables
|
||||
let params = Params::from_env()?;
|
||||
|
||||
@ -20,10 +20,8 @@ fn main() -> Result<()> {
|
||||
println!("Circuit size (degree bits): {:?}", data.common.degree_bits());
|
||||
|
||||
// export the circuit data
|
||||
export_circuit_data::<F,C,D>(data, &targets)?;
|
||||
println!("Prover Data written to {}", PROVER_CIRC_DATA_JSON);
|
||||
println!("Verifier Data written to {}", VERIFIER_CIRC_DATA_JSON);
|
||||
println!("Targets written to {}", TARGETS_JSON);
|
||||
export_circuit_data::<F,C,D, _>(data, &targets, SAMPLING_CIRC_BASE_PATH)?;
|
||||
println!("all data written to {}", SAMPLING_CIRC_BASE_PATH);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
4
workflow/src/file_paths.rs
Executable file
4
workflow/src/file_paths.rs
Executable file
@ -0,0 +1,4 @@
|
||||
pub(crate) const SAMPLING_CIRC_BASE_PATH: &str = "../output/sampling_circuit/";
|
||||
pub(crate) const TREE_CIRC_BASE_PATH: &str = "../output/tree/";
|
||||
pub(crate) const COMPRESS_CIRC_BASE_PATH: &str = "../output/compression/";
|
||||
pub(crate) const WRAP_CIRC_BASE_PATH: &str = "../output/wrap/";
|
||||
8
workflow/src/bin/gen_input.rs → workflow/src/gen_input.rs
Normal file → Executable file
8
workflow/src/bin/gen_input.rs → workflow/src/gen_input.rs
Normal file → Executable file
@ -4,9 +4,9 @@ use proof_input::serialization::circuit_input::export_circ_input_to_json;
|
||||
use proof_input::gen_input::gen_testing_circuit_input;
|
||||
use proof_input::params::Params;
|
||||
use proof_input::params::{D, F};
|
||||
use proof_input::serialization::file_paths::CIRC_INPUT_JSON;
|
||||
use crate::file_paths::SAMPLING_CIRC_BASE_PATH;
|
||||
|
||||
fn main() -> Result<()> {
|
||||
pub fn run() -> Result<()> {
|
||||
// Load the parameters from environment variables
|
||||
let params = Params::from_env()?;
|
||||
|
||||
@ -16,8 +16,8 @@ fn main() -> Result<()> {
|
||||
println!("Generating input time: {:?}", start_time.elapsed());
|
||||
|
||||
// export circuit parameters to json file
|
||||
export_circ_input_to_json(circ_input)?;
|
||||
println!("proof input written to {}", CIRC_INPUT_JSON);
|
||||
export_circ_input_to_json(circ_input, SAMPLING_CIRC_BASE_PATH)?;
|
||||
println!("proof input written to {}", SAMPLING_CIRC_BASE_PATH);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
71
workflow/src/main.rs
Executable file
71
workflow/src/main.rs
Executable file
@ -0,0 +1,71 @@
|
||||
use anyhow::Result;
|
||||
use clap::{Parser, Subcommand};
|
||||
use codex_plonky2_circuits::bn254_wrapper::config::PoseidonBN254GoldilocksConfig;
|
||||
use crate::file_paths::{COMPRESS_CIRC_BASE_PATH, SAMPLING_CIRC_BASE_PATH, TREE_CIRC_BASE_PATH, WRAP_CIRC_BASE_PATH};
|
||||
use proof_input::params::C;
|
||||
type OuterParameters = PoseidonBN254GoldilocksConfig;
|
||||
|
||||
mod build_circ;
|
||||
mod prove;
|
||||
mod verify;
|
||||
mod gen_input;
|
||||
mod aggregate;
|
||||
mod bn254_wrap;
|
||||
mod file_paths;
|
||||
|
||||
/// Codex_zk_cli: unified CLI for all zk operations
|
||||
#[derive(Parser)]
|
||||
#[command(name = "codex_zk_cli", version, about = "gen_input, build, prove, aggregate, wrap, verify")]
|
||||
struct Cli {
|
||||
#[command(subcommand)]
|
||||
command: Commands,
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
enum Commands {
|
||||
/// Generate witness inputs
|
||||
GenInput,
|
||||
/// build the circuit
|
||||
Build,
|
||||
/// Run the prover
|
||||
Prove,
|
||||
/// Aggregate proofs
|
||||
Aggregate,
|
||||
/// Aggregate and compress proofs
|
||||
AggregateAndCompress,
|
||||
/// Wrap sampling proof
|
||||
Wrap,
|
||||
/// Wrap aggregated tree proof
|
||||
WrapTree,
|
||||
/// Wrap compressed proof
|
||||
WrapCompress,
|
||||
/// Verify a sampling proof
|
||||
Verify,
|
||||
/// Verify a tree proof
|
||||
VerifyTree,
|
||||
/// Verify a compressed tree proof
|
||||
VerifyCompressed,
|
||||
/// Verify a wrapped proof
|
||||
VerifyWrapped,
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let cli = Cli::parse();
|
||||
|
||||
match cli.command {
|
||||
Commands::GenInput => gen_input::run()?,
|
||||
Commands::Build => build_circ::run()?,
|
||||
Commands::Prove => prove::run()?,
|
||||
Commands::Aggregate => aggregate::run(false)?,
|
||||
Commands::AggregateAndCompress => aggregate::run(true)?,
|
||||
Commands::Wrap => bn254_wrap::run(SAMPLING_CIRC_BASE_PATH)?,
|
||||
Commands::WrapTree => bn254_wrap::run(TREE_CIRC_BASE_PATH)?,
|
||||
Commands::WrapCompress => bn254_wrap::run(COMPRESS_CIRC_BASE_PATH)?,
|
||||
Commands::Verify => verify::run::<C>(SAMPLING_CIRC_BASE_PATH)?,
|
||||
Commands::VerifyTree => verify::run::<C>(TREE_CIRC_BASE_PATH)?,
|
||||
Commands::VerifyCompressed => verify::run::<C>(COMPRESS_CIRC_BASE_PATH)?,
|
||||
Commands::VerifyWrapped => verify::run::<OuterParameters>(WRAP_CIRC_BASE_PATH)?,
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
25
workflow/src/bin/prove.rs → workflow/src/prove.rs
Normal file → Executable file
25
workflow/src/bin/prove.rs → workflow/src/prove.rs
Normal file → Executable file
@ -1,28 +1,27 @@
|
||||
use anyhow::Result;
|
||||
use std::time::Instant;
|
||||
use codex_plonky2_circuits::circuit_helper::Plonky2Circuit;
|
||||
use proof_input::serialization::circuit_input::import_circ_input_from_json;
|
||||
use proof_input::serialization::circuit_input::{import_circ_input_from_json};
|
||||
use codex_plonky2_circuits::circuits::sample_cells::{SampleCircuit, SampleCircuitInput, SampleTargets};
|
||||
use codex_plonky2_circuits::circuits::params::CircuitParams;
|
||||
use proof_input::params::{D, C, F, HF};
|
||||
use proof_input::serialization::file_paths::{CIRC_INPUT_JSON, PROVER_CIRC_DATA_JSON, TARGETS_JSON, TREE_PROOF_JSON};
|
||||
use proof_input::serialization::json::{export_proof_with_pi, import_prover_circuit_data, import_targets};
|
||||
|
||||
fn main() -> Result<()> {
|
||||
use codex_plonky2_circuits::serialization::{export_proof_with_pi, import_prover_circuit_data, import_targets};
|
||||
use crate::file_paths::SAMPLING_CIRC_BASE_PATH;
|
||||
pub fn run() -> Result<()> {
|
||||
// Load the parameters from environment variables
|
||||
let circuit_params = CircuitParams::from_env()?;
|
||||
|
||||
// Read the witness from input.json
|
||||
let circ_input: SampleCircuitInput<F, D> = import_circ_input_from_json()?;
|
||||
println!("Witness imported from: {}", CIRC_INPUT_JSON);
|
||||
let circ_input: SampleCircuitInput<F, D> = import_circ_input_from_json(SAMPLING_CIRC_BASE_PATH)?;
|
||||
println!("Witness imported from: {}", SAMPLING_CIRC_BASE_PATH);
|
||||
|
||||
// read the targets
|
||||
let circ_targets: SampleTargets = import_targets()?;
|
||||
println!("circuit targets imported from: {}", TARGETS_JSON);
|
||||
let circ_targets: SampleTargets = import_targets(SAMPLING_CIRC_BASE_PATH)?;
|
||||
println!("circuit targets imported from: {}", SAMPLING_CIRC_BASE_PATH);
|
||||
|
||||
// read the circuit data
|
||||
let prover_data = import_prover_circuit_data::<F,C,D>()?;
|
||||
println!("Prover circuit data imported from: {}", PROVER_CIRC_DATA_JSON);
|
||||
let prover_data = import_prover_circuit_data::<F,C,D,_>(SAMPLING_CIRC_BASE_PATH)?;
|
||||
println!("Prover circuit data imported from: {}", SAMPLING_CIRC_BASE_PATH);
|
||||
println!("Circuit size (degree bits): {:?}", prover_data.common.degree_bits());
|
||||
|
||||
// Prove the circuit with the assigned witness
|
||||
@ -32,8 +31,8 @@ fn main() -> Result<()> {
|
||||
println!("Proving time: {:?}", start_time.elapsed());
|
||||
|
||||
//export the proof to json file
|
||||
export_proof_with_pi(&proof_with_pis)?;
|
||||
println!("Tree proof written to: {}", TREE_PROOF_JSON);
|
||||
export_proof_with_pi(&proof_with_pis, SAMPLING_CIRC_BASE_PATH)?;
|
||||
println!("proof written to: {}", SAMPLING_CIRC_BASE_PATH);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
27
workflow/src/verify.rs
Executable file
27
workflow/src/verify.rs
Executable file
@ -0,0 +1,27 @@
|
||||
use std::time::Instant;
|
||||
use anyhow::Result;
|
||||
use plonky2::plonk::config::GenericConfig;
|
||||
use serde::Serialize;
|
||||
use proof_input::params::{D, F};
|
||||
use codex_plonky2_circuits::serialization::{import_proof_with_pi, import_verifier_circuit_data};
|
||||
|
||||
pub fn run<
|
||||
// F: RichField + Extendable<D> + Poseidon2 + Serialize,
|
||||
C: GenericConfig<D, F = F> + Serialize,
|
||||
>(circuit_path: &str) -> Result<()> {
|
||||
|
||||
// read the circuit data
|
||||
let verifier_data = import_verifier_circuit_data::<F,C,D,_>(circuit_path)?;
|
||||
println!("Verifier circuit data imported from: {}", circuit_path);
|
||||
|
||||
// Read the proof
|
||||
let proof_with_pi = import_proof_with_pi::<F,C,D,_>(circuit_path)?;
|
||||
println!("Proof with public input imported from: {}", circuit_path);
|
||||
|
||||
// verify the proof
|
||||
let start_time = Instant::now();
|
||||
assert!(verifier_data.verify(proof_with_pi).is_ok(), "proof is NOT VALID");
|
||||
println!("Verifying time: {:?}", start_time.elapsed());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user