binius_circuits/
unconstrained.rs

1// Copyright 2024-2025 Irreducible Inc.
2use binius_core::oracle::OracleId;
3use binius_field::{as_packed_field::PackScalar, ExtensionField, TowerField};
4use binius_maybe_rayon::prelude::*;
5use bytemuck::Pod;
6use rand::{thread_rng, Rng};
7
8use crate::builder::{
9	types::{F, U},
10	ConstraintSystemBuilder,
11};
12
13pub fn unconstrained<FS>(
14	builder: &mut ConstraintSystemBuilder,
15	name: impl ToString,
16	log_size: usize,
17) -> Result<OracleId, anyhow::Error>
18where
19	U: PackScalar<FS> + Pod,
20	F: TowerField + ExtensionField<FS>,
21	FS: TowerField,
22{
23	let rng = builder.add_committed(name, log_size, FS::TOWER_LEVEL);
24
25	if let Some(witness) = builder.witness() {
26		witness
27			.new_column::<FS>(rng)
28			.as_mut_slice::<u8>()
29			.into_par_iter()
30			.for_each_init(thread_rng, |rng, data| {
31				*data = rng.gen();
32			});
33	}
34
35	Ok(rng)
36}
37
38// Same as 'unconstrained' but uses some pre-defined values instead of a random ones
39pub fn fixed_u32<FS>(
40	builder: &mut ConstraintSystemBuilder,
41	name: impl ToString,
42	log_size: usize,
43	values: Vec<u32>,
44) -> Result<OracleId, anyhow::Error>
45where
46	U: PackScalar<FS> + Pod,
47	F: TowerField + ExtensionField<FS>,
48	FS: TowerField,
49{
50	let fixed = builder.add_committed(name, log_size, FS::TOWER_LEVEL);
51
52	if let Some(witness) = builder.witness() {
53		witness
54			.new_column::<FS>(fixed)
55			.as_mut_slice::<u32>()
56			.into_par_iter()
57			.zip(values.into_par_iter())
58			.for_each(|(data, value)| {
59				*data = value;
60			});
61	}
62
63	Ok(fixed)
64}