feat: serialization compatibility for pre-generated SRS (#120)

This commit is contained in:
dante
2023-02-26 02:33:07 +00:00
committed by GitHub
parent 9594f09d1d
commit 898696167a
7 changed files with 296 additions and 143 deletions

View File

@@ -2,9 +2,9 @@ name: Rust
on:
push:
branches: [ "main" ]
branches: ["main"]
pull_request:
branches: [ "main" ]
branches: ["main"]
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
@@ -15,180 +15,169 @@ env:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions-rs/toolchain@v1
with:
- uses: actions/checkout@v3
- uses: actions-rs/toolchain@v1
with:
toolchain: nightly
override: true
components: rustfmt, clippy
- name: Build
run: cargo build --verbose
benchmarks:
components: rustfmt, clippy
- name: Build
run: cargo build --verbose
benchmarks:
runs-on: ubuntu-latest-16-cores
steps:
- uses: actions/checkout@v3
- uses: actions-rs/toolchain@v1
with:
- uses: actions/checkout@v3
- uses: actions-rs/toolchain@v1
with:
toolchain: nightly
override: true
components: rustfmt, clippy
- name: Bench
run: cargo bench --verbose
components: rustfmt, clippy
- name: Bench
run: cargo bench --verbose
docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions-rs/toolchain@v1
with:
- uses: actions/checkout@v3
- uses: actions-rs/toolchain@v1
with:
toolchain: nightly
override: true
components: rustfmt, clippy
- name: Docs
run: cargo doc --verbose
components: rustfmt, clippy
- name: Docs
run: cargo doc --verbose
library-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions-rs/toolchain@v1
with:
- uses: actions/checkout@v3
- uses: actions-rs/toolchain@v1
with:
toolchain: nightly
override: true
components: rustfmt, clippy
- name: Doc tests
run: cargo test --doc --verbose
- name: Library tests
run: cargo test --lib --verbose
components: rustfmt, clippy
- name: Doc tests
run: cargo test --doc --verbose
- name: Library tests
run: cargo test --lib --verbose
mock-proving-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
- uses: actions/checkout@v3
with:
submodules: recursive
- uses: actions-rs/toolchain@v1
with:
toolchain: nightly
override: true
components: rustfmt, clippy
- name: Mock proving tests (public outputs)
run: cargo test --release --verbose tests::mock_public_outputs_ -- --test-threads 16
- name: Mock proving tests (public inputs)
run: cargo test --release --verbose tests::mock_public_inputs_ -- --test-threads 16
- name: Mock proving tests (public params)
run: cargo test --release --verbose tests::mock_public_params_ -- --test-threads 16
prove-and-verify-evm-tests:
runs-on: ubuntu-latest-16-cores
steps:
- uses: actions/checkout@v3
with:
submodules: recursive
- uses: actions-rs/toolchain@v1
with:
- uses: actions-rs/toolchain@v1
with:
toolchain: nightly
override: true
components: rustfmt, clippy
- name: Install solc
run: (hash svm 2>/dev/null || cargo install svm-rs) && svm install 0.8.17 && solc --version
- name: Install Anvil
run: cargo install --git https://github.com/foundry-rs/foundry --profile local --locked foundry-cli anvil
- name: KZG prove and verify tests (EVM)
run: cargo test --release --verbose tests_evm -- --test-threads 4
- name: Mock proving tests (public outputs)
run: cargo test --release --verbose tests::mock_public_outputs_ -- --test-threads 16
- name: Mock proving tests (public inputs)
run: cargo test --release --verbose tests::mock_public_inputs_ -- --test-threads 16
- name: Mock proving tests (public params)
run: cargo test --release --verbose tests::mock_public_params_ -- --test-threads 16
prove-and-verify-evm-tests:
runs-on: ubuntu-latest-16-cores
steps:
- uses: actions/checkout@v3
with:
submodules: recursive
- uses: actions-rs/toolchain@v1
with:
toolchain: nightly
override: true
components: rustfmt, clippy
- name: Install solc
run: (hash svm 2>/dev/null || cargo install svm-rs) && svm install 0.8.17 && solc --version
- name: Install Anvil
run: cargo install --git https://github.com/foundry-rs/foundry --profile local --locked foundry-cli anvil
- name: KZG prove and verify tests (EVM)
run: cargo test --release --verbose tests_evm -- --test-threads 4
prove-and-verify-tests:
runs-on: ubuntu-latest-16-cores
steps:
- uses: actions/checkout@v3
with:
- uses: actions/checkout@v3
with:
submodules: recursive
- uses: actions-rs/toolchain@v1
with:
- uses: actions-rs/toolchain@v1
with:
toolchain: nightly
override: true
components: rustfmt, clippy
- name: KZG prove and verify tests
run: cargo test --release --verbose tests::kzg_prove_and_verify_ -- --test-threads 4
- name: KZG prove and verify tests
run: cargo test --release --verbose tests::kzg_prove_and_verify_ -- --test-threads 4
prove-and-verify-aggr-tests:
runs-on: self-hosted
steps:
- uses: actions/checkout@v3
with:
- uses: actions/checkout@v3
with:
submodules: recursive
- uses: actions-rs/toolchain@v1
with:
- uses: actions-rs/toolchain@v1
with:
toolchain: nightly
override: true
components: rustfmt, clippy
- name: KZG prove and verify aggr tests
run: cargo test --release --verbose tests_aggr::kzg_aggr_prove_and_verify_ -- --test-threads 2
- name: KZG prove and verify aggr tests
run: cargo test --release --verbose tests_aggr::kzg_aggr_prove_and_verify_ -- --test-threads 4
prove-and-verify-evm-aggr-tests:
runs-on: self-hosted
steps:
- uses: actions/checkout@v3
with:
- uses: actions/checkout@v3
with:
submodules: recursive
- uses: actions-rs/toolchain@v1
with:
- uses: actions-rs/toolchain@v1
with:
toolchain: nightly
override: true
components: rustfmt, clippy
- name: Install solc
run: (hash svm 2>/dev/null || cargo install svm-rs) && svm install 0.8.17 && solc --version
- name: KZG prove and verify aggr tests
run: cargo test --release --verbose tests_evm::kzg_evm_aggr_prove_and_verify_ -- --test-threads 2 --include-ignored
- name: Install solc
run: (hash svm 2>/dev/null || cargo install svm-rs) && svm install 0.8.17 && solc --version
- name: KZG prove and verify aggr tests
run: cargo test --release --verbose tests_evm::kzg_evm_aggr_prove_and_verify_ -- --test-threads 4 --include-ignored
examples:
runs-on: self-hosted
steps:
- uses: actions/checkout@v3
- uses: actions-rs/toolchain@v1
with:
- uses: actions/checkout@v3
- uses: actions-rs/toolchain@v1
with:
toolchain: nightly
override: true
components: rustfmt, clippy
- name: Download MNIST
run: sh data.sh
- name: Examples
run: cargo test --release tests_examples
- name: Download MNIST
run: sh data.sh
- name: Examples
run: cargo test --release tests_examples
neg-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
- uses: actions/checkout@v3
with:
submodules: recursive
- uses: actions-rs/toolchain@v1
with:
- uses: actions-rs/toolchain@v1
with:
toolchain: nightly
override: true
components: rustfmt, clippy
- name: Mock proving tests (should fail)
run: cargo test neg_tests::neg_examples_
- name: Mock proving tests (should fail)
run: cargo test neg_tests::neg_examples_

95
Cargo.lock generated
View File

@@ -1761,11 +1761,13 @@ dependencies = [
"mnist",
"plotters",
"rand",
"reqwest",
"seq-macro",
"serde",
"serde_json",
"snark-verifier",
"tabled",
"tempfile",
"tensorflow",
"test-case",
"thiserror",
@@ -2357,6 +2359,19 @@ dependencies = [
"tokio-rustls",
]
[[package]]
name = "hyper-tls"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
dependencies = [
"bytes",
"hyper",
"native-tls",
"tokio",
"tokio-native-tls",
]
[[package]]
name = "iana-time-zone"
version = "0.1.53"
@@ -2889,6 +2904,24 @@ dependencies = [
"byteorder",
]
[[package]]
name = "native-tls"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e"
dependencies = [
"lazy_static",
"libc",
"log",
"openssl",
"openssl-probe",
"openssl-sys",
"schannel",
"security-framework",
"security-framework-sys",
"tempfile",
]
[[package]]
name = "ndarray"
version = "0.15.6"
@@ -3082,6 +3115,32 @@ dependencies = [
"syn",
]
[[package]]
name = "openssl"
version = "0.10.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b102428fd03bc5edf97f62620f7298614c45cedf287c271e7ed450bbaf83f2e1"
dependencies = [
"bitflags",
"cfg-if",
"foreign-types",
"libc",
"once_cell",
"openssl-macros",
"openssl-sys",
]
[[package]]
name = "openssl-macros"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "openssl-probe"
version = "0.1.5"
@@ -3774,10 +3833,12 @@ dependencies = [
"http-body",
"hyper",
"hyper-rustls",
"hyper-tls",
"ipnet",
"js-sys",
"log",
"mime",
"native-tls",
"once_cell",
"percent-encoding",
"pin-project-lite",
@@ -3787,6 +3848,7 @@ dependencies = [
"serde_json",
"serde_urlencoded",
"tokio",
"tokio-native-tls",
"tokio-rustls",
"tower-service",
"url",
@@ -4086,6 +4148,29 @@ dependencies = [
"cc",
]
[[package]]
name = "security-framework"
version = "2.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a332be01508d814fed64bf28f798a146d73792121129962fdf335bb3c49a4254"
dependencies = [
"bitflags",
"core-foundation",
"core-foundation-sys",
"libc",
"security-framework-sys",
]
[[package]]
name = "security-framework-sys"
version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "31c9bb296072e961fcbd8853511dd39c2d8be2deb1e17c6860b1d30732b323b4"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "semver"
version = "0.11.0"
@@ -4781,6 +4866,16 @@ dependencies = [
"syn",
]
[[package]]
name = "tokio-native-tls"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
dependencies = [
"native-tls",
"tokio",
]
[[package]]
name = "tokio-rustls"
version = "0.23.4"

View File

@@ -33,6 +33,8 @@ tokio = { version = "1.22.0", features = ["macros"] }
[dev-dependencies]
criterion = {version = "0.3", features = ["html_reports"]}
tempfile = "3.3.0"
reqwest = "0.11.14"
lazy_static = "1.4.0"
mnist = "0.5"
seq-macro = "0.3.1"

View File

@@ -136,6 +136,10 @@ ezkl -K=17 --bits=16 verify-evm --pfsys=kzg --proof-path aggr_1l_relu.pf --deplo
Also note that this may require a local [solc](https://docs.soliditylang.org/en/v0.8.17/installing-solidity.html) installation, and that aggregated proof verification in Solidity is not currently supported.
#### using pre-generated SRS
Note that you can use pre-generated KZG SRS. These SRS can be converted to a format that is ingestable by the `pse/halo2` prover ezkl uses by leveraging [han0110/halo2-kzg-srs](https://github.com/han0110/halo2-kzg-srs). This repo also contains pre-converted SRS from large projects such as Hermez and the [perpetual powers of tau repo](https://github.com/privacy-scaling-explorations/perpetualpowersoftau). Simply download the pre-converted file locally and point `--params-path` to the file !
### general usage 🔧

View File

@@ -1,21 +1,21 @@
use crate::pfsys::evm::EvmVerificationError;
use crate::pfsys::Snark;
use ethers::contract::abigen;
use ethers::contract::ContractFactory;
use ethers::core::k256::ecdsa::SigningKey;
use ethers::middleware::SignerMiddleware;
use ethers::providers::{Http, Provider};
use ethers::signers::Signer;
use ethers::types::U256;
use ethers::utils::AnvilInstance;
use ethers::{
prelude::{LocalWallet, Wallet},
utils::Anvil,
};
use crate::pfsys::evm::EvmVerificationError;
use crate::pfsys::Snark;
use std::{convert::TryFrom, sync::Arc, time::Duration};
use ethers_solc::Solc;
use ethers::contract::ContractFactory;
use ethers::contract::abigen;
use ethers::types::U256;
use halo2curves::bn256::{Fr, G1Affine};
use halo2curves::group::ff::PrimeField;
use std::{convert::TryFrom, sync::Arc, time::Duration};
/// A local ethers-rs based client
pub type EthersClient = Arc<SignerMiddleware<Provider<Http>, Wallet<SigningKey>>>;
@@ -50,8 +50,10 @@ pub async fn verify_proof_via_solidity(
let (anvil, client) = setup_eth_backend().await;
let compiled = Solc::default().compile_source(sol_code_path).unwrap();
let (abi, bytecode, _runtime_bytecode) =
compiled.find("Verifier").expect("could not find contract").into_parts_or_default();
let (abi, bytecode, _runtime_bytecode) = compiled
.find("Verifier")
.expect("could not find contract")
.into_parts_or_default();
let factory = ContractFactory::new(abi, bytecode, client.clone());
let contract = factory.deploy(()).unwrap().send().await.unwrap();
let addr = contract.address();
@@ -66,14 +68,17 @@ pub async fn verify_proof_via_solidity(
public_inputs.push(u);
}
let result = contract.verify(
public_inputs,
ethers::types::Bytes::from(proof.proof.to_vec()),
).call().await;
let result = contract
.verify(
public_inputs,
ethers::types::Bytes::from(proof.proof.to_vec()),
)
.call()
.await;
if result.is_err() {
return Err(Box::new(EvmVerificationError::SolidityExecution));
}
}
let result = result.unwrap();
if !result {
return Err(Box::new(EvmVerificationError::InvalidProof));

View File

@@ -1,3 +1,4 @@
use super::eth::verify_proof_via_solidity;
use crate::commands::{Cli, Commands, ProofSystem, StrategyType, TranscriptType};
use crate::graph::{Model, ModelCircuit};
use crate::pfsys::evm::aggregation::{
@@ -5,10 +6,10 @@ use crate::pfsys::evm::aggregation::{
};
use crate::pfsys::evm::single::gen_evm_verifier;
use crate::pfsys::evm::{evm_verify, DeploymentCode};
use crate::pfsys::{create_keys, load_params, load_vk, Snark};
use crate::pfsys::{create_keys, load_params_kzg, load_vk, Snark};
use crate::pfsys::{
create_proof_circuit, gen_srs, prepare_data, prepare_model_circuit_and_public_input,
save_params, save_vk, verify_proof_circuit,
save_params_kzg, save_vk, verify_proof_circuit,
};
use halo2_proofs::dev::VerifyFailure;
use halo2_proofs::plonk::{Circuit, ProvingKey, VerifyingKey};
@@ -27,13 +28,12 @@ use log::{info, trace};
use snark_verifier::loader::native::NativeLoader;
use snark_verifier::system::halo2::transcript::evm::EvmTranscript;
use std::error::Error;
use std::time::Instant;
use tabled::Table;
use thiserror::Error;
use std::fs::File;
use std::io::Write;
use std::process::Command;
use super::eth::verify_proof_via_solidity;
use std::time::Instant;
use tabled::Table;
use thiserror::Error;
/// A wrapper for tensor related errors.
#[derive(Debug, Error)]
@@ -144,7 +144,7 @@ pub async fn run(cli: Cli) -> Result<(), Box<dyn Error>> {
}
ProofSystem::KZG => {
let params = gen_srs::<KZGCommitmentScheme<Bn256>>(cli.args.logrows);
save_params::<KZGCommitmentScheme<Bn256>>(&params_path, &params)?;
save_params_kzg(&params_path, &params)?;
}
},
Commands::Table { model: _ } => {
@@ -182,8 +182,7 @@ pub async fn run(cli: Cli) -> Result<(), Box<dyn Error>> {
let (_, public_inputs) =
prepare_model_circuit_and_public_input::<Fr>(&data, &cli)?;
let num_instance = public_inputs.iter().map(|x| x.len()).collect();
let mut params: ParamsKZG<Bn256> =
load_params::<KZGCommitmentScheme<Bn256>>(params_path.to_path_buf())?;
let mut params: ParamsKZG<Bn256> = load_params_kzg(params_path.to_path_buf())?;
params.downsize(cli.args.logrows);
let vk = load_vk::<KZGCommitmentScheme<Bn256>, Fr, ModelCircuit<Fr>>(
vk_path.to_path_buf(),
@@ -194,7 +193,6 @@ pub async fn run(cli: Cli) -> Result<(), Box<dyn Error>> {
deployment_code.save(deployment_code_path.as_ref().unwrap())?;
if sol_code_path.is_some() {
let mut f = File::create(sol_code_path.as_ref().unwrap()).unwrap();
let _ = f.write(yul_code.as_bytes());
@@ -221,12 +219,10 @@ pub async fn run(cli: Cli) -> Result<(), Box<dyn Error>> {
unimplemented!()
}
ProofSystem::KZG => {
let params: ParamsKZG<Bn256> =
load_params::<KZGCommitmentScheme<Bn256>>(params_path)?;
let params: ParamsKZG<Bn256> = load_params_kzg(params_path)?;
let agg_vk = load_vk::<KZGCommitmentScheme<Bn256>, Fr, AggregationCircuit>(
vk_path,
)?;
let agg_vk =
load_vk::<KZGCommitmentScheme<Bn256>, Fr, AggregationCircuit>(vk_path)?;
let deployment_code = gen_aggregation_evm_verifier(
&params,
@@ -257,8 +253,7 @@ pub async fn run(cli: Cli) -> Result<(), Box<dyn Error>> {
info!("proof with {}", pfsys);
let (circuit, public_inputs) =
prepare_model_circuit_and_public_input(&data, &cli)?;
let mut params: ParamsKZG<Bn256> =
load_params::<KZGCommitmentScheme<Bn256>>(params_path.to_path_buf())?;
let mut params: ParamsKZG<Bn256> = load_params_kzg(params_path.to_path_buf())?;
params.downsize(cli.args.logrows);
let pk = create_keys::<KZGCommitmentScheme<Bn256>, Fr, ModelCircuit<Fr>>(
&circuit, &params,
@@ -315,8 +310,7 @@ pub async fn run(cli: Cli) -> Result<(), Box<dyn Error>> {
unimplemented!()
}
ProofSystem::KZG => {
let params: ParamsKZG<Bn256> =
load_params::<KZGCommitmentScheme<Bn256>>(params_path.to_path_buf())?;
let params: ParamsKZG<Bn256> = load_params_kzg(params_path.to_path_buf())?;
let mut snarks = vec![];
for (proof_path, vk_path) in aggregation_snarks.iter().zip(aggregation_vk_paths)
@@ -373,8 +367,7 @@ pub async fn run(cli: Cli) -> Result<(), Box<dyn Error>> {
unimplemented!()
}
ProofSystem::KZG => {
let mut params: ParamsKZG<Bn256> =
load_params::<KZGCommitmentScheme<Bn256>>(params_path)?;
let mut params: ParamsKZG<Bn256> = load_params_kzg(params_path)?;
params.downsize(cli.args.logrows);
let proof = Snark::load::<KZGCommitmentScheme<Bn256>>(&proof_path, None, None)?;
@@ -403,8 +396,7 @@ pub async fn run(cli: Cli) -> Result<(), Box<dyn Error>> {
unimplemented!()
}
ProofSystem::KZG => {
let mut params: ParamsKZG<Bn256> =
load_params::<KZGCommitmentScheme<Bn256>>(params_path)?;
let mut params: ParamsKZG<Bn256> = load_params_kzg(params_path)?;
params.downsize(cli.args.logrows);
let proof = Snark::load::<KZGCommitmentScheme<Bn256>>(&proof_path, None, None)?;
@@ -430,10 +422,9 @@ pub async fn run(cli: Cli) -> Result<(), Box<dyn Error>> {
evm_verify(code, proof.clone())?;
if sol_code_path.is_some() {
let result = verify_proof_via_solidity(
proof,
sol_code_path.unwrap(),
).await.unwrap();
let result = verify_proof_via_solidity(proof, sol_code_path.unwrap())
.await
.unwrap();
info!("Solidity verification result: {}", result);

View File

@@ -13,8 +13,10 @@ use halo2_proofs::plonk::{
create_proof, keygen_pk, keygen_vk, verify_proof, Circuit, ProvingKey, VerifyingKey,
};
use halo2_proofs::poly::commitment::{CommitmentScheme, Params, ParamsProver, Prover, Verifier};
use halo2_proofs::poly::kzg::commitment::ParamsKZG;
use halo2_proofs::poly::VerificationStrategy;
use halo2_proofs::transcript::{EncodedChallenge, TranscriptReadBuffer, TranscriptWriterBuffer};
use halo2curves::bn256::Bn256;
use halo2curves::group::ff::PrimeField;
use halo2curves::serde::SerdeObject;
use halo2curves::CurveAffine;
@@ -431,6 +433,15 @@ pub fn load_params<Scheme: CommitmentScheme>(
Params::<'_, Scheme::Curve>::read(&mut reader).map_err(Box::<dyn Error>::from)
}
/// Loads the [ParamsKZG] at `path`.
pub fn load_params_kzg(path: PathBuf) -> Result<ParamsKZG<Bn256>, Box<dyn Error>> {
info!("loading params from {:?}", path);
let f = File::open(path).map_err(Box::<dyn Error>::from)?;
let mut reader = BufReader::new(f);
ParamsKZG::<Bn256>::read_custom(&mut reader, halo2_proofs::SerdeFormat::Processed)
.map_err(Box::<dyn Error>::from)
}
/// Saves a [ProvingKey] to `path`.
pub fn save_pk<Scheme: CommitmentScheme>(
path: &PathBuf,
@@ -477,3 +488,59 @@ pub fn save_params<Scheme: CommitmentScheme>(
writer.flush()?;
Ok(())
}
/// Saves [ParamsKZG] to `path`.
pub fn save_params_kzg(path: &PathBuf, params: &'_ ParamsKZG<Bn256>) -> Result<(), io::Error> {
info!("saving parameters 💾");
let f = File::create(path)?;
let mut writer = BufWriter::new(f);
params.write_custom(&mut writer, halo2_proofs::SerdeFormat::Processed)?;
writer.flush()?;
Ok(())
}
////////////////////////
#[cfg(test)]
mod tests {
use std::io::copy;
use super::*;
use halo2_proofs::poly::kzg::commitment::KZGCommitmentScheme;
use tempfile::Builder;
#[tokio::test]
async fn test_can_load_pre_generated_srs() {
let tmp_dir = Builder::new().prefix("example").tempdir().unwrap();
// lets hope this link never rots
let target = "https://trusted-setup-halo2kzg.s3.eu-central-1.amazonaws.com/hermez-1";
let response = reqwest::get(target).await.unwrap();
let fname = response
.url()
.path_segments()
.and_then(|segments| segments.last())
.and_then(|name| if name.is_empty() { None } else { Some(name) })
.unwrap_or("tmp.bin");
println!("file to download: '{}'", fname);
let fname = tmp_dir.path().join(fname);
println!("will be located under: '{:?}'", fname);
let mut dest = File::create(fname.clone()).unwrap();
let content = response.bytes().await.unwrap();
copy(&mut &content[..], &mut dest).unwrap();
let res = load_params_kzg(fname);
assert!(res.is_ok())
}
#[tokio::test]
async fn test_can_load_saved_srs() {
let tmp_dir = Builder::new().prefix("example").tempdir().unwrap();
let fname = tmp_dir.path().join("kzg.params");
let srs = gen_srs::<KZGCommitmentScheme<Bn256>>(1);
let res = save_params_kzg(&fname, &srs);
assert!(res.is_ok());
let res = load_params_kzg(fname);
assert!(res.is_ok())
}
}