openvm_pairing_circuit/
config.rs

1use std::result::Result;
2
3use openvm_algebra_circuit::{
4    AlgebraCpuProverExt, Fp2Extension, Fp2ExtensionExecutor, Rv32ModularConfig,
5    Rv32ModularConfigExecutor, Rv32ModularCpuBuilder,
6};
7use openvm_circuit::{
8    arch::{
9        AirInventory, ChipInventoryError, InitFileGenerator, MatrixRecordArena, SystemConfig,
10        VmBuilder, VmChipComplex, VmProverExtension,
11    },
12    system::SystemChipInventory,
13};
14use openvm_circuit_derive::VmConfig;
15use openvm_ecc_circuit::{EccCpuProverExt, WeierstrassExtension, WeierstrassExtensionExecutor};
16use openvm_stark_backend::{
17    config::{StarkGenericConfig, Val},
18    engine::StarkEngine,
19    p3_field::PrimeField32,
20    prover::cpu::{CpuBackend, CpuDevice},
21};
22use serde::{Deserialize, Serialize};
23
24use super::*;
25
26#[derive(Clone, Debug, VmConfig, Serialize, Deserialize)]
27pub struct Rv32PairingConfig {
28    #[config(generics = true)]
29    pub modular: Rv32ModularConfig,
30    #[extension]
31    pub fp2: Fp2Extension,
32    #[extension]
33    pub weierstrass: WeierstrassExtension,
34    #[extension(generics = true)]
35    pub pairing: PairingExtension,
36}
37
38impl Rv32PairingConfig {
39    pub fn new(curves: Vec<PairingCurve>, complex_struct_names: Vec<String>) -> Self {
40        let modulus_primes: Vec<_> = curves
41            .iter()
42            .map(|c| c.curve_config().modulus.clone())
43            .collect();
44        let mut modulus_and_scalar_primes = modulus_primes.clone();
45        modulus_and_scalar_primes.extend(curves.iter().map(|c| c.curve_config().scalar.clone()));
46        Self {
47            modular: Rv32ModularConfig::new(modulus_and_scalar_primes),
48            fp2: Fp2Extension::new(
49                complex_struct_names
50                    .into_iter()
51                    .zip(modulus_primes)
52                    .collect(),
53            ),
54            weierstrass: WeierstrassExtension::new(
55                curves.iter().map(|c| c.curve_config()).collect(),
56            ),
57            pairing: PairingExtension::new(curves),
58        }
59    }
60}
61
62impl InitFileGenerator for Rv32PairingConfig {
63    fn generate_init_file_contents(&self) -> Option<String> {
64        Some(format!(
65            "// This file is automatically generated by cargo openvm. Do not rename or edit.\n{}\n{}\n{}\n",
66            self.modular.modular.generate_moduli_init(),
67            self.fp2.generate_complex_init(&self.modular.modular),
68            self.weierstrass.generate_sw_init()
69        ))
70    }
71}
72
73#[derive(Clone)]
74pub struct Rv32PairingCpuBuilder;
75
76impl<E, SC> VmBuilder<E> for Rv32PairingCpuBuilder
77where
78    SC: StarkGenericConfig,
79    E: StarkEngine<SC = SC, PB = CpuBackend<SC>, PD = CpuDevice<SC>>,
80    Val<SC>: PrimeField32,
81{
82    type VmConfig = Rv32PairingConfig;
83    type SystemChipInventory = SystemChipInventory<SC>;
84    type RecordArena = MatrixRecordArena<Val<SC>>;
85
86    fn create_chip_complex(
87        &self,
88        config: &Rv32PairingConfig,
89        circuit: AirInventory<SC>,
90    ) -> Result<
91        VmChipComplex<SC, Self::RecordArena, E::PB, Self::SystemChipInventory>,
92        ChipInventoryError,
93    > {
94        let mut chip_complex =
95            VmBuilder::<E>::create_chip_complex(&Rv32ModularCpuBuilder, &config.modular, circuit)?;
96        let inventory = &mut chip_complex.inventory;
97        VmProverExtension::<E, _, _>::extend_prover(&AlgebraCpuProverExt, &config.fp2, inventory)?;
98        VmProverExtension::<E, _, _>::extend_prover(
99            &EccCpuProverExt,
100            &config.weierstrass,
101            inventory,
102        )?;
103        VmProverExtension::<E, _, _>::extend_prover(&PairingProverExt, &config.pairing, inventory)?;
104        Ok(chip_complex)
105    }
106}