proof-of-sql 0.129.0

High performance zero knowledge (ZK) prover for SQL.
Documentation
use super::HyperKZGCommitment;
use crate::{
    base::{
        commitment::{CommitmentEvaluationProof, VecCommitmentExt},
        database::Column,
        polynomial::compute_evaluation_vector,
        proof::{Keccak256Transcript, Transcript},
        scalar::MontScalar,
    },
    proof_primitive::hyperkzg::{
        public_setup::load_small_setup_for_testing, BNScalar, HyperKZGCommitmentEvaluationProof,
    },
};
use ark_ff::{PrimeField, UniformRand};
use bincode::config::{BigEndian, Configuration, Fixint};
use itertools::Itertools;
use rand::Rng;

const BINCODE_CONFIG: Configuration<BigEndian, Fixint> = bincode::config::standard()
    .with_big_endian()
    .with_fixed_int_encoding();

fn run_evm_verify_hyperkzg(
    commit: HyperKZGCommitment,
    proof: &HyperKZGCommitmentEvaluationProof,
    state: [u8; 32],
    x: &[BNScalar],
    y: BNScalar,
) {
    run_evm_verify_hyperkzg_with_extra_args(commit, proof, state, x, y, &[]);
    run_evm_verify_hyperkzg_with_extra_args(commit, proof, state, x, y, &["--via-ir"]);
    run_evm_verify_hyperkzg_with_extra_args(commit, proof, state, x, y, &["--optimize"]);
    run_evm_verify_hyperkzg_with_extra_args(
        commit,
        proof,
        state,
        x,
        y,
        &["--via-ir", "--optimize"],
    );
}
fn run_evm_verify_hyperkzg_with_extra_args(
    commit: HyperKZGCommitment,
    proof: &HyperKZGCommitmentEvaluationProof,
    state: [u8; 32],
    x: &[BNScalar],
    y: BNScalar,
    extra_args: &[&'static str],
) {
    let commits_bytes = bincode::serde::encode_to_vec(commit, BINCODE_CONFIG).unwrap();
    let proof_bytes = bincode::serde::encode_to_vec(proof, BINCODE_CONFIG).unwrap();
    assert!(
        std::process::Command::new("../../solidity/scripts/pre_forge.sh")
            .arg("script")
            .args(extra_args)
            .args(["--tc", "HyperKZGVerifierTest"])
            .args([
                "--sig",
                "verifyHyperKZG(bytes,uint256[1],uint256[2],uint256[],uint256)"
            ])
            .arg("./test/hyperkzg/HyperKZGVerifier.t.post.sol")
            .arg(hex::encode(&proof_bytes))
            .arg(format!("[0x{}]", hex::encode(state)))
            .arg(format!(
                "[0x{},0x{}]",
                hex::encode(&commits_bytes[..32]),
                hex::encode(&commits_bytes[32..])
            ))
            .arg(format!(
                "[{}]",
                x.iter().map(|x| x.0.into_bigint().to_string()).join(",")
            ))
            .arg(y.0.into_bigint().to_string())
            .output()
            .unwrap()
            .status
            .success()
    );
}

#[ignore = "foundry must be installed in order to run this test"]
#[test]
fn we_can_create_small_valid_proof_for_use_in_solidity_tests() {
    let (ps, vk) = load_small_setup_for_testing();

    let a = [
        BNScalar::from(0),
        BNScalar::from(1),
        BNScalar::from(2),
        BNScalar::from(3),
    ];
    let x = [BNScalar::from(7), BNScalar::from(5)];

    let mut b_vec = vec![BNScalar::default(); a.len()];
    compute_evaluation_vector(&mut b_vec, &x);
    let y: BNScalar = a.iter().zip(b_vec).map(|(a, b)| *a * b).sum();
    let commit = Vec::from_columns_with_offset([Column::Scalar(&a)], 0, &&ps[..])[0];

    let mut transcript = Keccak256Transcript::new();
    let proof = <HyperKZGCommitmentEvaluationProof>::new(&mut transcript, &a, &x, 0, &&ps[..]);

    let mut transcript = Keccak256Transcript::new();
    let r = proof.verify_proof(&mut transcript, &commit, &y, &x, 0, a.len(), &&vk);
    assert!(r.is_ok());

    let mut transcript = Keccak256Transcript::new();
    let state = transcript.challenge_as_le();

    run_evm_verify_hyperkzg(commit, &proof, state, &x, y);
}

#[ignore = "foundry must be installed in order to run this test"]
#[test]
fn we_can_generate_and_verify_random_hyperkzg_proofs() {
    let (ps, vk) = load_small_setup_for_testing();

    let mut rng = ark_std::test_rng();

    for nu in 1..9 {
        let len = 1 << nu;

        let a = (0..len)
            .map(|_| MontScalar(ark_ff::Fp::rand(&mut rng)))
            .collect::<Vec<_>>();
        let x = (0..nu)
            .map(|_| MontScalar(ark_ff::Fp::rand(&mut rng)))
            .collect::<Vec<_>>();

        let mut b_vec = vec![BNScalar::default(); a.len()];
        compute_evaluation_vector(&mut b_vec, &x);
        let y: BNScalar = a.iter().zip(b_vec).map(|(a, b)| *a * b).sum();
        let commit = Vec::from_columns_with_offset([Column::Scalar(&a)], 0, &&ps[..])[0];

        let mut transcript = Keccak256Transcript::new();
        let proof = <HyperKZGCommitmentEvaluationProof>::new(&mut transcript, &a, &x, 0, &&ps[..]);

        let mut transcript = Keccak256Transcript::new();
        let r = proof.verify_proof(&mut transcript, &commit, &y, &x, 0, a.len(), &&vk);
        assert!(r.is_ok());

        let mut transcript = Keccak256Transcript::new();
        let state = transcript.challenge_as_le();

        run_evm_verify_hyperkzg(commit, &proof, state, &x, y);
    }
}

#[ignore = "foundry must be installed in order to run this test"]
#[test]
fn we_can_generate_and_verify_random_hyperkzg_proofs_with_random_length() {
    let (ps, vk) = load_small_setup_for_testing();

    let mut rng = ark_std::test_rng();

    for nu in 1..8 {
        let len = rng.gen_range((1 << (nu - 1)) + 1..=1 << nu);

        let a = (0..len)
            .map(|_| MontScalar(ark_ff::Fp::rand(&mut rng)))
            .collect::<Vec<_>>();
        let x = (0..nu)
            .map(|_| MontScalar(ark_ff::Fp::rand(&mut rng)))
            .collect::<Vec<_>>();

        let mut b_vec = vec![BNScalar::default(); a.len()];
        compute_evaluation_vector(&mut b_vec, &x);
        let y: BNScalar = a.iter().zip(b_vec).map(|(a, b)| *a * b).sum();
        let commit = Vec::from_columns_with_offset([Column::Scalar(&a)], 0, &&ps[..])[0];

        let mut transcript = Keccak256Transcript::new();
        let proof = <HyperKZGCommitmentEvaluationProof>::new(&mut transcript, &a, &x, 0, &&ps[..]);

        let mut transcript = Keccak256Transcript::new();
        let r = proof.verify_proof(&mut transcript, &commit, &y, &x, 0, a.len(), &&vk);
        assert!(r.is_ok());

        let mut transcript = Keccak256Transcript::new();
        let state = transcript.challenge_as_le();

        run_evm_verify_hyperkzg(commit, &proof, state, &x, y);
    }
}