43 if (
a.is_constant() &&
b.is_constant()) {
47 a_native.
get_msb(), num_bits - 1,
"field_t: Left operand in logic gate exceeds specified bit length");
49 b_native.
get_msb(), num_bits - 1,
"field_t: Right operand in logic gate exceeds specified bit length");
51 uint256_t result_native = is_xor_gate ? (a_native ^ b_native) : (a_native & b_native);
57 if (
a.is_constant() && !
b.is_constant()) {
62 return create_logic_constraint(a_witness,
b, num_bits, is_xor_gate, get_chunk);
65 if (!
a.is_constant() &&
b.is_constant()) {
70 return create_logic_constraint(
a, b_witness, num_bits, is_xor_gate, get_chunk);
73 Builder* ctx = validate_context<Builder>(
a.get_context(),
b.get_context());
80 const size_t num_chunks = (num_bits / 32) + ((num_bits % 32 == 0) ? 0 : 1);
88 for (
size_t i = 0; i < num_chunks; ++i) {
89 size_t chunk_size = (i != num_chunks - 1) ? 32 : num_bits - i * 32;
90 auto [left_chunk, right_chunk] = get_chunk(left, right, chunk_size);
97 auto scaling_factor =
uint256_t(1) << (32 * i);
98 a_accumulator += a_chunk * scaling_factor;
99 b_accumulator += b_chunk * scaling_factor;
101 if (chunk_size != 32) {
107 res += result_chunk * scaling_factor;
113 a.assert_equal(a_accumulator,
"stdlib logic: failed to reconstruct left operand");
114 b.assert_equal(b_accumulator,
"stdlib logic: failed to reconstruct right operand");
static field_pt create_logic_constraint(field_pt &a, field_pt &b, size_t num_bits, bool is_xor_gate, const std::function< std::pair< uint256_t, uint256_t >(uint256_t, uint256_t, size_t)> &get_chunk=[](uint256_t left, uint256_t right, size_t chunk_size) { uint256_t left_chunk=left &((uint256_t(1)<< chunk_size) - 1);uint256_t right_chunk=right &((uint256_t(1)<< chunk_size) - 1);return std::make_pair(left_chunk, right_chunk);})
A logical AND or XOR over a variable number of bits.