openvm_deferral_circuit/canonicity/
trace.rs1use std::array::from_fn;
2
3use openvm_stark_backend::p3_field::{PrimeCharacteristicRing, PrimeField32};
4
5use super::CanonicityAuxCols;
6use crate::utils::F_NUM_BYTES;
7
8pub struct CanonicityTraceGen;
10
11impl CanonicityTraceGen {
12 pub fn generate_subrow<F: PrimeField32>(
13 x_le: &[F; F_NUM_BYTES],
14 aux: &mut CanonicityAuxCols<F>,
15 ) -> u32 {
16 aux.diff_marker.fill(F::ZERO);
17 aux.diff_val = F::ZERO;
18 let x_be: [F; F_NUM_BYTES] = from_fn(|i| x_le[F_NUM_BYTES - 1 - i]);
19 let order_be = F::ORDER_U32.to_le_bytes().into_iter().rev();
20
21 let mut found = false;
22 let mut to_range_check = 0u32;
23
24 for (i, (&x, y)) in x_be.iter().zip(order_be).enumerate() {
25 let x_u32 = x.as_canonical_u32();
26 if !found && x_u32 != y as u32 {
27 debug_assert!(x_u32 < 256);
28 debug_assert!(y as u32 > x_u32);
29 let diff = y as u32 - x_u32;
30 aux.diff_marker[i] = F::ONE;
31 aux.diff_val = F::from_u32(diff);
32 to_range_check = diff - 1;
33 found = true;
34 }
35 }
36 debug_assert!(found);
37 to_range_check
38 }
39
40 pub fn clear_aux<F: PrimeCharacteristicRing>(aux: &mut CanonicityAuxCols<F>) {
41 aux.diff_marker.fill(F::ZERO);
42 aux.diff_val = F::ZERO;
43 }
44}