88 static constexpr size_t kN = 1 << LOGN;
89 static constexpr size_t kNv32Elts = (32u + LOGN - 1u) / LOGN;
90 static constexpr size_t kNv256Elts = (256u + LOGN - 1u) / LOGN;
91 static constexpr size_t kNv128Elts = (128u + LOGN - 1u) / LOGN;
92 using Field =
typename Logic::Field;
94 using EltW =
typename Logic::EltW;
98 using v32 =
typename Logic::v32;
99 using v256 =
typename Logic::v256;
100 using packed_v32 = std::array<EltW, kNv32Elts>;
101 using packed_v128 = std::array<EltW, kNv128Elts>;
102 using packed_v256 = std::array<EltW, kNv256Elts>;
105 std::vector<PolyN> plucker_;
107 explicit BitPlucker(
const Logic& l) : l_(l), plucker_(LOGN) {
110 for (
size_t i = 0; i < kN; ++i) {
113 for (
size_t k = 0; k < LOGN; ++k) {
115 for (
size_t i = 0; i < kN; ++i) {
116 Y[i] = l_.f_.of_scalar((i >> k) & 1);
118 plucker_[k] = InterpolationN::monomial_of_lagrange(Y, X, l_.f_);
122 typename Logic::template bitvec<LOGN> pluck(
const EltW& e)
const {
123 typename Logic::template bitvec<LOGN> r;
127 for (
size_t k = 0; k < LOGN; ++k) {
128 EltW v = P.eval(plucker_[k], e);
130 r[k] = BitW(v, l_.f_);
136 v32 unpack_v32(
const packed_v32& v)
const {
138 for (
size_t i = 0; i < v.size(); ++i) {
139 auto b = pluck(v[i]);
140 for (
size_t j = 0; j < LOGN; ++j) {
141 if (LOGN * i + j < 32) {
142 r[LOGN * i + j] = b[j];
150 template <
typename T,
typename PackedT>
151 T unpack(
const PackedT& v)
const {
153 for (
size_t i = 0; i < v.size(); ++i) {
154 auto b = pluck(v[i]);
155 for (
size_t j = 0; j < LOGN; ++j) {
156 if (LOGN * i + j < r.size()) {
157 r[LOGN * i + j] = b[j];
173 static constexpr size_t kN = 1 << LOGN;
176 using Field =
typename Logic::Field;
177 using EltW =
typename Logic::EltW;
181 EltMuxer(
const Logic& l,
const EltW arr[]) : l_(l), coeff_(kN) {
182 for (
size_t i = 0; i < kN; ++i) {
183 coeff_[i] = l_.konst(0);
185 for (
size_t i = 0; i < kN; ++i) {
186 PolyN basis_i = even_lagrange_basis(i);
187 for (
size_t j = 0; j < kN; ++j) {
188 auto bi = l_.konst(basis_i[j]);
189 auto barr_i = l_.mul(&bi, arr[i]);
190 coeff_[j] = l_.add(&coeff_[j], barr_i);
195 EltW mux(
const EltW& ind)
const {
198 std::array<EltW, kN> xi;
199 P.powers_of_x(kN, xi.data(), ind);
202 EltW r = l_.konst(0);
203 for (
size_t i = 0; i < kN; ++i) {
204 auto cxi = l_.mul(&coeff_[i], xi[i]);
212 std::vector<EltW> coeff_;
214 PolyN even_lagrange_basis(
size_t k) {
216 for (
size_t i = 0; i < kN; ++i) {
218 Y[i] = l_.f_.of_scalar((i == k));
220 return InterpolationN::monomial_of_lagrange(Y, X, l_.f_);