binius_circuits/
transparent.rs

1// Copyright 2024-2025 Irreducible Inc.
2
3use binius_core::{oracle::OracleId, transparent};
4use binius_field::{
5	as_packed_field::{PackScalar, PackedType},
6	BinaryField1b, ExtensionField, PackedField, TowerField,
7};
8
9use crate::builder::{
10	types::{F, U},
11	ConstraintSystemBuilder,
12};
13
14pub fn step_down(
15	builder: &mut ConstraintSystemBuilder,
16	name: impl ToString,
17	log_size: usize,
18	index: usize,
19) -> Result<OracleId, anyhow::Error> {
20	let step_down = transparent::step_down::StepDown::new(log_size, index)?;
21	let id = builder.add_transparent(name, step_down.clone())?;
22	if let Some(witness) = builder.witness() {
23		step_down.populate(witness.new_column::<BinaryField1b>(id).packed());
24	}
25	Ok(id)
26}
27
28pub fn step_up(
29	builder: &mut ConstraintSystemBuilder,
30	name: impl ToString,
31	log_size: usize,
32	index: usize,
33) -> Result<OracleId, anyhow::Error> {
34	let step_up = transparent::step_up::StepUp::new(log_size, index)?;
35	let id = builder.add_transparent(name, step_up.clone())?;
36	if let Some(witness) = builder.witness() {
37		step_up.populate(witness.new_column::<BinaryField1b>(id).packed());
38	}
39	Ok(id)
40}
41
42pub fn constant<FS>(
43	builder: &mut ConstraintSystemBuilder,
44	name: impl ToString,
45	log_size: usize,
46	value: FS,
47) -> Result<OracleId, anyhow::Error>
48where
49	U: PackScalar<FS>,
50	F: TowerField + ExtensionField<FS>,
51	FS: TowerField,
52{
53	let poly = transparent::constant::Constant::new(log_size, value);
54	let id = builder.add_transparent(name, poly)?;
55	if let Some(witness) = builder.witness() {
56		witness
57			.new_column::<FS>(id)
58			.packed()
59			.fill(<PackedType<U, FS>>::broadcast(value));
60	}
61	Ok(id)
62}
63
64pub fn make_transparent<FS>(
65	builder: &mut ConstraintSystemBuilder,
66	name: impl ToString,
67	values: &[FS],
68) -> Result<OracleId, anyhow::Error>
69where
70	U: PackScalar<FS>,
71	F: TowerField + ExtensionField<FS>,
72	FS: TowerField,
73{
74	let packed_length = values.len().div_ceil(PackedType::<U, FS>::WIDTH);
75	let mut packed_values = vec![PackedType::<U, FS>::default(); packed_length];
76	for (i, value) in values.iter().enumerate() {
77		binius_field::packed::set_packed_slice(&mut packed_values, i, *value);
78	}
79
80	use binius_core::transparent::multilinear_extension::MultilinearExtensionTransparent;
81	let mle = MultilinearExtensionTransparent::<_, PackedType<U, F>, _>::from_values(
82		packed_values.clone(),
83	)?;
84
85	let oracle = builder.add_transparent(name, mle)?;
86
87	if let Some(witness) = builder.witness() {
88		let mut entry_builder = witness.new_column::<FS>(oracle);
89		entry_builder.packed().copy_from_slice(&packed_values);
90	}
91
92	Ok(oracle)
93}