openvm_pairing_circuit/pairing_chip/line/
evaluate_line.rs
1use std::{
2 cell::RefCell,
3 rc::Rc,
4 sync::{Arc, Mutex},
5};
6
7use openvm_algebra_circuit::Fp2;
8use openvm_circuit::{arch::VmChipWrapper, system::memory::OfflineMemory};
9use openvm_circuit_derive::InstructionExecutor;
10use openvm_circuit_primitives::var_range::{
11 SharedVariableRangeCheckerChip, VariableRangeCheckerBus,
12};
13use openvm_circuit_primitives_derive::{Chip, ChipUsageGetter};
14use openvm_mod_circuit_builder::{
15 ExprBuilder, ExprBuilderConfig, FieldExpr, FieldExpressionCoreChip,
16};
17use openvm_pairing_transpiler::PairingOpcode;
18use openvm_rv32_adapters::Rv32VecHeapTwoReadsAdapterChip;
19use openvm_stark_backend::p3_field::PrimeField32;
20
21#[derive(Chip, ChipUsageGetter, InstructionExecutor)]
24pub struct EvaluateLineChip<
25 F: PrimeField32,
26 const INPUT_BLOCKS1: usize,
27 const INPUT_BLOCKS2: usize,
28 const OUTPUT_BLOCKS: usize,
29 const BLOCK_SIZE: usize,
30>(
31 pub VmChipWrapper<
32 F,
33 Rv32VecHeapTwoReadsAdapterChip<
34 F,
35 INPUT_BLOCKS1,
36 INPUT_BLOCKS2,
37 OUTPUT_BLOCKS,
38 BLOCK_SIZE,
39 BLOCK_SIZE,
40 >,
41 FieldExpressionCoreChip,
42 >,
43);
44
45impl<
46 F: PrimeField32,
47 const INPUT_BLOCKS1: usize,
48 const INPUT_BLOCKS2: usize,
49 const OUTPUT_BLOCKS: usize,
50 const BLOCK_SIZE: usize,
51 > EvaluateLineChip<F, INPUT_BLOCKS1, INPUT_BLOCKS2, OUTPUT_BLOCKS, BLOCK_SIZE>
52{
53 pub fn new(
54 adapter: Rv32VecHeapTwoReadsAdapterChip<
55 F,
56 INPUT_BLOCKS1,
57 INPUT_BLOCKS2,
58 OUTPUT_BLOCKS,
59 BLOCK_SIZE,
60 BLOCK_SIZE,
61 >,
62 config: ExprBuilderConfig,
63 offset: usize,
64 range_checker: SharedVariableRangeCheckerChip,
65 offline_memory: Arc<Mutex<OfflineMemory<F>>>,
66 ) -> Self {
67 let expr = evaluate_line_expr(config, range_checker.bus());
68 let core = FieldExpressionCoreChip::new(
69 expr,
70 offset,
71 vec![PairingOpcode::EVALUATE_LINE as usize],
72 vec![],
73 range_checker,
74 "EvaluateLine",
75 false,
76 );
77 Self(VmChipWrapper::new(adapter, core, offline_memory))
78 }
79}
80
81pub fn evaluate_line_expr(
82 config: ExprBuilderConfig,
83 range_bus: VariableRangeCheckerBus,
84) -> FieldExpr {
85 config.check_valid();
86 let builder = ExprBuilder::new(config, range_bus.range_max_bits);
87 let builder = Rc::new(RefCell::new(builder));
88
89 let mut uneval_b = Fp2::new(builder.clone());
90 let mut uneval_c = Fp2::new(builder.clone());
91
92 let mut x_over_y = ExprBuilder::new_input(builder.clone());
93 let mut y_inv = ExprBuilder::new_input(builder.clone());
94
95 let mut b = uneval_b.scalar_mul(&mut x_over_y);
96 let mut c = uneval_c.scalar_mul(&mut y_inv);
97 b.save_output();
98 c.save_output();
99
100 let builder = builder.borrow().clone();
101 FieldExpr::new(builder, range_bus, false)
102}