Skip to content

Commit

Permalink
example: Add example of Transparent (EqIndPartialEval) column usage
Browse files Browse the repository at this point in the history
  • Loading branch information
storojs72 committed Feb 12, 2025
1 parent ce5148c commit 3bb62c4
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 30 deletions.
4 changes: 4 additions & 0 deletions examples/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ path = "acc-constants.rs"
name = "acc-disjoint-product"
path = "acc-disjoint-product.rs"

[[example]]
name = "acc-eq-ind-partial-eval"
path = "acc-eq-ind-partial-eval.rs"

[lints.clippy]
needless_range_loop = "allow"

Expand Down
63 changes: 33 additions & 30 deletions examples/acc-disjoint-product.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use binius_circuits::builder::ConstraintSystemBuilder;
use binius_core::constraint_system::validate::validate_witness;
use binius_core::transparent::constant::Constant;
use binius_core::transparent::disjoint_product::DisjointProduct;
use binius_core::transparent::powers::Powers;
use binius_field::arch::OptimalUnderlier;
use binius_field::{BinaryField, BinaryField128b, BinaryField8b, PackedField};
use binius_core::{
constraint_system::validate::validate_witness,
transparent::{constant::Constant, disjoint_product::DisjointProduct, powers::Powers},
};
use binius_field::{
arch::OptimalUnderlier, BinaryField, BinaryField128b, BinaryField8b, PackedField,
};

type U = OptimalUnderlier;
type F128 = BinaryField128b;
Expand All @@ -27,35 +28,37 @@ const LOG_SIZE: usize = 4;
// Also note, that DisjointProduct makes eventual Transparent column to have height (n_vars) which is sum
// of heights (n_vars) of Powers and Constant, so actual data could be repeated multiple times
fn main() {
let allocator = bumpalo::Bump::new();
let mut builder = ConstraintSystemBuilder::<U, F128>::new_with_witness(&allocator);
let allocator = bumpalo::Bump::new();
let mut builder = ConstraintSystemBuilder::<U, F128>::new_with_witness(&allocator);

let generator = F8::MULTIPLICATIVE_GENERATOR;
let powers = Powers::new(LOG_SIZE, generator.into());
let generator = F8::MULTIPLICATIVE_GENERATOR;
let powers = Powers::new(LOG_SIZE, generator.into());

let constant_value = F8::new(0xf0);
let constant = Constant::new(LOG_SIZE, constant_value);
let constant_value = F8::new(0xf0);
let constant = Constant::new(LOG_SIZE, constant_value);

let disjoint_product = DisjointProduct(powers, constant);
let disjoint_product_id = builder.add_transparent("disjoint_product" , disjoint_product).unwrap();
let disjoint_product = DisjointProduct(powers, constant);
let disjoint_product_id = builder
.add_transparent("disjoint_product", disjoint_product)
.unwrap();

if let Some(witness) = builder.witness() {
let mut disjoint_product_witness = witness.new_column::<F8>(disjoint_product_id);
if let Some(witness) = builder.witness() {
let mut disjoint_product_witness = witness.new_column::<F8>(disjoint_product_id);

let values = disjoint_product_witness.as_mut_slice::<F8>();
let values = disjoint_product_witness.as_mut_slice::<F8>();

let mut exponent = 0u64;
for val in values.into_iter() {
if exponent == 2u64.pow(LOG_SIZE as u32) {
exponent = 0;
}
*val = generator.pow(exponent) * constant_value;
exponent += 1;
}
}
let mut exponent = 0u64;
for val in values.into_iter() {
if exponent == 2u64.pow(LOG_SIZE as u32) {
exponent = 0;
}
*val = generator.pow(exponent) * constant_value;
exponent += 1;
}
}

let witness = builder.take_witness().unwrap();
let constraints_system = builder.build().unwrap();
let witness = builder.take_witness().unwrap();
let constraints_system = builder.build().unwrap();

validate_witness(&constraints_system, &[], &witness).unwrap();
}
validate_witness(&constraints_system, &[], &witness).unwrap();
}
81 changes: 81 additions & 0 deletions examples/acc-eq-ind-partial-eval.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
use binius_circuits::builder::ConstraintSystemBuilder;
use binius_core::{
constraint_system::validate::validate_witness, transparent::eq_ind::EqIndPartialEval,
};
use binius_field::{arch::OptimalUnderlier, BinaryField128b, PackedField};

type U = OptimalUnderlier;
type F128 = BinaryField128b;

const LOG_SIZE: usize = 3;

// FIXME: Following gadgets are unconstrained. Only for demonstrative purpose, don't use in production

// Currently, it is hard for me to imagine some real world use-cases where Transparent column specified by
// EqIndPartialEval could be useful. The program can use some of its data as challenges and the Transparent
// column with EqIndPartialEval will expect witness values defined as following:
//
// x_i * y_i + (1 - x_i) * (1 - y_i)
//
// where 'x_i' is an element from a particular row of basis matrix, and y_i is a given challenge.
//
fn main() {
let allocator = bumpalo::Bump::new();
let mut builder = ConstraintSystemBuilder::<U, F128>::new_with_witness(&allocator);

// A truth table [000, 001, 010, 011 ... 111] where each row is in reversed order
let rev_basis = vec![
vec![0, 0, 0],
vec![1, 0, 0],
vec![0, 1, 0],
vec![1, 1, 0],
vec![0, 0, 1],
vec![1, 0, 1],
vec![0, 1, 1],
vec![1, 1, 1],
];

// rev_basis size correlates with LOG_SIZE
assert_eq!(1 << LOG_SIZE, rev_basis.len());

// let's choose some random challenges (each not greater than 1 << LOG_SIZE bits for this example)
let challenges = vec![F128::from(110), F128::from(190), F128::from(200)];

// challenges size correlates with LOG_SIZE
assert_eq!(challenges.len(), LOG_SIZE);

let eq_ind_partial_eval = EqIndPartialEval::new(LOG_SIZE, challenges.clone()).unwrap();

let id = builder
.add_transparent("eq_ind_partial_eval", eq_ind_partial_eval)
.unwrap();

if let Some(witness) = builder.witness() {
let mut eq_witness = witness.new_column::<F128>(id);

let column_values = eq_witness.as_mut_slice::<F128>();
assert_eq!(column_values.len(), 1 << LOG_SIZE);

let one = F128::one();

for (inv_basis_item, val) in rev_basis.iter().zip(column_values.iter_mut()) {
let mut value = F128::one();
inv_basis_item
.iter()
.zip(challenges.iter())
.for_each(|(x, y)| {
let x = F128::new(*x);
let y = *y;

// following expression is defined in the EqIndPartialEval implementation
value *= x * y + (one - x) * (one - y);
});
*val = value;
}
}

let witness = builder.take_witness().unwrap();
let constraints_system = builder.build().unwrap();

validate_witness(&constraints_system, &[], &witness).unwrap();
}

0 comments on commit 3bb62c4

Please sign in to comment.