openvm_ecc_circuit/extension/
mod.rs1use 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}