zksync-gpu-prover 0.155.10

ZKsync GPU prover utilities
use super::*;

pub fn round5<C: Circuit<Bn256>, T: Transcript<Fr>, MC: ManagerConfigs>(
    manager: &mut DeviceMemoryManager<Fr, MC>,
    proof: &mut Proof<Bn256, C>,
    constants: &mut ProverConstants<Fr>,
    transcript: &mut T,
) -> Result<(), ProvingError> {
    get_round_5_challenges(constants, transcript);
    compute_proof_opening_at_z(manager, constants)?;
    compute_proof_opening_at_z_omega(manager, constants)?;
    free_useless_round_5_slots(manager)?;

    commit_proof_openings(manager, proof)?;

    let poly_ids = [PolyId::W, PolyId::W1];

    for id in poly_ids.iter() {
        manager.free_slot(*id, PolyForm::Monomial);
    }

    Ok(())
}

fn get_round_5_challenges<T: Transcript<Fr>>(
    constants: &mut ProverConstants<Fr>,
    transcript: &mut T,
) {
    let v = transcript.get_challenge();
    let mut tmp = v;
    constants.v = vec![];

    for _ in 0..17 {
        constants.v.push(tmp);
        tmp.mul_assign(&v);
    }
}

fn compute_proof_opening_at_z<MC: ManagerConfigs>(
    manager: &mut DeviceMemoryManager<Fr, MC>,
    constants: &ProverConstants<Fr>,
) -> Result<(), ProvingError> {
    manager.rename_slot(PolyId::TPart(0), PolyId::W, PolyForm::Monomial);

    for (coeff, id) in compute_coeffs_and_ids_for_opening_at_z(constants).iter() {
        manager.add_assign_scaled(PolyId::W, *id, PolyForm::Monomial, *coeff)?;
    }

    manager.devide_monomial_by_degree_one_monomial(PolyId::W, constants.z)?;
    Ok(())
}

fn compute_coeffs_and_ids_for_opening_at_z(constants: &ProverConstants<Fr>) -> Vec<(Fr, PolyId)> {
    let mut coeffs = vec![];

    for v_power in constants.v[0..12].iter() {
        coeffs.push(*v_power);
    }

    let ids = [
        PolyId::R,
        PolyId::A,
        PolyId::B,
        PolyId::C,
        PolyId::D,
        PolyId::QMainSelector,
        PolyId::Sigma(0),
        PolyId::Sigma(1),
        PolyId::Sigma(2),
        PolyId::T,
        PolyId::QLookupSelector,
        PolyId::QTableType,
    ];

    coeffs.into_iter().zip(ids.into_iter()).collect()
}

fn compute_proof_opening_at_z_omega<MC: ManagerConfigs>(
    manager: &mut DeviceMemoryManager<Fr, MC>,
    constants: &ProverConstants<Fr>,
) -> Result<(), ProvingError> {
    manager.copy_from_device_to_free_device(PolyId::ZPerm, PolyId::W1, PolyForm::Monomial)?;
    manager.mul_constant(PolyId::W1, PolyForm::Monomial, constants.v[12])?;

    let ids = [PolyId::D, PolyId::S, PolyId::ZLookup, PolyId::T];
    for (i, id) in ids.into_iter().enumerate() {
        manager.add_assign_scaled(PolyId::W1, id, PolyForm::Monomial, constants.v[i + 13])?;
    }

    let mut zw = domain_generator::<Fr>(MC::FULL_SLOT_SIZE);
    zw.mul_assign(&constants.z);

    manager.devide_monomial_by_degree_one_monomial(PolyId::W1, zw)?;
    Ok(())
}

fn commit_proof_openings<C: Circuit<Bn256>, MC: ManagerConfigs>(
    manager: &mut DeviceMemoryManager<Fr, MC>,
    proof: &mut Proof<Bn256, C>,
) -> Result<(), ProvingError> {
    let opening_at_z_handle = manager.msm(PolyId::W)?;
    let opening_at_z_omega_handle = manager.msm(PolyId::W1)?;

    proof.opening_proof_at_z = opening_at_z_handle.get_result::<MC>(manager)?;
    proof.opening_proof_at_z_omega = opening_at_z_omega_handle.get_result::<MC>(manager)?;
    Ok(())
}

pub fn free_useless_round_5_slots<MC: ManagerConfigs>(
    manager: &mut DeviceMemoryManager<Fr, MC>,
) -> Result<(), ProvingError> {
    let poly_ids = [
        PolyId::Sigma(0),
        PolyId::Sigma(1),
        PolyId::Sigma(2),
        PolyId::QMainSelector,
        PolyId::QLookupSelector,
        PolyId::QTableType,
        PolyId::S,
        PolyId::T,
        PolyId::ZPerm,
        PolyId::ZLookup,
        PolyId::A,
        PolyId::B,
        PolyId::C,
        PolyId::D,
        PolyId::R,
    ];

    for id in poly_ids.iter() {
        manager.free_slot(*id, PolyForm::Monomial);
    }
    Ok(())
}