openvm_ecc_circuit/weierstrass_chip/add_ne/
mod.rs1use std::{cell::RefCell, rc::Rc};
2
3use derive_more::derive::{Deref, DerefMut};
4use openvm_circuit::{
5 arch::*,
6 system::memory::{offline_checker::MemoryBridge, SharedMemoryHelper},
7};
8use openvm_circuit_derive::PreflightExecutor;
9use openvm_circuit_primitives::{
10 bitwise_op_lookup::{BitwiseOperationLookupBus, SharedBitwiseOperationLookupChip},
11 var_range::{SharedVariableRangeCheckerChip, VariableRangeCheckerBus},
12};
13use openvm_ecc_transpiler::Rv32WeierstrassOpcode;
14use openvm_instructions::riscv::RV32_CELL_BITS;
15use openvm_mod_circuit_builder::{
16 ExprBuilder, ExprBuilderConfig, FieldExpr, FieldExpressionCoreAir, FieldExpressionExecutor,
17 FieldExpressionFiller,
18};
19use openvm_rv32_adapters::{
20 Rv32VecHeapAdapterAir, Rv32VecHeapAdapterExecutor, Rv32VecHeapAdapterFiller,
21};
22
23use super::{WeierstrassAir, WeierstrassChip};
24
25#[cfg(feature = "cuda")]
26mod cuda;
27mod execution;
28
29#[cfg(feature = "cuda")]
30pub use cuda::*;
31
32pub fn ec_add_ne_expr(
35 config: ExprBuilderConfig, range_bus: VariableRangeCheckerBus,
37) -> FieldExpr {
38 config.check_valid();
39 let builder = ExprBuilder::new(config, range_bus.range_max_bits);
40 let builder = Rc::new(RefCell::new(builder));
41
42 let x1 = ExprBuilder::new_input(builder.clone());
43 let y1 = ExprBuilder::new_input(builder.clone());
44 let x2 = ExprBuilder::new_input(builder.clone());
45 let y2 = ExprBuilder::new_input(builder.clone());
46 let mut lambda = (y2 - y1.clone()) / (x2.clone() - x1.clone());
47 let mut x3 = lambda.square() - x1.clone() - x2;
48 x3.save_output();
49 let mut y3 = lambda * (x1 - x3.clone()) - y1;
50 y3.save_output();
51
52 let builder = (*builder).borrow().clone();
53 FieldExpr::new(builder, range_bus, true)
54}
55
56#[derive(Clone, PreflightExecutor, Deref, DerefMut)]
61pub struct EcAddNeExecutor<const BLOCKS: usize, const BLOCK_SIZE: usize>(
62 FieldExpressionExecutor<Rv32VecHeapAdapterExecutor<2, BLOCKS, BLOCKS, BLOCK_SIZE, BLOCK_SIZE>>,
63);
64
65fn gen_base_expr(
66 config: ExprBuilderConfig,
67 range_checker_bus: VariableRangeCheckerBus,
68) -> (FieldExpr, Vec<usize>) {
69 let expr = ec_add_ne_expr(config, range_checker_bus);
70
71 let local_opcode_idx = vec![
72 Rv32WeierstrassOpcode::EC_ADD_NE as usize,
73 Rv32WeierstrassOpcode::SETUP_EC_ADD_NE as usize,
74 ];
75
76 (expr, local_opcode_idx)
77}
78
79pub fn get_ec_addne_air<const BLOCKS: usize, const BLOCK_SIZE: usize>(
80 exec_bridge: ExecutionBridge,
81 mem_bridge: MemoryBridge,
82 config: ExprBuilderConfig,
83 range_checker_bus: VariableRangeCheckerBus,
84 bitwise_lookup_bus: BitwiseOperationLookupBus,
85 pointer_max_bits: usize,
86 offset: usize,
87) -> WeierstrassAir<2, BLOCKS, BLOCK_SIZE> {
88 let (expr, local_opcode_idx) = gen_base_expr(config, range_checker_bus);
89 WeierstrassAir::new(
90 Rv32VecHeapAdapterAir::new(
91 exec_bridge,
92 mem_bridge,
93 bitwise_lookup_bus,
94 pointer_max_bits,
95 ),
96 FieldExpressionCoreAir::new(expr.clone(), offset, local_opcode_idx.clone(), vec![]),
97 )
98}
99
100pub fn get_ec_addne_step<const BLOCKS: usize, const BLOCK_SIZE: usize>(
101 config: ExprBuilderConfig,
102 range_checker_bus: VariableRangeCheckerBus,
103 pointer_max_bits: usize,
104 offset: usize,
105) -> EcAddNeExecutor<BLOCKS, BLOCK_SIZE> {
106 let (expr, local_opcode_idx) = gen_base_expr(config, range_checker_bus);
107 EcAddNeExecutor(FieldExpressionExecutor::new(
108 Rv32VecHeapAdapterExecutor::new(pointer_max_bits),
109 expr,
110 offset,
111 local_opcode_idx,
112 vec![],
113 "EcAddNe",
114 ))
115}
116
117pub fn get_ec_addne_chip<F, const BLOCKS: usize, const BLOCK_SIZE: usize>(
118 config: ExprBuilderConfig,
119 mem_helper: SharedMemoryHelper<F>,
120 range_checker: SharedVariableRangeCheckerChip,
121 bitwise_lookup_chip: SharedBitwiseOperationLookupChip<RV32_CELL_BITS>,
122 pointer_max_bits: usize,
123) -> WeierstrassChip<F, 2, BLOCKS, BLOCK_SIZE> {
124 let (expr, local_opcode_idx) = gen_base_expr(config, range_checker.bus());
125 WeierstrassChip::new(
126 FieldExpressionFiller::new(
127 Rv32VecHeapAdapterFiller::new(pointer_max_bits, bitwise_lookup_chip),
128 expr,
129 local_opcode_idx,
130 vec![],
131 range_checker,
132 false,
133 ),
134 mem_helper,
135 )
136}