openvm_ecc_circuit/weierstrass_chip/
mod.rs

1mod add_ne;
2mod double;
3
4use std::sync::Arc;
5
6pub use add_ne::*;
7pub use double::*;
8
9#[cfg(test)]
10mod tests;
11
12use std::sync::Mutex;
13
14use num_bigint::BigUint;
15use openvm_circuit::{arch::VmChipWrapper, system::memory::OfflineMemory};
16use openvm_circuit_derive::InstructionExecutor;
17use openvm_circuit_primitives::var_range::SharedVariableRangeCheckerChip;
18use openvm_circuit_primitives_derive::{Chip, ChipUsageGetter};
19use openvm_ecc_transpiler::Rv32WeierstrassOpcode;
20use openvm_mod_circuit_builder::{ExprBuilderConfig, FieldExpressionCoreChip};
21use openvm_rv32_adapters::Rv32VecHeapAdapterChip;
22use openvm_stark_backend::p3_field::PrimeField32;
23
24/// BLOCK_SIZE: how many cells do we read at a time, must be a power of 2.
25/// BLOCKS: how many blocks do we need to represent one input or output
26/// For example, for bls12_381, BLOCK_SIZE = 16, each element has 3 blocks and with two elements per input AffinePoint, BLOCKS = 6.
27/// For secp256k1, BLOCK_SIZE = 32, BLOCKS = 2.
28#[derive(Chip, ChipUsageGetter, InstructionExecutor)]
29pub struct EcAddNeChip<F: PrimeField32, const BLOCKS: usize, const BLOCK_SIZE: usize>(
30    pub  VmChipWrapper<
31        F,
32        Rv32VecHeapAdapterChip<F, 2, BLOCKS, BLOCKS, BLOCK_SIZE, BLOCK_SIZE>,
33        FieldExpressionCoreChip,
34    >,
35);
36
37impl<F: PrimeField32, const BLOCKS: usize, const BLOCK_SIZE: usize>
38    EcAddNeChip<F, BLOCKS, BLOCK_SIZE>
39{
40    pub fn new(
41        adapter: Rv32VecHeapAdapterChip<F, 2, BLOCKS, BLOCKS, BLOCK_SIZE, BLOCK_SIZE>,
42        config: ExprBuilderConfig,
43        offset: usize,
44        range_checker: SharedVariableRangeCheckerChip,
45        offline_memory: Arc<Mutex<OfflineMemory<F>>>,
46    ) -> Self {
47        let expr = ec_add_ne_expr(config, range_checker.bus());
48        let core = FieldExpressionCoreChip::new(
49            expr,
50            offset,
51            vec![
52                Rv32WeierstrassOpcode::EC_ADD_NE as usize,
53                Rv32WeierstrassOpcode::SETUP_EC_ADD_NE as usize,
54            ],
55            vec![],
56            range_checker,
57            "EcAddNe",
58            false,
59        );
60        Self(VmChipWrapper::new(adapter, core, offline_memory))
61    }
62}
63
64#[derive(Chip, ChipUsageGetter, InstructionExecutor)]
65pub struct EcDoubleChip<F: PrimeField32, const BLOCKS: usize, const BLOCK_SIZE: usize>(
66    pub  VmChipWrapper<
67        F,
68        Rv32VecHeapAdapterChip<F, 1, BLOCKS, BLOCKS, BLOCK_SIZE, BLOCK_SIZE>,
69        FieldExpressionCoreChip,
70    >,
71);
72
73impl<F: PrimeField32, const BLOCKS: usize, const BLOCK_SIZE: usize>
74    EcDoubleChip<F, BLOCKS, BLOCK_SIZE>
75{
76    pub fn new(
77        adapter: Rv32VecHeapAdapterChip<F, 1, BLOCKS, BLOCKS, BLOCK_SIZE, BLOCK_SIZE>,
78        range_checker: SharedVariableRangeCheckerChip,
79        config: ExprBuilderConfig,
80        offset: usize,
81        a: BigUint,
82        offline_memory: Arc<Mutex<OfflineMemory<F>>>,
83    ) -> Self {
84        let expr = ec_double_ne_expr(config, range_checker.bus(), a);
85        let core = FieldExpressionCoreChip::new(
86            expr,
87            offset,
88            vec![
89                Rv32WeierstrassOpcode::EC_DOUBLE as usize,
90                Rv32WeierstrassOpcode::SETUP_EC_DOUBLE as usize,
91            ],
92            vec![],
93            range_checker,
94            "EcDouble",
95            true,
96        );
97        Self(VmChipWrapper::new(adapter, core, offline_memory))
98    }
99}