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