openvm_algebra_circuit/extension/
mod.rs1use std::result::Result;
2
3use num_bigint::BigUint;
4use openvm_circuit::{
5 arch::{
6 AirInventory, ChipInventoryError, InitFileGenerator, MatrixRecordArena, SystemConfig,
7 VmBuilder, VmChipComplex, VmField, VmProverExtension,
8 },
9 system::{SystemChipInventory, SystemCpuBuilder, SystemExecutor},
10};
11use openvm_circuit_derive::VmConfig;
12use openvm_cpu_backend::{CpuBackend, CpuDevice};
13use openvm_rv32im_circuit::{
14 Rv32I, Rv32IExecutor, Rv32ImCpuProverExt, Rv32Io, Rv32IoExecutor, Rv32M, Rv32MExecutor,
15};
16use openvm_stark_backend::{StarkEngine, StarkProtocolConfig, Val};
17use serde::{Deserialize, Serialize};
18
19mod modular;
20pub use modular::*;
21mod fp2;
22pub use fp2::*;
23
24cfg_if::cfg_if! {
25 if #[cfg(feature = "cuda")] {
26 mod hybrid;
27 pub use hybrid::*;
28 pub use {
29 AlgebraHybridProverExt as AlgebraProverExt,
30 Rv32ModularHybridBuilder as Rv32ModularBuilder,
31 Rv32ModularWithFp2HybridBuilder as Rv32ModularWithFp2Builder,
32 };
33 } else {
34 pub use self::{
35 AlgebraCpuProverExt as AlgebraProverExt,
36 Rv32ModularCpuBuilder as Rv32ModularBuilder,
37 Rv32ModularWithFp2CpuBuilder as Rv32ModularWithFp2Builder,
38 };
39 }
40}
41
42pub struct AlgebraCpuProverExt;
43
44#[derive(Clone, Debug, VmConfig, Serialize, Deserialize)]
45pub struct Rv32ModularConfig {
46 #[config(executor = "SystemExecutor<F>")]
47 pub system: SystemConfig,
48 #[extension]
49 pub base: Rv32I,
50 #[extension]
51 pub mul: Rv32M,
52 #[extension]
53 pub io: Rv32Io,
54 #[extension]
55 pub modular: ModularExtension,
56}
57
58impl InitFileGenerator for Rv32ModularConfig {
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",
62 self.modular.generate_moduli_init()
63 ))
64 }
65}
66
67impl Rv32ModularConfig {
68 pub fn new(moduli: Vec<BigUint>) -> Self {
69 Self {
70 system: SystemConfig::default(),
71 base: Default::default(),
72 mul: Default::default(),
73 io: Default::default(),
74 modular: ModularExtension::new(moduli),
75 }
76 }
77}
78
79#[derive(Clone, Debug, VmConfig, Serialize, Deserialize)]
80pub struct Rv32ModularWithFp2Config {
81 #[config(generics = true)]
82 pub modular: Rv32ModularConfig,
83 #[extension]
84 pub fp2: Fp2Extension,
85}
86
87impl Rv32ModularWithFp2Config {
88 pub fn new(moduli_with_names: Vec<(String, BigUint)>) -> Self {
89 let moduli = moduli_with_names
90 .iter()
91 .map(|(_, modulus)| modulus.clone())
92 .collect();
93 Self {
94 modular: Rv32ModularConfig::new(moduli),
95 fp2: Fp2Extension::new(moduli_with_names),
96 }
97 }
98}
99
100impl InitFileGenerator for Rv32ModularWithFp2Config {
101 fn generate_init_file_contents(&self) -> Option<String> {
102 Some(format!(
103 "// This file is automatically generated by cargo openvm. Do not rename or edit.\n{}\n{}\n",
104 self.modular.modular.generate_moduli_init(),
105 self.fp2.generate_complex_init(&self.modular.modular)
106 ))
107 }
108}
109
110#[derive(Clone)]
111pub struct Rv32ModularCpuBuilder;
112
113impl<SC, E> VmBuilder<E> for Rv32ModularCpuBuilder
114where
115 SC: StarkProtocolConfig,
116 E: StarkEngine<SC = SC, PB = CpuBackend<SC>, PD = CpuDevice<SC>>,
117 Val<SC>: VmField,
118 SC::EF: Ord,
119{
120 type VmConfig = Rv32ModularConfig;
121 type SystemChipInventory = SystemChipInventory<SC>;
122 type RecordArena = MatrixRecordArena<Val<SC>>;
123
124 fn create_chip_complex(
125 &self,
126 config: &Rv32ModularConfig,
127 circuit: AirInventory<SC>,
128 device_ctx: &openvm_stark_backend::EngineDeviceCtx<E>,
129 ) -> Result<
130 VmChipComplex<SC, Self::RecordArena, E::PB, Self::SystemChipInventory>,
131 ChipInventoryError,
132 > {
133 let mut chip_complex = VmBuilder::<E>::create_chip_complex(
134 &SystemCpuBuilder,
135 &config.system,
136 circuit,
137 device_ctx,
138 )?;
139 let inventory = &mut chip_complex.inventory;
140 VmProverExtension::<E, _, _>::extend_prover(&Rv32ImCpuProverExt, &config.base, inventory)?;
141 VmProverExtension::<E, _, _>::extend_prover(&Rv32ImCpuProverExt, &config.mul, inventory)?;
142 VmProverExtension::<E, _, _>::extend_prover(&Rv32ImCpuProverExt, &config.io, inventory)?;
143 VmProverExtension::<E, _, _>::extend_prover(
144 &AlgebraCpuProverExt,
145 &config.modular,
146 inventory,
147 )?;
148 Ok(chip_complex)
149 }
150}
151
152#[derive(Clone)]
153pub struct Rv32ModularWithFp2CpuBuilder;
154
155impl<SC, E> VmBuilder<E> for Rv32ModularWithFp2CpuBuilder
156where
157 SC: StarkProtocolConfig,
158 E: StarkEngine<SC = SC, PB = CpuBackend<SC>, PD = CpuDevice<SC>>,
159 Val<SC>: VmField,
160 SC::EF: Ord,
161{
162 type VmConfig = Rv32ModularWithFp2Config;
163 type SystemChipInventory = SystemChipInventory<SC>;
164 type RecordArena = MatrixRecordArena<Val<SC>>;
165
166 fn create_chip_complex(
167 &self,
168 config: &Rv32ModularWithFp2Config,
169 circuit: AirInventory<SC>,
170 device_ctx: &openvm_stark_backend::EngineDeviceCtx<E>,
171 ) -> Result<
172 VmChipComplex<SC, Self::RecordArena, E::PB, Self::SystemChipInventory>,
173 ChipInventoryError,
174 > {
175 let mut chip_complex = VmBuilder::<E>::create_chip_complex(
176 &Rv32ModularCpuBuilder,
177 &config.modular,
178 circuit,
179 device_ctx,
180 )?;
181 let inventory = &mut chip_complex.inventory;
182 VmProverExtension::<E, _, _>::extend_prover(&AlgebraCpuProverExt, &config.fp2, inventory)?;
183 Ok(chip_complex)
184 }
185}