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