openvm_ecc_circuit/extension/
mod.rs

1use std::result::Result;
2
3use openvm_algebra_circuit::{Rv32ModularConfig, Rv32ModularConfigExecutor, Rv32ModularCpuBuilder};
4use openvm_circuit::{
5    arch::{
6        AirInventory, ChipInventoryError, InitFileGenerator, MatrixRecordArena, SystemConfig,
7        VmBuilder, VmChipComplex, VmProverExtension,
8    },
9    system::SystemChipInventory,
10};
11use openvm_circuit_derive::VmConfig;
12use openvm_stark_backend::{
13    config::{StarkGenericConfig, Val},
14    engine::StarkEngine,
15    p3_field::PrimeField32,
16    prover::cpu::{CpuBackend, CpuDevice},
17};
18use serde::{Deserialize, Serialize};
19
20mod weierstrass;
21pub use weierstrass::*;
22
23cfg_if::cfg_if! {
24    if #[cfg(feature = "cuda")] {
25        mod cuda;
26        mod hybrid;
27        pub use cuda::*;
28        pub use hybrid::*;
29        pub use {
30            EccHybridProverExt as EccProverExt,
31            Rv32WeierstrassHybridBuilder as Rv32WeierstrassBuilder,
32        };
33    } else {
34        pub use self::{
35            EccCpuProverExt as EccProverExt,
36            Rv32WeierstrassCpuBuilder as Rv32WeierstrassBuilder,
37        };
38    }
39}
40pub struct EccCpuProverExt;
41
42#[derive(Clone, Debug, VmConfig, Serialize, Deserialize)]
43pub struct Rv32WeierstrassConfig {
44    #[config(generics = true)]
45    pub modular: Rv32ModularConfig,
46    #[extension]
47    pub weierstrass: WeierstrassExtension,
48}
49
50impl Rv32WeierstrassConfig {
51    pub fn new(curves: Vec<CurveConfig>) -> Self {
52        let primes: Vec<_> = curves
53            .iter()
54            .flat_map(|c| [c.modulus.clone(), c.scalar.clone()])
55            .collect();
56        Self {
57            modular: Rv32ModularConfig::new(primes),
58            weierstrass: WeierstrassExtension::new(curves),
59        }
60    }
61}
62
63impl InitFileGenerator for Rv32WeierstrassConfig {
64    fn generate_init_file_contents(&self) -> Option<String> {
65        Some(format!(
66            "// This file is automatically generated by cargo openvm. Do not rename or edit.\n{}\n{}\n",
67            self.modular.modular.generate_moduli_init(),
68            self.weierstrass.generate_sw_init()
69        ))
70    }
71}
72
73#[derive(Clone)]
74pub struct Rv32WeierstrassCpuBuilder;
75
76impl<E, SC> VmBuilder<E> for Rv32WeierstrassCpuBuilder
77where
78    SC: StarkGenericConfig,
79    E: StarkEngine<SC = SC, PB = CpuBackend<SC>, PD = CpuDevice<SC>>,
80    Val<SC>: PrimeField32,
81{
82    type VmConfig = Rv32WeierstrassConfig;
83    type SystemChipInventory = SystemChipInventory<SC>;
84    type RecordArena = MatrixRecordArena<Val<SC>>;
85
86    fn create_chip_complex(
87        &self,
88        config: &Self::VmConfig,
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(
98            &EccCpuProverExt,
99            &config.weierstrass,
100            inventory,
101        )?;
102        Ok(chip_complex)
103    }
104}