18 static constexpr std::array<FF, 16> precomputed_inverses = [] {
19 std::array<FF, 16> inverses{ 0, 1 };
21 for (
size_t i = 2; i <= 15; i++) {
22 inverses[i] =
FF(i).invert();
31 return C::bitwise_sel_and;
33 return C::bitwise_sel_or;
35 return C::bitwise_sel_xor;
37 __builtin_unreachable();
42 for (
const auto&
event : events) {
43 auto tag =
event.a.get_tag();
55 bool is_tag_mismatch =
event.a.get_tag() !=
event.b.get_tag();
59 const uint8_t tag_a_u8 =
static_cast<uint8_t
>(
event.a.get_tag());
60 const uint8_t tag_b_u8 =
static_cast<uint8_t
>(
event.b.get_tag());
62 FF tag_a_inv = precomputed_inverses[tag_a_u8];
64 FF tag_ab_diff_inv = 0;
65 if (tag_a_u8 > tag_b_u8) {
66 tag_ab_diff_inv = precomputed_inverses[tag_a_u8 - tag_b_u8];
69 tag_ab_diff_inv = -precomputed_inverses[tag_b_u8 - tag_a_u8];
72 if (is_tag_ff || is_tag_mismatch) {
77 { C::bitwise_sel, 1 },
78 { C::bitwise_op_id,
static_cast<uint8_t
>(
event.operation) },
79 { C::bitwise_start, 1 },
80 { C::bitwise_sel_get_ctr, 0 },
81 { C::bitwise_end, 1 },
82 { C::bitwise_acc_ia,
event.a.as_ff() },
83 { C::bitwise_acc_ib,
event.b.as_ff() },
84 { C::bitwise_acc_ic, output_c },
85 { C::bitwise_ia_byte,
event.a.as_ff() },
86 { C::bitwise_ib_byte,
event.b.as_ff() },
87 { C::bitwise_ic_byte, output_c },
88 { C::bitwise_tag_a, tag_a_u8 },
89 { C::bitwise_tag_b, tag_b_u8 },
92 { C::bitwise_sel_tag_ff_err, is_tag_ff ? 1 : 0 },
93 { C::bitwise_sel_tag_mismatch_err, is_tag_mismatch ? 1 : 0 },
94 { C::bitwise_err, 1 },
96 { C::bitwise_tag_a_inv, tag_a_inv },
97 { C::bitwise_tag_ab_diff_inv, tag_ab_diff_inv },
109 constexpr uint128_t mask_low_byte = (1 << 8) - 1;
112 for (
int ctr = start_ctr; ctr > 0; ctr--) {
113 bool is_start = (ctr == start_ctr);
114 uint8_t ia_byte = input_a & mask_low_byte;
115 uint8_t ib_byte = input_b & mask_low_byte;
117 { { { C::bitwise_sel, 1 },
118 { C::bitwise_sel_compute, 1 },
119 { get_op_id_column_selector(
event.operation), 1 },
120 { C::bitwise_op_id,
static_cast<uint8_t
>(
event.operation) },
123 { C::bitwise_acc_ia, input_a },
124 { C::bitwise_acc_ib, input_b },
125 { C::bitwise_acc_ic, output_c },
126 { C::bitwise_ia_byte, ia_byte },
127 { C::bitwise_ib_byte, ib_byte },
128 { C::bitwise_ic_byte, output_c & mask_low_byte },
129 { C::bitwise_output_and, ia_byte & ib_byte },
130 { C::bitwise_output_or, ia_byte | ib_byte },
131 { C::bitwise_output_xor, ia_byte ^ ib_byte },
132 { C::bitwise_tag_a, is_start ? tag_a_u8 : 0 },
133 { C::bitwise_tag_b, is_start ? tag_b_u8 : 0 },
134 { C::bitwise_tag_c, is_start ? tag_a_u8 : 0 },
135 { C::bitwise_ctr, ctr },
136 { C::bitwise_ctr_min_one_inv, precomputed_inverses[
static_cast<uint8_t
>(ctr - 1)] },
137 { C::bitwise_end, ctr == 1 ? 1 : 0 },
138 { C::bitwise_start, is_start ? 1 : 0 },
139 { C::bitwise_sel_get_ctr, is_start ? 1 : 0 },
141 { C::bitwise_tag_a_inv, is_start ? tag_a_inv : 0 },
142 { C::bitwise_tag_ab_diff_inv, is_start ? tag_ab_diff_inv : 0 } } });