1use anyhow::Result;
5use binius_compute::ComputeHolder;
6use binius_core::{constraint_system::channel::Boundary, fiat_shamir::HasherChallenger};
7use binius_fast_compute::layer::FastCpuLayerHolder;
8use binius_field::{
9 BinaryField128bPolyval, PackedField, PackedFieldIndexable, TowerField,
10 as_packed_field::{PackScalar, PackedType},
11 linear_transformation::PackedTransformationFactory,
12 tower::CanonicalTowerFamily,
13 underlier::UnderlierType,
14};
15use binius_hash::groestl::{Groestl256, Groestl256ByteCompression};
16use binius_utils::env::boolean_env_flag_set;
17
18use super::{
19 B1, B8, B16, B32, B64,
20 constraint_system::ConstraintSystem,
21 table::TableId,
22 witness::{TableFiller, TableWitnessSegment},
23};
24use crate::builder::{B128, WitnessIndex};
25
26#[allow(clippy::type_complexity)]
31pub struct ClosureFiller<'a, P, Event>
32where
33 P: PackedField,
34 P::Scalar: TowerField,
35{
36 table_id: TableId,
37 fill:
38 Box<dyn for<'b> Fn(&'b [Event], &'b mut TableWitnessSegment<P>) -> Result<()> + Sync + 'a>,
39}
40
41impl<'a, P: PackedField<Scalar: TowerField>, Event> ClosureFiller<'a, P, Event> {
42 pub fn new(
43 table_id: TableId,
44 fill: impl for<'b> Fn(&'b [Event], &'b mut TableWitnessSegment<P>) -> Result<()> + Sync + 'a,
45 ) -> Self {
46 Self {
47 table_id,
48 fill: Box::new(fill),
49 }
50 }
51}
52
53impl<P: PackedField<Scalar: TowerField>, Event: Clone> TableFiller<P>
54 for ClosureFiller<'_, P, Event>
55{
56 type Event = Event;
57
58 fn id(&self) -> TableId {
59 self.table_id
60 }
61
62 fn fill(&self, rows: &[Event], witness: &mut TableWitnessSegment<P>) -> Result<()> {
63 (*self.fill)(rows, witness)
64 }
65}
66
67pub fn validate_system_witness<U>(
69 cs: &ConstraintSystem<B128>,
70 witness: WitnessIndex<PackedType<U, B128>>,
71 boundaries: Vec<Boundary<B128>>,
72) where
73 U: UnderlierType
74 + PackScalar<B1>
75 + PackScalar<B8>
76 + PackScalar<B16>
77 + PackScalar<B32>
78 + PackScalar<B64>
79 + PackScalar<B128>
80 + PackScalar<BinaryField128bPolyval>,
81 PackedType<U, B128>:
82 PackedFieldIndexable + PackedTransformationFactory<PackedType<U, BinaryField128bPolyval>>,
83 PackedType<U, BinaryField128bPolyval>: PackedTransformationFactory<PackedType<U, B128>>,
84{
85 const TEST_PROVE_VERIFY_ENV_NAME: &str = "BINIUS_M3_TEST_PROVE_VERIFY";
86 validate_system_witness_with_prove_verify::<U>(
87 cs,
88 witness,
89 boundaries,
90 boolean_env_flag_set(TEST_PROVE_VERIFY_ENV_NAME),
91 )
92}
93
94pub fn validate_system_witness_with_prove_verify<U>(
95 cs: &ConstraintSystem<B128>,
96 witness: WitnessIndex<PackedType<U, B128>>,
97 boundaries: Vec<Boundary<B128>>,
98 prove_verify: bool,
99) where
100 U: UnderlierType
101 + PackScalar<B1>
102 + PackScalar<B8>
103 + PackScalar<B16>
104 + PackScalar<B32>
105 + PackScalar<B64>
106 + PackScalar<B128>
107 + PackScalar<BinaryField128bPolyval>,
108 PackedType<U, B128>:
109 PackedFieldIndexable + PackedTransformationFactory<PackedType<U, BinaryField128bPolyval>>,
110 PackedType<U, BinaryField128bPolyval>: PackedTransformationFactory<PackedType<U, B128>>,
111{
112 let table_sizes = witness.table_sizes();
113 let ccs = cs.compile().unwrap();
114 let witness = witness.into_multilinear_extension_index();
115
116 binius_core::constraint_system::validate::validate_witness(
117 &ccs,
118 &boundaries,
119 &table_sizes,
120 &witness,
121 )
122 .unwrap();
123
124 if prove_verify {
125 const LOG_INV_RATE: usize = 1;
126 const SECURITY_BITS: usize = 100;
127
128 let mut compute_holder =
129 FastCpuLayerHolder::<CanonicalTowerFamily, PackedType<U, B128>>::new(1 << 16, 1 << 24);
130
131 let ccs_digest = ccs.digest::<Groestl256>();
132 let proof = binius_core::constraint_system::prove::<
133 _,
134 U,
135 CanonicalTowerFamily,
136 Groestl256,
137 Groestl256ByteCompression,
138 HasherChallenger<Groestl256>,
139 _,
140 _,
141 _,
142 >(
143 &mut compute_holder.to_data(),
144 &ccs,
145 LOG_INV_RATE,
146 SECURITY_BITS,
147 &ccs_digest,
148 &boundaries,
149 &table_sizes,
150 witness,
151 &binius_hal::make_portable_backend(),
152 )
153 .unwrap();
154
155 binius_core::constraint_system::verify::<
156 U,
157 CanonicalTowerFamily,
158 Groestl256,
159 Groestl256ByteCompression,
160 HasherChallenger<Groestl256>,
161 >(&ccs, LOG_INV_RATE, SECURITY_BITS, &ccs_digest, &boundaries, proof)
162 .unwrap();
163 }
164}