binius_circuits/
pack.rs

1// Copyright 2024-2025 Irreducible Inc.
2
3use anyhow::Result;
4use binius_core::oracle::OracleId;
5use binius_field::{as_packed_field::PackScalar, ExtensionField, TowerField};
6
7use crate::builder::{
8	types::{F, U},
9	ConstraintSystemBuilder,
10};
11
12pub fn pack<FInput, FOutput>(
13	oracle_id: OracleId,
14	builder: &mut ConstraintSystemBuilder,
15	name: impl ToString,
16) -> Result<OracleId>
17where
18	F: ExtensionField<FInput> + ExtensionField<FOutput>,
19	FInput: TowerField,
20	FOutput: TowerField + ExtensionField<FInput>,
21	U: PackScalar<FInput> + PackScalar<FOutput>,
22{
23	if FInput::TOWER_LEVEL == FOutput::TOWER_LEVEL {
24		return Ok(oracle_id);
25	}
26
27	let packed_id =
28		builder.add_packed(name, oracle_id, FOutput::TOWER_LEVEL - FInput::TOWER_LEVEL)?;
29
30	if let Some(witness) = builder.witness() {
31		let values_witness = witness.get::<FInput>(oracle_id)?;
32
33		witness.set(packed_id, values_witness.repacked::<FOutput>())?;
34	}
35
36	Ok(packed_id)
37}