1use alloc::{boxed::Box, vec, vec::Vec};
3
4use ark_ff::PrimeField;
5use core::array;
6use num_bigint::BigUint;
7use num_integer::Integer;
8use o1_utils::{field_helpers::BigUintFieldHelpers, FieldHelpers, ForeignElement};
9
10use crate::{
11 circuits::{
12 polynomial::COLUMNS,
13 polynomials::foreign_field_common::{BigUintForeignFieldHelpers, LIMB_BITS},
14 witness::{init_row, CopyBitsCell, CopyCell, VariableCell, Variables, WitnessCell},
15 },
16 variable_map, variables,
17};
18
19fn layout<F: PrimeField>() -> [Vec<Box<dyn WitnessCell<F>>>; 4] {
31 [
32 range_check_0_row("v0", 0),
34 range_check_0_row("v1", 1),
36 vec![
38 VariableCell::create("v2"),
39 VariableCell::create("v12"), CopyBitsCell::create(2, 0, 86, 88),
43 CopyBitsCell::create(2, 0, 74, 86),
45 CopyBitsCell::create(2, 0, 62, 74),
46 CopyBitsCell::create(2, 0, 50, 62),
47 CopyBitsCell::create(2, 0, 38, 50),
48 CopyBitsCell::create(2, 0, 36, 38),
50 CopyBitsCell::create(2, 0, 34, 36),
51 CopyBitsCell::create(2, 0, 32, 34),
52 CopyBitsCell::create(2, 0, 30, 32),
53 CopyBitsCell::create(2, 0, 28, 30),
54 CopyBitsCell::create(2, 0, 26, 28),
55 CopyBitsCell::create(2, 0, 24, 26),
56 CopyBitsCell::create(2, 0, 22, 24),
57 ],
58 vec![
60 CopyBitsCell::create(2, 0, 20, 22),
61 CopyBitsCell::create(2, 0, 18, 20),
64 CopyBitsCell::create(2, 0, 16, 18),
65 CopyCell::create(0, 1),
67 CopyCell::create(0, 2),
68 CopyCell::create(1, 1),
69 CopyCell::create(1, 2),
70 CopyBitsCell::create(2, 0, 14, 16),
72 CopyBitsCell::create(2, 0, 12, 14),
73 CopyBitsCell::create(2, 0, 10, 12),
74 CopyBitsCell::create(2, 0, 8, 10),
75 CopyBitsCell::create(2, 0, 6, 8),
76 CopyBitsCell::create(2, 0, 4, 6),
77 CopyBitsCell::create(2, 0, 2, 4),
78 CopyBitsCell::create(2, 0, 0, 2),
79 ],
80 ]
81}
82
83pub fn range_check_0_row<F: PrimeField>(
85 limb_name: &'static str,
86 row: usize,
87) -> Vec<Box<dyn WitnessCell<F>>> {
88 vec![
89 VariableCell::create(limb_name),
90 CopyBitsCell::create(row, 0, 76, 88),
96 CopyBitsCell::create(row, 0, 64, 76),
97 CopyBitsCell::create(row, 0, 52, 64),
99 CopyBitsCell::create(row, 0, 40, 52),
100 CopyBitsCell::create(row, 0, 28, 40),
101 CopyBitsCell::create(row, 0, 16, 28),
102 CopyBitsCell::create(row, 0, 14, 16),
104 CopyBitsCell::create(row, 0, 12, 14),
105 CopyBitsCell::create(row, 0, 10, 12),
106 CopyBitsCell::create(row, 0, 8, 10),
107 CopyBitsCell::create(row, 0, 6, 8),
108 CopyBitsCell::create(row, 0, 4, 6),
109 CopyBitsCell::create(row, 0, 2, 4),
110 CopyBitsCell::create(row, 0, 0, 2),
111 ]
112}
113
114pub fn create_multi<F: PrimeField>(v0: F, v1: F, v2: F) -> [Vec<F>; COLUMNS] {
116 let layout = layout();
117 let mut witness: [Vec<F>; COLUMNS] = array::from_fn(|_| vec![F::zero(); 4]);
118
119 init_row(&mut witness, 0, 0, &layout, &variables!(v0));
120 init_row(&mut witness, 0, 1, &layout, &variables!(v1));
121 init_row(
122 &mut witness,
123 0,
124 2,
125 &layout,
126 &variable_map!("v2" => v2, "v12" => F::zero()),
127 );
128 init_row(&mut witness, 0, 3, &layout, &variables!());
129
130 witness
131}
132
133pub fn create_multi_compact<F: PrimeField>(v01: F, v2: F) -> [Vec<F>; COLUMNS] {
136 let layout = layout();
137 let mut witness: [Vec<F>; COLUMNS] = array::from_fn(|_| vec![F::zero(); 4]);
138
139 let (v1, v0) = v01.to_biguint().div_rem(&BigUint::two_to_limb());
140 let v0: F = v0.to_field().expect("failed to convert to field element");
141 let v1: F = v1.to_field().expect("failed to convert to field element");
142
143 init_row(&mut witness, 0, 0, &layout, &variable_map!("v0" => v2));
144 init_row(&mut witness, 0, 1, &layout, &variable_map!("v1" => v0));
145
146 init_row(
147 &mut witness,
148 0,
149 2,
150 &layout,
151 &variable_map!("v2" => v1, "v12" => v01),
152 );
153 init_row(&mut witness, 0, 3, &layout, &variables!());
154
155 witness
156}
157
158pub fn create_multi_limbs<F: PrimeField>(limbs: &[F; 3]) -> [Vec<F>; COLUMNS] {
160 create_multi(limbs[0], limbs[1], limbs[2])
161}
162
163pub fn create_multi_compact_limbs<F: PrimeField>(limbs: &[F; 2]) -> [Vec<F>; COLUMNS] {
165 create_multi_compact(limbs[0], limbs[1])
166}
167
168pub fn create<F: PrimeField>(v0: F) -> [Vec<F>; COLUMNS] {
171 let layout = vec![range_check_0_row("v0", 0)];
172 let mut witness: [Vec<F>; COLUMNS] = array::from_fn(|_| vec![F::zero()]);
173
174 init_row(&mut witness, 0, 0, &layout, &variables!(v0));
175
176 witness
177}
178
179pub fn extend_multi<F: PrimeField>(witness: &mut [Vec<F>; COLUMNS], v0: F, v1: F, v2: F) {
181 let limbs_witness = create_multi(v0, v1, v2);
182 for col in 0..COLUMNS {
183 witness[col].extend(limbs_witness[col].iter())
184 }
185}
186
187pub fn extend_multi_compact<F: PrimeField>(witness: &mut [Vec<F>; COLUMNS], v01: F, v2: F) {
190 let limbs_witness = create_multi_compact(v01, v2);
191 for col in 0..COLUMNS {
192 witness[col].extend(limbs_witness[col].iter())
193 }
194}
195
196pub fn extend_multi_limbs<F: PrimeField>(witness: &mut [Vec<F>; COLUMNS], limbs: &[F; 3]) {
198 let limbs_witness = create_multi_limbs(limbs);
199 for col in 0..COLUMNS {
200 witness[col].extend(limbs_witness[col].iter())
201 }
202}
203
204pub fn extend_multi_compact_limbs<F: PrimeField>(witness: &mut [Vec<F>; COLUMNS], limbs: &[F; 2]) {
206 let limbs_witness = create_multi_compact_limbs(limbs);
207 for col in 0..COLUMNS {
208 witness[col].extend(limbs_witness[col].iter())
209 }
210}
211
212pub fn extend_multi_from_fe<F: PrimeField>(
214 witness: &mut [Vec<F>; COLUMNS],
215 fe: &ForeignElement<F, LIMB_BITS, 3>,
216) {
217 extend_multi(witness, fe.limbs[0], fe.limbs[1], fe.limbs[2]);
218}
219
220pub fn extend<F: PrimeField>(witness: &mut [Vec<F>; COLUMNS], fe: F) {
222 let limbs_witness = create(fe);
223 for col in 0..COLUMNS {
224 witness[col].extend(limbs_witness[col].iter())
225 }
226}
227
228pub fn extend_single<F: PrimeField>(witness: &mut [Vec<F>; COLUMNS], elem: F) {
230 let single_wit = create(elem);
231 for col in 0..COLUMNS {
232 witness[col].extend(single_wit[col].iter())
233 }
234}