use std::marker::PhantomData;
use anyhow::Context;
use midnight_circuits::hash::poseidon::PoseidonState;
use midnight_zk_stdlib::{self as zk};
use rand_chacha::ChaCha20Rng;
use rand_core::{CryptoRng, RngCore, SeedableRng};
use serde::{Deserialize, Serialize};
use crate::{
AggregateVerificationKeyForSnark, MembershipDigest, Parameters, SingleSignature, StmResult,
circuits::halo2::{circuit::StmCircuit, types::CircuitBase},
codec,
proof_system::halo2_snark::{
SnarkError, build_snark_message, circuit_verification_key::CircuitVerificationKey,
prover_input::SnarkProverInput,
},
};
use super::{SnarkClerk, SnarkSetup};
/// `SnarkProof` contains a proof generated by the certificate circuit represented as a vector of
/// bytes. It can be verified using verifier parameters derived from the srs, the circuit verification key
/// and the public inputs which are all public values
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SnarkProof<D: MembershipDigest> {
/// Raw proof bytes produced by the SNARK prover.
circuit_proof: Vec<u8>,
// The protocol parameters
// Note: this field is temporary and will be removed once the circuit setup is stable
params: Parameters,
/// The maximum Merkle tree depth
// Note: this field is temporary and will be removed once the circuit setup is stable
merkle_tree_depth: u32,
/// Circuit verification key
circuit_verification_key: CircuitVerificationKey,
/// Phantom data
#[serde(skip)]
phantom: PhantomData<D>,
}
impl<D: MembershipDigest> SnarkProof<D> {
/// Tries to generate a new SnarkProof given as input a vector of bytes representing a proof,
/// protocol parameters and a merkle tree depth
pub fn try_new(
circuit_proof: Vec<u8>,
params: Parameters,
merkle_tree_depth: u32,
) -> StmResult<Self> {
let snark_setup = SnarkSetup::try_new(¶ms, merkle_tree_depth)?;
Ok(Self {
circuit_proof,
circuit_verification_key: CircuitVerificationKey::new(snark_setup.verification_key),
params,
merkle_tree_depth,
phantom: PhantomData,
})
}
/// Verify a SNARK proof given a message, an aggregate verification key for snark
/// and a circuit verification key
///
/// For now, we generate a temporary SnarkSetup inside the function to get access
/// to the srs and generate the verifier parameters. This part will be removed once
/// the circuit is stable and the srs is stored and available.
///
/// This proof verifies that there exists a witness such that:
/// * each signatures in the witness is valid for the given message
/// * each signatures has a winning lottery index
/// * each leaf in the witness has a valid merkle path
/// * each lottery index is unique and fits the parameters
/// * enough lottery index are valid to meet the parameters requirements
///
pub fn verify(
&self,
message: &[u8],
aggregate_verification_key_for_snark: &AggregateVerificationKeyForSnark<D>,
) -> StmResult<()> {
let snark_setup = SnarkSetup::try_new(&self.params, self.merkle_tree_depth)?;
let merkle_root = &aggregate_verification_key_for_snark.get_merkle_tree_commitment().root;
let proof_message = build_snark_message(merkle_root, message)?;
let proof_instance = (proof_message[0].into(), proof_message[1].into());
let verify_result = zk::verify::<StmCircuit, PoseidonState<CircuitBase>>(
&snark_setup.srs.verifier_params(),
&self.circuit_verification_key.get_midnight_vk(),
&proof_instance,
None,
&self.circuit_proof,
);
verify_result.map_err(|_| SnarkError::VerifyProofFail.into())
}
/// Converts a SnarkProof to CBOR bytes with a version prefix.
pub fn to_bytes(&self) -> StmResult<Vec<u8>> {
codec::to_cbor_bytes(self)
}
/// Deserialise a proof from bytes.
///
/// Supports both the new versioned CBOR format and the legacy fixed-offset format.
pub fn from_bytes(bytes: &[u8]) -> StmResult<Self> {
codec::from_versioned_bytes(bytes, Self::from_bytes_legacy)
}
/// Deserialise a proof from the legacy fixed-offset byte format.
///
/// # Layout
/// * Parameters (24 bytes, big-endian m/k/phi_f)
/// * Merkle tree depth (u32, little-endian)
/// * Circuit proof length (u64, little-endian)
/// * Circuit proof bytes
/// * Circuit verification key bytes (remaining)
fn from_bytes_legacy(bytes: &[u8]) -> StmResult<Self> {
// Legacy Parameters format is exactly 24 bytes (m: u64 + k: u64 + phi_f: f64, big-endian).
let params =
Parameters::from_bytes(bytes.get(0..24).ok_or(SnarkError::SerializationError)?)?;
let merkle_tree_depth = u32::from_le_bytes(
bytes.get(24..28).ok_or(SnarkError::SerializationError)?.try_into()?,
);
let circuit_proof_length = u64::from_le_bytes(
bytes.get(28..36).ok_or(SnarkError::SerializationError)?.try_into()?,
) as usize;
let circuit_proof = bytes
.get(36..(circuit_proof_length + 36))
.ok_or(SnarkError::SerializationError)?
.to_vec();
let circuit_vk_bytes = bytes
.get((circuit_proof_length + 36)..)
.ok_or(SnarkError::SerializationError)?;
let circuit_verification_key = CircuitVerificationKey::from_bytes(circuit_vk_bytes)?;
Ok(Self {
circuit_proof,
params,
merkle_tree_depth,
circuit_verification_key,
phantom: PhantomData,
})
}
}
/// Holds the pre-computed SNARK setup and exposes proof generation.
///
/// The type parameter `R` selects the randomness source used during proof generation.
/// Use `try_new_non_deterministic` for production (`OsRng`) and `try_new_deterministic` for
/// reproducible tests.
// TODO: remove this allow dead_code directive when function is called or future_snark is activated
#[allow(dead_code)]
pub struct SnarkProver<R: RngCore + CryptoRng> {
setup: SnarkSetup,
rng: R,
}
// TODO: remove this allow dead_code directive when function is called or future_snark is activated
#[allow(dead_code)]
impl SnarkProver<rand_core::OsRng> {
/// Create a new prover with a non-deterministic randomness source (`OsRng`).
///
/// This is the constructor intended for production use.
pub fn try_new_non_deterministic(
parameters: &Parameters,
merkle_tree_depth: u32,
) -> StmResult<Self> {
Ok(Self {
setup: SnarkSetup::try_new(parameters, merkle_tree_depth)
.with_context(|| "Failed to initialize SNARK setup (SRS, circuit, keys)")?,
rng: rand_core::OsRng,
})
}
}
// TODO: remove this allow dead_code directive when function is called or future_snark is activated
#[allow(dead_code)]
impl SnarkProver<ChaCha20Rng> {
/// Create a new prover with a deterministic randomness source seeded from `seed`.
///
/// This constructor is intended for testing, where reproducible proof generation is needed.
pub fn try_new_deterministic(
parameters: &Parameters,
merkle_tree_depth: u32,
seed: [u8; 32],
) -> StmResult<Self> {
Ok(Self {
setup: SnarkSetup::try_new(parameters, merkle_tree_depth)
.with_context(|| "Failed to initialize SNARK setup (SRS, circuit, keys)")?,
rng: ChaCha20Rng::from_seed(seed),
})
}
}
// TODO: remove this allow dead_code directive when function is called or future_snark is activated
#[allow(dead_code)]
impl<R: RngCore + CryptoRng> SnarkProver<R> {
/// Aggregate a set of single signatures into a SNARK proof.
///
/// Prepares the prover input (public instance and per-index witness) from the collected
/// single signatures, then runs the SNARK prover.
///
/// Returns an error if fewer than `k` valid signatures are available or if proof generation fails.
pub fn aggregate_signatures<D: MembershipDigest>(
&mut self,
clerk: &SnarkClerk,
signatures: &[SingleSignature],
message: &[u8],
) -> StmResult<SnarkProof<D>> {
let snark_prover_input =
SnarkProverInput::prepare_prover_input::<D>(clerk, signatures, message)
.with_context(|| "Failed to prepare SNARK prover input")?;
let instance = snark_prover_input.get_instance();
let witness = snark_prover_input.into_witness();
let circuit_proof = zk::prove::<StmCircuit, PoseidonState<CircuitBase>>(
&self.setup.srs,
&self.setup.proving_key,
&self.setup.circuit,
&instance,
witness,
&mut self.rng,
)
.with_context(|| "SNARK proof generation failed")?;
Ok(SnarkProof {
circuit_proof,
circuit_verification_key: CircuitVerificationKey::new(
self.setup.verification_key.clone(),
),
params: clerk.parameters,
merkle_tree_depth: clerk
.closed_key_registration
.number_of_registered_parties()
.next_power_of_two()
.trailing_zeros(),
phantom: PhantomData,
})
}
}
#[cfg(feature = "future_snark")]
#[cfg(test)]
mod tests {
use rand_chacha::ChaCha20Rng;
use rand_core::{RngCore, SeedableRng};
use crate::{
Initializer, KeyRegistration, MithrilMembershipDigest, Signer, SingleSignature,
proof_system::{
SnarkClerk,
halo2_snark::{
SnarkSetup, circuit_verification_key::CircuitVerificationKey, proof::SnarkProof,
},
},
};
const BASE_CIRCUIT_DEGREE: u32 = 11;
// Compute the circuit degree from the protocol parameter `k`.
fn compute_circuit_degree(k: u64) -> u32 {
BASE_CIRCUIT_DEGREE + k.next_power_of_two().trailing_zeros()
}
use super::{Parameters, SnarkProver};
type D = MithrilMembershipDigest;
fn setup_signers_and_clerk(
params: Parameters,
nparties: usize,
rng: &mut ChaCha20Rng,
) -> (Vec<Signer<D>>, SnarkClerk) {
let mut key_reg = KeyRegistration::initialize();
let mut initializers = Vec::with_capacity(nparties);
for _ in 0..nparties {
let init = Initializer::new(params, 1, rng);
key_reg.register_by_entry(&init.clone().try_into().unwrap()).unwrap();
initializers.push(init);
}
let closed_reg = key_reg.close_registration(¶ms).unwrap();
let signers: Vec<Signer<D>> = initializers
.into_iter()
.map(|init| init.try_create_signer::<D>(&closed_reg).unwrap())
.collect();
let clerk = SnarkClerk::new_clerk_from_signer(&signers[0]);
(signers, clerk)
}
fn collect_signatures(signers: &[Signer<D>], message: &[u8]) -> Vec<SingleSignature> {
signers
.iter()
.filter_map(|signer| signer.create_single_signature(message).ok())
.collect()
}
fn create_prover(
params: Parameters,
number_of_signers: usize,
seed: [u8; 32],
) -> SnarkProver<ChaCha20Rng> {
let merkle_tree_depth = number_of_signers.next_power_of_two().trailing_zeros();
SnarkProver::try_new_deterministic(¶ms, merkle_tree_depth, seed).unwrap()
}
#[test]
fn produces_valid_snark_proof() {
let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
let params = Parameters {
m: 200,
k: 5,
phi_f: 0.8,
};
let nparties = 10;
let message = [1u8; 32];
let (signers, clerk) = setup_signers_and_clerk(params, nparties, &mut rng);
let signatures = collect_signatures(&signers, &message);
let mut prover = create_prover(
params,
clerk.closed_key_registration.number_of_registered_parties(),
[0u8; 32],
);
let result = prover.aggregate_signatures::<D>(&clerk, &signatures, &message);
assert!(
result.is_ok(),
"Expected proof creation to succeed, got: {result:?}"
);
let proof = result.unwrap();
assert!(
!proof.circuit_proof.is_empty(),
"Proof bytes should not be empty"
);
}
#[test]
fn fails_with_insufficient_signatures() {
let mut rng = ChaCha20Rng::from_seed([1u8; 32]);
let params = Parameters {
m: 20,
k: 5,
phi_f: 0.1,
};
let nparties = 4;
let message = [2u8; 32];
let (signers, clerk) = setup_signers_and_clerk(params, nparties, &mut rng);
let signatures = collect_signatures(&signers, &message);
let mut prover = create_prover(
params,
clerk.closed_key_registration.number_of_registered_parties(),
[1u8; 32],
);
let result = prover.aggregate_signatures::<D>(&clerk, &signatures, &message);
assert!(
result.is_err(),
"Expected failure due to insufficient signatures"
);
}
#[test]
fn fails_with_empty_signatures() {
let mut rng = ChaCha20Rng::from_seed([2u8; 32]);
let params = Parameters {
m: 200,
k: 5,
phi_f: 0.8,
};
let nparties = 5;
let (_, clerk) = setup_signers_and_clerk(params, nparties, &mut rng);
let mut prover = create_prover(
params,
clerk.closed_key_registration.number_of_registered_parties(),
[2u8; 32],
);
let result = prover.aggregate_signatures::<D>(&clerk, &[], &[3u8; 32]);
assert!(result.is_err(), "Expected failure with empty signatures");
}
#[test]
fn valid_proof_verifies() {
let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
let params = Parameters {
m: 200,
k: 3,
phi_f: 0.8,
};
let nparties = 10;
let message = [1u8; 32];
let (signers, clerk) = setup_signers_and_clerk(params, nparties, &mut rng);
let signatures = collect_signatures(&signers, &message);
let avk = clerk.compute_aggregate_verification_key_for_snark();
let mut prover = create_prover(
params,
clerk.closed_key_registration.number_of_registered_parties(),
[0u8; 32],
);
let snark_proof = prover
.aggregate_signatures::<D>(&clerk, &signatures, &message)
.unwrap();
let result = snark_proof.verify(message.as_slice(), &avk);
assert!(result.is_ok());
}
#[test]
fn different_parameters_prove_and_verify_fails() {
let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
let params = Parameters {
m: 100,
k: 5,
phi_f: 0.8,
};
let forged_params = Parameters { m: 3000, ..params };
assert_ne!(params, forged_params);
let nparties = 10;
let merkle_tree_depth = (nparties as u32).next_power_of_two().trailing_zeros();
let message = [1u8; 32];
let (signers, clerk) = setup_signers_and_clerk(params, nparties, &mut rng);
let signatures = collect_signatures(&signers, &message);
let avk: crate::AggregateVerificationKeyForSnark<MithrilMembershipDigest> =
clerk.compute_aggregate_verification_key_for_snark();
let mut prover = create_prover(
forged_params,
clerk.closed_key_registration.number_of_registered_parties(),
[0u8; 32],
);
let forged_snark_proof = prover
.aggregate_signatures::<D>(&clerk, &signatures, &message)
.unwrap();
let snark_proof =
SnarkProof::try_new(forged_snark_proof.circuit_proof, params, merkle_tree_depth)
.unwrap();
let result = snark_proof.verify(message.as_slice(), &avk);
assert!(result.is_err());
}
#[test]
fn verify_fails_with_random_bytes_or_wrong_number_bytes() {
let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
let params = Parameters {
m: 200,
k: 3,
phi_f: 0.8,
};
let nparties = 10;
let message = [1u8; 32];
let (signers, clerk) = setup_signers_and_clerk(params, nparties, &mut rng);
let signatures = collect_signatures(&signers, &message);
let avk: crate::AggregateVerificationKeyForSnark<MithrilMembershipDigest> =
clerk.compute_aggregate_verification_key_for_snark();
let mut prover = create_prover(
params,
clerk.closed_key_registration.number_of_registered_parties(),
[0u8; 32],
);
let snark_proof = prover
.aggregate_signatures::<D>(&clerk, &signatures, &message)
.unwrap();
let mut random_bytes = vec![0u8; snark_proof.circuit_proof.len()];
rng.fill_bytes(&mut random_bytes);
let random_proof =
SnarkProof::try_new(random_bytes, params, compute_circuit_degree(params.k)).unwrap();
let result = random_proof.verify(message.as_slice(), &avk);
assert!(result.is_err(), "Verification of random proof should fail");
let not_enough_bytes = &snark_proof.circuit_proof[0..snark_proof.circuit_proof.len() - 1];
let small_proof = SnarkProof::try_new(
not_enough_bytes.to_vec(),
params,
compute_circuit_degree(params.k),
)
.unwrap();
assert!(
small_proof.verify(message.as_slice(), &avk).is_err(),
"Verification of small proof should fail"
);
let mut too_many_bytes = snark_proof.circuit_proof.to_vec();
too_many_bytes.push(0u8);
let large_proof =
SnarkProof::try_new(too_many_bytes, params, compute_circuit_degree(params.k)).unwrap();
assert!(
large_proof.verify(message.as_slice(), &avk).is_err(),
"Verification of large proof should fail"
);
}
#[test]
fn verify_fails_with_wrong_message() {
let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
let params = Parameters {
m: 100,
k: 5,
phi_f: 0.8,
};
let nparties = 10;
let message = [1u8; 32];
let wrong_message = [2u8; 32];
let (signers, clerk) = setup_signers_and_clerk(params, nparties, &mut rng);
let signatures = collect_signatures(&signers, &message);
let avk = clerk.compute_aggregate_verification_key_for_snark();
let mut prover = create_prover(
params,
clerk.closed_key_registration.number_of_registered_parties(),
[0u8; 32],
);
let snark_proof = prover
.aggregate_signatures::<D>(&clerk, &signatures, &message)
.unwrap();
let result = snark_proof.verify(wrong_message.as_slice(), &avk);
assert!(result.is_err());
}
#[test]
fn non_deterministic_proofs_verify() {
let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
let params = Parameters {
m: 100,
k: 5,
phi_f: 0.8,
};
let nparties = 10;
let message = [1u8; 32];
let (signers, clerk) = setup_signers_and_clerk(params, nparties, &mut rng);
let signatures = collect_signatures(&signers, &message);
let avk = clerk.compute_aggregate_verification_key_for_snark();
let mut prover_1 = create_prover(
params,
clerk.closed_key_registration.number_of_registered_parties(),
[0u8; 32],
);
let snark_proof_1 = prover_1
.aggregate_signatures::<D>(&clerk, &signatures, &message)
.unwrap();
let snark_proof_2 = prover_1
.aggregate_signatures::<D>(&clerk, &signatures, &message)
.unwrap();
assert!(snark_proof_1.verify(&message, &avk).is_ok());
assert!(snark_proof_2.verify(&message, &avk).is_ok());
assert_ne!(
snark_proof_1.circuit_proof, snark_proof_2.circuit_proof,
"The two proofs are different but both verify."
);
}
#[test]
fn snark_proof_to_from_bytes() {
let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
let params = Parameters {
m: 100,
k: 5,
phi_f: 0.8,
};
let nparties = 10;
let message = [1u8; 32];
let (signers, clerk) = setup_signers_and_clerk(params, nparties, &mut rng);
let signatures = collect_signatures(&signers, &message);
let avk = clerk.compute_aggregate_verification_key_for_snark();
let mut prover = create_prover(
params,
clerk.closed_key_registration.number_of_registered_parties(),
[0u8; 32],
);
let snark_proof = prover
.aggregate_signatures::<D>(&clerk, &signatures, &message)
.unwrap();
assert!(snark_proof.verify(&message, &avk).is_ok());
let proof_bytes = snark_proof.to_bytes().unwrap();
let reconstructed_proof: SnarkProof<MithrilMembershipDigest> =
SnarkProof::from_bytes(&proof_bytes).unwrap();
assert_eq!(
proof_bytes,
reconstructed_proof.to_bytes().unwrap(),
"The original bytes should match the ones of the reconstructed proof."
);
assert!(reconstructed_proof.verify(&message, &avk).is_ok());
}
#[test]
fn midnight_vk_wrapper_to_from_bytes() {
let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
let params = Parameters {
m: 100,
k: 5,
phi_f: 0.8,
};
let nparties = 10;
let merkle_tree_depth = (nparties as u32).next_power_of_two().trailing_zeros();
let message = [1u8; 32];
let (signers, clerk) = setup_signers_and_clerk(params, nparties, &mut rng);
let signatures = collect_signatures(&signers, &message);
let avk = clerk.compute_aggregate_verification_key_for_snark();
let snark_setup = SnarkSetup::try_new(¶ms, merkle_tree_depth).unwrap();
let mut prover = SnarkProver {
setup: snark_setup,
rng: ChaCha20Rng::from_seed([0u8; 32]),
};
let mut snark_proof = prover
.aggregate_signatures::<D>(&clerk, &signatures, &message)
.unwrap();
snark_proof.verify(&message, &avk).unwrap();
let cvk_bytes = snark_proof.circuit_verification_key.to_bytes().unwrap();
let cvk_recovered = CircuitVerificationKey::from_bytes(&cvk_bytes).unwrap();
assert_eq!(
cvk_bytes,
cvk_recovered.to_bytes().unwrap(),
"The original bytes should match the ones of the reconstructed value."
);
snark_proof.circuit_verification_key = cvk_recovered;
assert!(
snark_proof.verify(&message, &avk).is_ok(),
"The verification should work when using the reconstructed circuit verification key"
);
}
mod golden {
use crate::AggregateVerificationKeyForSnark;
use super::*;
const GOLDEN_JSON: &str = r#"
{
"circuit_proof": [
179,176,81,240,155,194,225,72,19,100,136,87,186,87,160,172,222,222,118,153,238,236,19,53,19,170,136,7,145,18,240,112,103,207,150,240,161,139,199,179,16,200,226,18,251,212,83,137,169,141,94,231,228,137,127,221,126,19,41,32,12,5,49,115,81,82,127,5,101,136,144,20,71,61,73,96,47,70,84,122,59,112,226,62,116,96,95,249,196,107,136,92,91,33,74,217,180,148,22,138,212,112,89,235,218,31,145,66,33,8,27,211,170,151,91,179,160,195,180,209,59,4,98,155,6,174,184,69,188,15,174,56,164,244,177,106,8,172,205,56,205,217,243,183,165,152,61,62,214,56,149,239,228,119,49,184,108,254,147,14,37,4,239,112,198,192,164,132,165,242,113,98,234,9,235,34,212,177,139,161,181,91,117,245,125,95,8,42,222,175,46,180,183,105,113,209,22,252,171,57,112,215,136,40,98,121,110,45,190,11,80,101,91,163,128,67,117,182,54,66,5,142,103,249,70,66,187,120,115,227,33,197,227,221,56,214,252,191,224,41,181,40,5,144,24,49,46,233,131,144,1,34,85,133,50,5,126,202,78,93,26,240,102,50,228,247,221,121,107,98,187,168,174,23,195,56,74,246,216,95,139,115,17,221,57,54,150,32,132,127,177,65,252,82,162,137,149,245,211,140,120,54,234,255,76,36,168,247,148,195,35,116,135,61,12,82,152,237,190,195,251,233,116,118,36,94,91,133,35,170,178,102,75,187,132,8,136,171,94,128,156,153,102,156,76,68,112,57,67,32,3,99,64,253,159,132,249,135,166,92,73,181,29,61,200,7,140,147,61,0,46,96,25,77,169,50,50,126,88,105,94,221,120,93,184,241,62,2,218,126,32,119,253,14,15,132,33,4,132,126,111,130,55,213,218,175,57,144,189,145,165,134,84,253,164,18,154,19,113,144,186,137,74,88,107,79,203,150,99,249,232,84,138,164,172,119,155,170,233,235,170,116,23,3,230,43,54,52,80,252,44,121,35,139,44,13,235,16,142,145,83,170,228,56,210,237,12,221,169,200,225,20,93,130,214,26,39,51,239,202,142,214,32,45,159,74,88,74,143,232,125,214,130,41,105,225,138,218,58,99,18,240,59,104,34,40,19,113,38,154,52,85,13,82,237,54,227,97,147,22,217,156,140,66,251,153,208,136,134,202,78,216,213,2,34,39,230,145,29,170,9,175,107,71,48,27,188,219,201,225,136,168,113,71,53,57,27,242,43,178,196,189,174,93,221,138,175,186,170,9,5,126,179,19,210,241,179,74,162,98,107,47,6,6,76,138,253,30,225,154,2,69,142,232,174,139,122,212,234,172,176,2,28,32,138,70,137,61,56,89,178,64,106,198,71,59,194,97,160,24,81,131,31,19,147,83,229,9,203,210,30,210,117,77,50,193,77,115,155,148,216,105,160,157,51,42,158,253,225,136,161,194,44,222,247,235,125,215,180,247,189,44,73,130,84,236,209,10,65,211,183,95,164,26,130,38,147,250,157,115,40,123,51,85,148,193,146,61,21,241,9,128,7,255,160,56,125,105,35,15,185,24,143,243,27,129,86,6,174,196,171,77,11,27,141,88,249,127,206,19,160,220,7,253,30,9,57,151,8,35,10,11,37,143,172,228,57,146,29,227,107,42,68,201,75,177,19,129,100,194,145,114,149,212,158,210,126,155,23,217,81,101,51,234,218,68,240,157,142,233,33,84,20,139,165,144,44,169,64,96,11,156,194,35,114,48,92,54,33,40,51,224,237,19,20,126,144,24,242,173,183,240,246,66,17,173,106,155,245,36,104,89,248,152,115,155,132,90,234,186,223,134,231,251,96,31,75,184,89,158,82,206,170,115,150,162,72,34,65,16,188,105,134,95,7,26,23,211,105,58,113,216,3,209,80,255,109,232,153,182,76,159,155,145,166,5,53,160,108,87,58,250,73,163,70,166,76,179,231,34,28,152,225,35,27,55,135,254,4,60,108,77,155,14,24,205,74,190,162,172,23,245,197,0,183,240,226,140,48,247,250,246,148,243,198,172,169,155,244,205,49,13,20,38,24,123,17,246,187,70,239,190,103,230,138,33,48,81,195,134,247,4,78,119,17,185,156,151,146,192,60,136,14,30,179,65,54,235,179,138,134,219,109,199,24,89,46,167,185,183,238,185,240,102,41,215,223,247,180,44,17,84,207,240,89,229,194,105,196,202,231,34,159,80,240,113,210,174,41,217,111,69,21,245,15,71,199,181,143,154,83,63,196,152,195,233,162,185,130,2,14,33,86,217,122,187,86,52,52,127,136,10,56,139,164,79,125,74,144,74,183,79,59,56,96,136,134,173,235,186,102,90,70,228,45,128,141,255,170,137,190,255,172,167,222,126,218,93,96,104,12,113,98,132,176,177,151,26,177,1,150,149,247,112,188,121,99,16,100,173,82,133,200,12,113,193,168,251,145,121,100,126,46,140,175,59,189,41,242,83,202,62,3,104,84,59,197,154,150,2,115,152,110,191,141,243,153,221,37,229,184,163,237,111,9,133,55,124,156,228,58,232,178,203,237,31,222,212,217,144,205,29,130,98,117,9,186,199,15,132,73,148,73,226,253,199,64,163,0,161,86,192,70,126,197,234,205,66,63,151,228,204,241,66,42,49,77,27,130,166,164,181,81,36,53,168,199,122,213,110,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,115,180,185,233,219,54,134,1,249,204,228,105,25,52,21,197,192,179,131,47,167,49,39,123,78,169,158,231,4,215,105,38,173,215,53,153,82,126,227,85,73,11,17,231,119,214,25,74,210,46,45,175,249,228,92,205,221,151,138,52,173,5,118,2,188,153,237,228,184,139,77,219,117,134,72,197,92,249,135,87,115,110,90,142,198,212,198,67,10,136,182,52,201,232,8,55,175,186,247,226,1,99,235,121,169,88,97,98,224,115,73,107,243,76,63,141,197,70,237,68,109,254,2,186,178,228,212,39,26,176,160,197,144,73,51,119,243,114,196,134,167,150,10,140,136,172,11,61,78,70,233,16,228,253,111,194,63,240,86,100,1,94,129,101,156,161,105,247,12,195,114,36,77,147,98,242,37,53,36,224,89,128,36,152,200,75,197,136,15,127,44,90,1,79,28,50,222,189,30,59,230,75,68,48,170,165,82,136,26,40,176,75,161,6,154,135,218,97,46,10,46,148,5,106,254,124,53,144,86,147,83,248,113,153,0,215,173,142,118,109,54,79,4,232,211,187,104,123,93,62,209,239,112,107,243,111,154,166,113,150,191,76,27,99,69,88,165,160,125,199,242,162,250,56,140,254,2,223,62,69,201,200,53,43,157,209,10,31,159,51,108,226,85,248,56,197,1,126,116,254,61,8,25,176,109,241,97,70,249,186,249,98,22,32,144,4,171,99,159,36,38,247,186,22,100,126,33,104,160,161,180,14,215,119,139,14,150,4,82,181,198,75,245,112,207,156,239,56,86,254,250,59,22,183,204,177,144,129,75,168,1,45,109,50,75,51,74,4,11,3,148,80,196,84,67,22,217,196,162,109,64,217,34,72,209,141,96,181,141,23,233,215,5,159,218,165,147,209,162,146,45,52,86,186,23,190,49,161,43,238,185,120,121,201,245,111,51,234,248,242,3,113,134,74,164,165,238,36,108,189,185,21,79,43,248,248,133,134,25,138,251,216,107,214,110,253,157,22,37,189,250,60,122,191,37,148,67,143,150,180,204,181,45,76,191,10,100,37,83,82,226,99,240,242,173,2,110,167,204,4,145,177,209,105,25,150,55,207,202,61,221,181,142,51,51,104,186,35,182,146,103,122,153,20,182,0,89,36,255,151,193,114,83,109,105,119,196,41,144,179,24,161,162,194,129,254,152,255,62,137,36,207,78,83,30,13,170,39,37,235,105,138,147,110,109,221,71,169,12,15,144,59,122,191,140,114,201,123,80,63,24,47,162,134,79,99,247,207,191,129,91,174,176,86,249,68,224,30,70,29,130,101,203,247,94,111,3,87,93,179,225,165,74,151,103,203,80,60,32,152,180,119,217,245,163,24,2,109,252,244,222,240,14,155,12,115,125,59,160,142,24,249,184,228,151,54,38,104,103,252,37,120,234,169,218,182,23,87,80,30,25,147,186,106,246,120,89,37,214,82,228,97,133,104,220,32,170,15,161,227,213,115,168,77,151,100,234,96,64,1,161,6,165,230,23,24,54,67,28,58,248,13,119,164,247,0,35,50,135,229,133,167,16,160,51,252,147,247,235,125,69,225,224,54,180,7,64,85,121,147,141,212,37,91,53,70,251,176,198,209,11,147,136,179,42,16,219,176,240,92,164,106,18,220,97,10,64,151,247,3,71,43,25,3,97,58,197,53,68,127,109,0,239,189,243,190,212,225,195,195,240,164,232,150,72,15,40,96,51,192,181,172,192,15,28,190,98,14,151,98,66,197,228,76,59,160,205,133,77,24,165,158,240,21,235,220,79,104,245,98,237,150,21,191,127,56,87,209,91,21,10,32,210,192,217,57,189,44,226,145,231,182,31,73,183,96,73,110,45,196,19,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,45,74,83,75,149,79,63,245,30,216,109,18,189,13,150,161,242,79,215,65,197,23,103,41,7,142,72,221,254,113,95,145,217,231,253,106,155,216,145,86,124,244,208,103,216,31,150,237,40,254,68,199,169,97,166,108,87,40,135,163,196,171,12,230,240,1,102,28,131,17,243,203,22,168,40,100,254,204,111,167,170,130,16,59,208,213,63,89,80,204,225,17,239,121,11,220,113,189,183,188,205,211,181,11,30,210,89,144,112,94,168,9,53,84,179,188,166,245,171,188,182,95,180,55,171,184,20,115,117,131,134,238,35,235,38,85,210,208,44,136,151,152,116,186,170,49,82,48,188,0,85,228,237,200,89,46,144,139,77,209,13,7,183,60,196,131,78,166,20,226,93,200,34,214,72,2,129,130,21,183,226,216,51,64,224,219,74,104,94,96,43,133,74,49,33,145,7,21,203,95,118,221,52,207,249,133,122,162,51,109,73,178,184,32,210,231,241,179,123,118,200,223,88,6,60,203,152,181,175,231,168,215,180,120,120,167,12,180,77,27,143,132,71,73,26,133,84,180,55,191,209,108,146,24,22,150,156,134,186,255,169,170,234,89,154,172,157,64,104,128,242,198,244,192,6,156,207,146,179,104,223,181,253,249,248,244,92,110,194,156,117,43,97,54,253,225,196,27,31,123,194,130,3,141,104,13,48,252,175,19,160,71,33,133,27,35,83,143,55,121,6,12,246,47,118,197,14,193,96,85,253,4,141,99,82,167,43,4,153,240,151,220,25,108,24,161,2,252,38,115,80,2,147,215,144,233,9,0,53,229,180,228,237,10,68,70,195,166,217,102,146,70,69,115,166,161,20,72,246,110,47,50,101,170,203,117,94,145,50,115,178,183,241,158,145,113,243,35,1,194,80,167,217,31,28,224,68,25,106,240,13,5,52,138,68,7,21,48,15,248,215,45,219,6,114,195,114,94,77,153,169,139,79,22,255,114,8,138,127,20,24,214,96,222,145,156,10,239,91,207,184,130,59,142,33,43,233,2,136,33,54,123,190,6,246,127,100,130,186,159,234,219,67,95,131,69,182,225,51,148,210,56,123,179,75,200,67,230,130,186,94,98,103,190,92,119,175,20,243,219,137,218,24,238,105,23,188,188,70,90,20,88,33,22,67,161,140,193,59,219,121,171,138,101,34,206,146,114,129,81,162,198,159,177,42,0,61,244,79,55,50,215,80,249,68,83,169,241,171,161,65,238,150,55,222,158,23,226,26,46,237,13,192,98,18,215,73,150,83,160,69,194,24,194,29,83,69,200,150,72,196,222,58,216,6,128,31,121,251,54,178,162,187,254,136,73,90,108,190,177,196,21,52,64,27,40,3,196,27,236,218,5,137,226,7,253,156,191,60,22,28,169,4,183,237,1,17,140,33,16,19,102,188,225,126,104,168,254,92,36,70,117,82,144,32,212,53,134,199,199,242,182,5,62,235,250,28,216,250,145,126,252,34,131,110,251,13,91,124,130,111,57,93,11,179,191,119,229,138,178,38,228,113,210,6,27,4,73,197,178,85,248,230,239,95,119,150,24,72,234,34,100,108,57,37,99,250,72,1,47,39,153,211,93,211,124,32,201,18,65,0,48,98,240,247,16,20,184,174,243,48,65,153,28,10,165,255,219,250,140,160,157,73,186,70,65,139,45,228,222,171,2,219,211,233,70,237,52,212,150,115,169,179,243,14,86,98,1,91,133,98,49,79,92,144,203,65,132,241,119,93,22,68,201,100,120,228,233,183,166,149,125,83,116,157,214,217,249,78,176,85,234,110,231,14,110,95,157,214,253,164,242,90,126,37,213,251,159,135,136,37,222,228,177,91,54,116,168,207,69,41,184,136,78,216,74,232,125,113,238,113,16,9,114,131,102,90,39,131,50,126,72,139,45,132,79,97,187,69,181,142,12,4,5,163,54,146,67,82,211,68,233,37,213,178,100,30,142,111,58,181,54,184,41,1,242,47,35,149,94,144,234,249,167,34,50,51,102,145,212,17,209,185,17,186,12,78,96,52,219,232,113,79,211,0,225,202,136,148,8,232,47,248,192,229,149,26,73,192,58,234,98,206,166,123,136,58,4,21,250,121,50,177,139,2,201,58,196,40,14,6,0,63,41,54,244,82,100,94,51,187,31,244,251,71,97,215,210,109,182,43,132,188,212,139,172,105,46,39,245,47,196,10,201,63,247,179,72,242,134,79,182,24,184,211,138,80,215,149,250,89,39,206,220,100,86,200,24,79,67,194,60,141,63,96,81,115,180,247,251,188,167,59,190,196,22,140,16,106,189,251,228,101,99,4,165,232,135,148,29,96,139,174,238,184,216,58,103,80,88,184,96,160,228,61,222,180,106,74,125,240,7,150,130,203,44,112,254,83,107,227,41,172,165,133,174,242,100,159,234,111,247,122,173,172,200,6,162,250,87,195,64,154,56,167,150,210,175,220,122,96,248,56,169,35,101,121,27,235,53,34,30,70,214,175,47,143,73,16,177,37,116,224,82,102,117,226,27,161,30,96,213,49,217,183,104,64,103,87,18,40,156,95,76,53,129,51,42,248,56,94,110,90,118,29,175,160,93,59,91,3,169,112,117,140,145,76,156,7,57,98,107,219,164,72,106,207,228,123,134,4,160,13,77,111,237,133,139,139,8,21,62,114,131,35,67,246,248,22,176,153,156,238,102,89,238,211,245,131,134,54,151,211,225,72,180,226,203,106,60,101,117,145,231,41,255,60,187,148,87,46,67,40,104,113,254,27,177,126,231,28,197,94,134,184,137,103,240,209,228,201,20,227,14,141,255,29,232,233,127,59,27,222,77,57,95,205,60,93,35,56,158,10,78,78,245,187,233,28,163,235,254,66,133,77,15,77,65,59,66,18,224,9,148,137,210,47,33,132,165,237,200,98,131,75,58,22,232,137,252,68,70,72,84,180,64,120,71,17,56,190,203,148,19,49,98,39,43,200,14,132,183,31,252,14,165,146,26,174,144,74,197,158,52,244,12,98,198,10,37,181,66,7,146,128,77,18,238,78,40,160,71,157,11,240,94,171,0,249,226,45,138,80,143,79,168,40,92,152,80,218,215,64,166,51,35,72,70,211,252,59,74,208,106,125,66,191,157,40,160,230,178,3,21,177,158,80,173,179,126,156,158,22,67,52,82,127,143,13,185,145,6,78,25,206,110,59,55,164,189,48,197,234,62,194,242,236,123,144,36,251,110,28,116,34,249,42,146,178,248,163,112,172,194,112,168,161,219,229,30,236,44,3,130,155,169,192,79,117,127,70,158,190,156,96,74,23,165,70,188,153,16,100,91,173,145,67,103,49,87,95,46,190,71,150,160,232,40,17,106,112,0,164
],
"params": {
"m": 200,
"k": 5,
"phi_f": 0.8
},
"merkle_tree_depth": 4,
"circuit_verification_key": [
1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,2,8,2,0,0,0,3,14,22,0,0,0,25,174,47,83,192,214,13,208,45,3,207,117,105,130,76,32,221,2,158,125,34,25,19,164,43,56,191,149,129,103,33,235,140,98,81,29,229,57,226,120,143,239,229,134,2,79,21,210,15,49,97,119,151,113,64,59,182,27,25,214,74,213,191,123,110,34,210,45,249,222,168,122,133,34,29,169,35,109,54,80,19,175,241,108,243,54,115,160,14,155,77,0,137,128,51,80,17,217,217,152,96,174,142,158,156,31,249,231,183,17,204,238,40,2,241,178,98,92,49,13,157,18,94,20,158,14,171,251,139,28,180,197,150,213,103,89,215,95,26,65,223,150,49,47,24,30,83,158,82,99,81,53,74,27,124,83,226,16,157,226,103,68,43,161,230,65,129,78,170,87,14,91,70,137,93,255,18,52,43,248,156,240,231,227,255,224,73,25,21,160,42,215,21,60,64,56,96,212,126,52,99,215,190,60,75,151,2,120,133,11,79,246,35,46,180,254,171,242,37,138,97,251,156,201,86,255,32,243,239,192,250,181,177,232,213,50,15,93,165,204,8,97,216,150,51,106,75,24,149,219,228,139,236,159,55,78,82,28,57,66,15,112,228,204,117,131,70,5,195,17,137,95,8,85,188,56,128,207,33,254,9,169,220,183,65,31,45,253,17,104,107,38,61,137,23,84,231,129,180,35,12,11,117,98,15,69,239,101,68,122,6,139,2,157,162,3,177,23,189,79,245,57,7,122,60,8,5,102,147,76,177,61,78,53,52,115,8,69,40,112,134,94,200,93,85,134,222,47,248,5,141,149,109,241,110,214,207,78,254,11,125,156,61,130,203,94,254,239,4,19,206,182,162,221,250,86,118,79,101,219,213,2,133,8,18,204,135,83,13,125,56,143,19,55,177,221,96,52,50,39,159,146,184,58,7,31,235,25,195,97,139,5,115,69,94,140,238,252,98,128,32,165,242,214,129,101,148,80,17,113,206,206,3,190,164,43,1,62,29,165,61,150,154,166,191,56,204,149,35,247,99,64,175,156,129,178,50,242,163,46,100,92,37,30,2,33,133,143,129,81,10,9,217,98,15,105,70,237,242,136,10,172,31,184,23,144,75,161,109,121,96,106,116,236,81,122,210,18,0,106,3,148,191,18,228,221,52,171,214,37,199,145,222,77,69,31,248,2,67,153,229,23,132,25,206,54,6,63,1,144,247,178,63,47,229,15,145,193,20,111,103,171,188,199,192,23,251,196,161,106,151,153,16,85,196,49,217,44,181,202,122,82,64,142,63,142,246,245,19,115,102,2,77,76,72,114,9,194,119,203,66,6,186,165,197,150,20,128,128,218,2,207,138,26,161,36,199,175,203,78,111,100,50,70,18,51,49,149,41,227,251,26,8,114,187,110,185,242,40,49,239,22,151,41,16,62,85,184,218,114,71,10,173,198,43,215,183,209,103,212,15,127,48,1,68,70,82,91,6,100,216,48,97,208,145,157,211,63,169,51,55,139,215,49,36,145,246,128,130,137,136,148,19,153,71,157,148,102,235,42,90,46,92,58,157,109,210,119,49,43,122,9,47,150,65,123,246,193,80,37,181,158,191,45,118,146,231,93,62,210,145,105,246,130,212,241,53,119,166,249,0,191,132,159,143,98,213,203,78,135,30,16,136,48,26,57,169,230,249,56,83,236,20,181,73,81,93,140,28,204,244,193,172,53,213,210,113,77,228,17,100,147,128,47,67,129,52,133,18,151,0,99,185,121,122,176,198,8,98,168,184,83,128,54,1,175,232,157,58,209,56,180,162,108,9,55,194,117,42,245,7,47,84,83,14,235,164,95,235,146,153,10,255,242,146,254,14,139,42,130,59,33,223,81,205,44,139,49,171,221,64,164,171,173,37,127,238,6,46,174,163,234,157,252,115,212,87,72,223,160,84,224,227,249,0,197,236,150,203,172,89,63,166,58,20,172,185,44,50,182,102,151,103,232,220,115,163,117,134,111,100,173,247,154,205,190,25,17,216,164,162,156,122,247,175,50,207,156,145,144,205,106,178,18,90,148,64,130,221,200,237,116,16,176,198,39,95,76,233,49,28,57,109,160,183,150,121,211,183,152,127,235,115,106,52,115,224,181,6,156,187,103,209,240,90,235,116,16,174,20,90,208,28,50,23,141,20,40,67,30,12,105,233,178,154,102,11,251,246,233,122,6,80,146,19,142,204,248,218,77,186,83,92,86,153,0,230,136,215,16,158,3,255,189,194,51,237,106,110,78,153,190,155,59,222,84,96,133,14,229,127,109,161,239,169,132,4,142,58,120,222,117,217,207,131,231,193,65,104,10,127,115,217,233,161,65,226,61,79,242,237,120,90,52,106,87,78,69,166,247,175,52,86,27,115,234,14,109,146,152,134,232,47,213,9,204,255,228,166,48,184,58,121,60,176,196,228,252,19,176,241,146,52,47,235,134,77,140,162,2,112,69,4,97,222,27,200,69,201,16,122,5,50,218,4,176,141,129,118,91,232,6,158,224,133,255,131,30,166,124,149,59,34,30,37,199,148,113,245,79,244,171,66,198,173,71,183,33,160,145,248,167,65,80,168,1,1,72,50,66,124,3,23,39,165,170,248,142,102,213,142,2,189,203,31,33,232,114,205,127,166,165,222,250,16,74,219,124,13,103,125,194,169,141,126,111,97,75,173,162,89,163,47,193,201,89,211,160,102,143,5,96,76,28,124,195,71,58,192,213,41,221,49,189,239,246,60,121,223,68,254,221,216,167,25,47,217,121,89,213,92,157,58,174,89,79,191,185,44,149,180,206,251,232,106,77,154,64,8,1,46,106,185,100,45,92,105,27,40,189,41,15,31,181,221,236,41,125,69,76,95,97,207,119,33,69,210,138,156,147,58,15,212,75,89,245,144,111,99,67,37,148,8,176,115,222,11,51,30,225,237,103,166,102,186,38,25,18,176,183,59,86,70,125,245,242,160,51,37,171,74,60,112,142,189,32,17,122,178,4,77,151,185,203,152,213,128,192,138,98,209,113,241,86,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,202,35,194,94,221,247,176,97,140,65,70,17,129,29,151,185,126,238,97,125,154,126,184,7,109,231,195,214,107,79,118,139,71,125,106,42,36,37,255,209,74,98,96,253,215,218,210,8,50,207,128,121,178,243,159,248,44,173,233,184,251,32,89,102,6,99,173,71,93,86,213,131,114,143,246,104,124,158,161,246,35,136,62,80,89,13,9,61,250,49,81,238,127,149,117,19,29,117,37,10,240,18,44,215,204,216,80,74,85,79,0,169,9,167,60,217,173,61,89,17,1,50,239,215,142,178,90,19,236,43,118,153,228,165,152,146,47,20,231,180,49,99,164,2,212,154,237,151,35,26,111,127,102,10,147,254,193,142,249,171,68,155,139,17,183,2,96,101,81,187,31,20,38,203,165,243,150,59,139,133,99,123,37,176,67,45,149,85,69,142,106,7,184,37,1,179,154,57,217,21,89,140,34,116,45,93,61,80,164,217,51,101,15,76,252,58,10,26,178,249,90,55,103,14,228,229,167,162,72,97,189,196,26,172,20,175,148,157,125,9,215,119,112,152,212,225,126,160,104,66,75,207,56,22,169,253,53,26,199,55,174,104,226,186,217,175,190,141,52,183,115,255,94,116,43,57,123,66,37,193,177,233,96,95,19,203,168,1,89,180,54,18,43,68,235,205,30,245,102,227,249,226,62,242,25,9,137,102,89,36,137,140,7,8,153,4,143,32,87,82,203,45,133,43,134,121,135,48,228,207,205,159,84,113,191,22,17,221,20,195,241,29,11,66,16,182,178,214,227,212,144,225,75,196,131,112,25,183,24,70,253,242,89,30,118,121,54,190,84,231,2,24,239,124,188,3,144,204,80,101,220,92,57,19,254,42,143,47,246,237,56,153,220,100,101,218,231,101,131,125,107,58,174,249,135,169,82,96,230,234,104,254,27,167,242,142,41,241,176,87,143,19,130,141,97,139,253,147,102,178,165,24,149,218,58,96,187,162,143,192,106,79,154,108,100,0,214,95,171,225,157,221,186,39,210,255,208,88,33,215,113,105,91,215,165,196,196,55,90,164,81,191,230,56,190,122,247,236,157,12,154,124,197,66,245,240,30,28,34,106,115,241,67,148,122,13,221,102,243,232,22,101,221,101,242,60,67,42,160,223,226,50,3,182,79,243,133,62,85,64,127,247,227,5,177,182,120,9,14,220,124,146,153,113,137,31,58,218,154,63,246,58,217,205,115,109,222,82,237,89,81,3,23,105,218,149,193,252,111,153,238,159,57,195,174,45,60,179,248,26,120,177,254,159,15,4,242,248,106,199,93,18,228,248,107,180,251,108,211,245,226,29,112,212,194,83,55,107,67,149,197,199,224,170,134,167,3,223,145,91,210,146,57,136,149,172,166,34,237,85,145,86,75,25,85,251,78,201,134,111,135,223,89,91,114,149,234,92,47,154,216,49,157,136,57,109,8,244,31,113,39,127,92,28,63,130,147,10,124,119,150,202,84,159,131,3,5,185,167,79,49,25,43,52,164,185,147,31,229,48,202,227,221,65,30,127,154,1,31,221,93,86,226,35,249,10,5,28,104,161,110,182,128,121,76,5,61,10,104,198,25,61,59,128,57,251,103,221,204,14,87,220,183,68,170,29,93,47,51,25,73,254,154,171,119,47,142,13,97,169,111,100,220,121,117,69,153,50,126,54,100,89,48,203,211,145,177,94,178,6,116,49,199,215,205,24,215,20,221,189,99,121,208,217,156,154,196,206,41,1,62,218,187,211,141,44,30,200,111,76,207,121,170,43,93,62,109,54,214,227,207,18,112,249,52,239,117,73,107,3,189,148,124,188,242,3,99,63,222,221,168,98,87,216,199,32,255,61,118,202,207,74,53,252,66,83,125,68,201,52,83,203,134,185,167,46,187,11,108,15,10,31,5,190,234,201,203,249,208,253,249,8,233,5,88,186,70,99,119,123,0,247,212,3,102,84,23,25,87,75,212,13,21,102,48,135,137,197,176,205,54,131,94,117,224,88,34,124,98,66,128,81,215,106,242,124,210,248,172,90,55,21,204,82,255,136,168,189,16,91,133,211,161,119,85,179,162,110,218,48,219,3,35,80,10,247,203,152,108,51,201,58,170,247,83,183,28,58,209,74,12,95,163,51,2,61,234,156,235,3,235,69,156,126,106,163,145,71,65,12,54,166,27,115,168,235,193,40,237,169,203,186,146,104,167,69,215,125,219,16,67,26,137,90,127,248,53,55,105,136,75,183,167,150,90,144,59,5,155,41,184,26,205,249,219,67,184,106,175,148,41,115,7,84,4,85,85,158,254,206,240,180,57,57,242,150,194,126,100,224,24,61,232,109,139,214,87,191,18,54,208,181,157,165,128,2,18,207,27,169,11,102,100,224,112,91,46,23,227,48,73,109,135,149,180,215,69,158,248,231,88,237,216,41,161,87,187,139,248,41,59,111,253,195,253,147,212,66,23,195,9,115,118,2,216,112,42,248,121,206,68,212,51,197,0,18,251,176,227,109,103,177,22,145,211,111,14,104,78,247,63,121,121,179,101,140,251,246,244,227,33,248,76,22,50,16,182,189,100,144,26,13,24,236,152,50,100,106,247,71,156,242,75,94,138,171,32,215,107,42,80,5,1,234,158,38,119,220,13,84,216,199,106,25,181,213,79,75,146,68,244,155,159,101,153,153,127,233,109,0,108,74,148,148,250,21,68,226,100,77,103,182,101,115,9,3,28,212,218,141,250,50,20,18,174,1,79,165,244,210,37,83,122,172,195,10,151,35,57,232,169,207,187,193,1,84,105,1,106,219,3,219,156,189,192,69,96,125,155,221,178,104,234,4,38,139,69,64,46,17,227,0,62,237,48,223,25,228,168,60,159,59,57,50,140,240,61,144,112,103,248,85,228,251,169,20,209,161,237,113,208,27,110,178,16,198,12,127,86,135,123,106,134,50,58,42,186,67,130,158,2,106,8,6,227,184,249,194,165,148,132,168,144,161,201,80,51,138,194,189,89,77,23,19,15,230,153,131,60,169,122,238,191,242,179,171,252,83,157,221,253,8,162,109,65,186,157,71,46,61,242,157,189,157,74,232,112,27,191,208,194,162,36,237,230,192,213,154,69,223,87,6,16,160,207,238,154,177,109,195,201,201,173,77,197,64,92,66,156,102,213,189,174,57,145,74,173,209,141,189,56,159,86,94,15,239,214,248,44,90,218,241,60,5,177,18,50,22,55,3,119,156,199,194,89,56,116,105,156,242,139,85,184,77,9,208,48,63,82,198,243,65,14,14,119,70,197,242,125,245,193,197,149,70,73,69,15,74,145,155,39,50,33,48,126,2,95,1,178,102,120,226,81,219,146,227,117,147,245,89,59,44,11,69,217,74,140,177,133,208,224,180,69,126,199,162,160,237,65,175,130,137,112,3,34,43,126,149,232,182,45,105,4,217,33,10,74,104,75,114,93,42,163,162,222,177,68,246,160,231,58,59,48,129,188,243,37,95,46,107,139,78,42,29,148,69,245,107,100,239,19,18,236,103,16,192,210,40,36,220,169,98,12,5,47,197,30,235,182,19,176,178,8,19,82,33,161,7,113,67,141,72,236,85,84,251,52,202,255,144,229,173,133,68,241,8,132,224,122,9,117,89,193,86,26,198,210,101,158,242,14
]
}
"#;
// The proof generated is random for now so the golden value function is only
// used to generate a proof that is stored and needs to be verifiable
// TODO: Once the deterministic proof generation is available in the released
// midnight-proof crate, we can update is function to output a fixed value
// that can be compared to the JSON constant
fn golden_value_setup() -> (
SnarkProof<MithrilMembershipDigest>,
AggregateVerificationKeyForSnark<MithrilMembershipDigest>,
[u8; 32],
) {
let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
let params = Parameters {
m: 200,
k: 5,
phi_f: 0.8,
};
let nparties = 10;
let message = [1u8; 32];
let (signers, clerk) = setup_signers_and_clerk(params, nparties, &mut rng);
let signatures = collect_signatures(&signers, &message);
let mut prover = create_prover(
params,
clerk.closed_key_registration.number_of_registered_parties(),
[0u8; 32],
);
let avk = clerk.compute_aggregate_verification_key_for_snark();
let snark_proof = prover.aggregate_signatures::<D>(&clerk, &signatures, &message);
(snark_proof.unwrap(), avk, message)
}
#[test]
fn golden_conversion() {
let snark_proof: SnarkProof<MithrilMembershipDigest> =
serde_json::from_str(GOLDEN_JSON)
.expect("This JSON deserialization should not fail");
let (_, aggregate_verification_key, message) = golden_value_setup();
assert!(snark_proof.verify(&message, &aggregate_verification_key).is_ok());
}
}
}