Skip to main content

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