33 using EltW =
typename LogicCircuit::EltW;
34 using BitW =
typename LogicCircuit::BitW;
35 using v8 =
typename LogicCircuit::v8;
36 using v6 =
typename LogicCircuit::template bitvec<6>;
39 explicit Base64Decoder(
const LogicCircuit& lc) : lc_(lc) {}
41 void base64_rawurl_decode(
const v8 inputs[],
42 v8 output[],
size_t n)
const {
43 check(n < (1 << 28),
"input too large");
44 v6 zero = lc_.template vbit<6>(0);
46 size_t max = ceildiv<size_t>(n * 6, 8);
49 for (
size_t i = 0; i < n; i += 4, oc += 3) {
50 v6 quad[4] = {zero, zero, zero, zero};
51 for (
size_t j = 0; j < 4 && i + j < n; ++j) {
52 decode(inputs[i + j], quad[j]);
55 for (
size_t j = 0; j < 24 && (oc + j / 8) < max; ++j) {
56 output[oc + j / 8][7 - (j % 8)] = quad[j / 6][5 - (j % 6)];
62 void base64_rawurl_decode_len(
63 const v8 inputs[], v8 output[],
size_t n,
64 typename LogicCircuit::template bitvec<N>& len)
const {
65 check(n < (1 << 28),
"input too large");
66 v6 zero = lc_.template vbit<6>(0);
68 size_t max = ceildiv<size_t>(n * 6, 8);
71 for (
size_t i = 0; i < n; i += 4, oc += 3) {
72 v6 quad[4] = {zero, zero, zero, zero};
74 for (
size_t j = 0; j < 4 && i + j < n; ++j) {
75 decode(inputs[i + j], quad[j], invalid);
76 auto range = lc_.vlt(i + j, len);
77 lc_.assert_implies(&range, lc_.lnot(invalid));
80 for (
size_t j = 0; j < 24 && (oc + j / 8) < max; ++j) {
81 output[oc + j / 8][7 - (j % 8)] = quad[j / 6][5 - (j % 6)];
86 void decode(
const v8 in, v6& out)
const {
88 decode(in, out, invalid);
92 void decode(
const v8 in, v6& out, BitW& invalid)
const {
94 for (
size_t i = 0; i < 8; ++i) {
95 ni[i] = lc_.lnot(in[i]);
97 std::vector<std::vector<BitW> > exp[] = {
497 invalid = lc_.or_of_and(exp[0]);
498 for (
size_t i = 0; i < 6; ++i) {
499 out[5 - i] = lc_.or_of_and(exp[i + 1]);
504 const LogicCircuit& lc_;