binius_circuits/
transparent.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// Copyright 2024-2025 Irreducible Inc.

use binius_core::{oracle::OracleId, transparent};
use binius_field::{
	as_packed_field::{PackScalar, PackedType},
	underlier::UnderlierType,
	BinaryField1b, ExtensionField, PackedField, TowerField,
};
use bytemuck::Pod;

use crate::builder::ConstraintSystemBuilder;

pub fn step_down<U, F>(
	builder: &mut ConstraintSystemBuilder<U, F>,
	name: impl ToString,
	log_size: usize,
	index: usize,
) -> Result<OracleId, anyhow::Error>
where
	U: UnderlierType + PackScalar<F> + PackScalar<BinaryField1b> + Pod,
	F: TowerField,
{
	let step_down = transparent::step_down::StepDown::new(log_size, index)?;
	let id = builder.add_transparent(name, step_down.clone())?;
	if let Some(witness) = builder.witness() {
		step_down.populate(witness.new_column::<BinaryField1b>(id).packed());
	}
	Ok(id)
}

pub fn step_up<U, F>(
	builder: &mut ConstraintSystemBuilder<U, F>,
	name: impl ToString,
	log_size: usize,
	index: usize,
) -> Result<OracleId, anyhow::Error>
where
	U: UnderlierType + PackScalar<F> + PackScalar<BinaryField1b> + Pod,
	F: TowerField,
{
	let step_up = transparent::step_up::StepUp::new(log_size, index)?;
	let id = builder.add_transparent(name, step_up.clone())?;
	if let Some(witness) = builder.witness() {
		step_up.populate(witness.new_column::<BinaryField1b>(id).packed());
	}
	Ok(id)
}

pub fn constant<U, F, FS>(
	builder: &mut ConstraintSystemBuilder<U, F>,
	name: impl ToString,
	log_size: usize,
	value: FS,
) -> Result<OracleId, anyhow::Error>
where
	U: UnderlierType + PackScalar<F> + PackScalar<FS>,
	F: TowerField + ExtensionField<FS>,
	FS: TowerField,
{
	let poly = transparent::constant::Constant::new(log_size, value);
	let id = builder.add_transparent(name, poly)?;
	if let Some(witness) = builder.witness() {
		witness
			.new_column::<FS>(id)
			.packed()
			.fill(<PackedType<U, FS>>::broadcast(value));
	}
	Ok(id)
}

pub fn make_transparent<U, F, FS>(
	builder: &mut ConstraintSystemBuilder<U, F>,
	name: impl ToString,
	values: &[FS],
) -> Result<OracleId, anyhow::Error>
where
	U: PackScalar<F> + PackScalar<FS>,
	F: TowerField + ExtensionField<FS>,
	FS: TowerField,
{
	let packed_length = values.len().div_ceil(PackedType::<U, FS>::WIDTH);
	let mut packed_values = vec![PackedType::<U, FS>::default(); packed_length];
	for (i, value) in values.iter().enumerate() {
		binius_field::packed::set_packed_slice(&mut packed_values, i, *value);
	}

	use binius_core::transparent::multilinear_extension::MultilinearExtensionTransparent;
	let mle = MultilinearExtensionTransparent::<_, PackedType<U, F>, _>::from_values(
		packed_values.clone(),
	)?;

	let oracle = builder.add_transparent(name, mle)?;

	if let Some(witness) = builder.witness() {
		let mut entry_builder = witness.new_column::<FS>(oracle);
		entry_builder.packed().copy_from_slice(&packed_values);
	}

	Ok(oracle)
}