spawn-zk-snarks 0.1.5

Zero-knowledge proof library with EVM compatibility
Documentation
// Copyright (c) 2023 spawn-zk-snarks developers
//
// Licensed under the MIT License
// <LICENSE-MIT or http://opensource.org/licenses/MIT>

use super::*;
use ark_bn254::{Bn254, Fr};
use ark_ff::One;

#[test]
fn test_proof_generation_and_verification() {
    // Setup with realistic circuit size
    let num_constraints = 10;
    let num_variables = 5;
    let setup = Groth16Setup::new(num_constraints, num_variables).unwrap();

    // Create test inputs and witness
    let inputs = vec![Fr::one()];
    let witness = vec![Fr::one(), Fr::one(), Fr::one(), Fr::one(), Fr::one()];

    // Generate proof
    let proof = setup.prove(&inputs, &witness).unwrap();

    // Verify proof
    let result = setup.verify(&proof, &inputs).unwrap();
    assert!(result, "Proof verification should succeed");

    // Test with invalid inputs
    let invalid_inputs = vec![Fr::one(), Fr::one()];
    let result = setup.verify(&proof, &invalid_inputs);
    assert!(result.is_err(), "Verification should fail with invalid inputs");
}

#[test]
fn test_evm_compatibility() {
    // Setup
    let setup = Groth16Setup::new(10, 5).unwrap();
    
    // Generate a proof
    let inputs = vec![Fr::one()];
    let witness = vec![Fr::one(); 5];
    let proof = setup.prove(&inputs, &witness).unwrap();

    // Convert to EVM format
    let calldata = proof_to_calldata(&proof, &inputs).unwrap();
    assert!(!calldata.is_empty(), "Calldata should not be empty");

    // Generate verifier contract
    let contract = generate_verifier_contract(&setup.verifying_key).unwrap();
    assert!(contract.contains("contract Groth16Verifier"), "Contract should contain verifier code");
    assert!(contract.contains("function verify"), "Contract should contain verify function");
}

#[test]
fn test_gas_estimation() {
    // Test with various proof sizes
    let small_proof = 128;
    let large_proof = 512;
    let num_inputs = 2;
    
    let small_gas = Groth16Setup::<Bn254>::estimate_verification_gas(small_proof, num_inputs);
    let large_gas = Groth16Setup::<Bn254>::estimate_verification_gas(large_proof, num_inputs);
    
    // Basic assertions
    assert!(small_gas > 0, "Gas estimation should be positive");
    assert!(large_gas > small_gas, "Larger proof should cost more gas");
    assert!(small_gas < 1_000_000, "Gas cost should be reasonable");

    // Test gas cost components
    let base_cost = 150_000;
    let input_cost = num_inputs as u64 * 1_000;
    let data_cost = small_proof as u64 * 16;
    let expected_gas = base_cost + input_cost + data_cost;
    
    assert_eq!(small_gas, expected_gas, "Gas calculation should match expected formula");
}

#[test]
fn test_error_handling() {
    // Test invalid circuit size
    let result = Groth16Setup::new(0, 0);
    assert!(result.is_err(), "Should fail with zero-sized circuit");

    // Test invalid witness size
    let setup = Groth16Setup::new(10, 5).unwrap();
    let inputs = vec![Fr::one()];
    let invalid_witness = vec![Fr::one()]; // Too small
    let result = setup.prove(&inputs, &invalid_witness);
    assert!(result.is_err(), "Should fail with invalid witness size");
}