37 using CounterL = Counter<Logic>;
39 using Field =
typename Logic::Field;
40 using EltW =
typename Logic::EltW;
41 using CEltW =
typename CounterL::CEltW;
43 using v8 =
typename Logic::v8;
44 static constexpr size_t kIndexBits = IndexBits;
45 static constexpr size_t kNCounters = CborConstants::kNCounters;
46 using bv_counters =
typename Logic::template bitvec<kNCounters>;
50 using vindex =
typename Logic::template bitvec<kIndexBits>;
52 explicit Cbor(
const Logic& l) : l_(l), ctr_(l), bd_(l), bp_(l) {}
61 EltW encoded_sel_header;
75 void assert_decode(
size_t n,
const decode ds[],
83 for (
size_t i = 0; i < n; ++i) {
84 L.assert_implies(&ds[i].header, L.lnot(ds[i].bd.invalid));
88 L.assert_implies(&ds[n - 1].header,
89 L.lnot(ds[n - 1].bd.length_plus_next_v8));
93 L.assert_implies(&ds[n - 1].header, L.lnot(ds[n - 1].bd.count_is_next_v8));
99 std::vector<CEltW> mone(n);
100 std::vector<BitW> header(n);
101 std::vector<CEltW> length(n);
102 std::vector<CEltW> slen_next(n);
104 for (
size_t i = 0; i + 1 < n; ++i) {
105 mone[i] = ctr_.mone();
106 header[i] = ds[i].header;
107 length[i] = ds[i].bd.length;
110 ctr_.ite0(&ds[i].bd.length_plus_next_v8, ds[i + 1].bd.as_counter);
111 length[i] = ctr_.add(&length[i], len_i);
115 SC.add(n, slen_next.data(), header.data(), length.data(), mone.data());
120 L.assert1(header[0]);
124 EltW one = L.konst(L.one());
125 CEltW mone_counter = ctr_.mone();
130 for (
size_t i = 0; i + 1 < n; ++i) {
132 ctr_.ite0(&header[i + 1], ctr_.add(&slen_next[i], mone_counter));
133 ctr_.assert0(implies);
142 auto f = [&](
size_t i) {
143 CEltW snm1 = ctr_.add(&slen_next[i], mone_counter);
144 return L.mux(&header[i + 1], &one, ctr_.znz_indicator(snm1));
146 EltW prod = L.mul(0, n - 1, f);
147 auto want_one = L.mul(&prod, gw.invprod_decode);
148 L.assert_eq(&want_one, one);
156 using counters = std::array<CEltW, kNCounters>;
164 std::vector<CEltW> ddss(n);
165 std::vector<BitW> SS(n);
166 std::vector<CEltW> AA(n);
167 std::vector<CEltW> BB(n);
172 for (
size_t i = 0; i < n; ++i) {
173 ps[i].sel = bp_.pluckj(pw[i].encoded_sel_header);
176 CEltW mone = ctr_.mone();
177 for (
size_t l = 0; l < kNCounters; ++l) {
178 for (
size_t i = 0; i < n; ++i) {
180 auto dp = L.land(&ds[i].header, ps[i].sel[l]);
181 ddss[i] = ctr_.ite0(&dp, mone);
204 ddss[0] = gw.cc0_counter;
205 SC.add(n, BB.data(), ddss.data());
207 SC.add(n, BB.data(), SS.data(), AA.data(), ddss.data());
211 for (
size_t i = 0; i < n; ++i) {
216 for (
size_t i = 0; i < n; ++i) {
217 CEltW newc = ctr_.as_counter(ds[i].bd.tagp);
218 CEltW count = ds[i].bd.count_as_counter;
220 count = ctr_.mux(&ds[i].bd.count_is_next_v8, &ds[i + 1].bd.as_counter,
223 newc = ctr_.add(&newc, ctr_.ite0(&ds[i].bd.itemsp, count));
224 newc = ctr_.add(&newc, ctr_.ite0(&ds[i].bd.mapp, count));
227 auto sel = L.land(&ps[i].sel[l], ds[i].header);
228 auto tag = L.lor(&ds[i].bd.tagp, ds[i].bd.itemsp);
229 SS[i] = L.land(&sel, tag);
235 for (
size_t i = 0; i < n; ++i) {
240 void assert_parse(
size_t n,
const decode ds[],
245 for (
size_t i = 0; i < n; ++i) {
253 for (
size_t l = 0; l < kNCounters; ++l) {
254 for (
size_t m = l + 1; m < kNCounters; ++m) {
255 L.assert0(L.land(&ps[i].sel[l], ps[i].sel[m]));
261 for (
size_t l = 0; l < kNCounters; ++l) {
263 sum = L.lor_exclusive(&sum, ps[i].sel[l]);
265 L.assert_implies(&ds[i].header, sum);
271 for (
size_t l = 0; l < kNCounters; ++l) {
272 ctr_.assert0(ps[n - 1].c[l]);
277 L.assert1(ps[0].sel[0]);
279 for (
size_t i = 0; i + 1 < n; ++i) {
285 BitW b = ps[i + 1].sel[0];
286 for (
size_t l = 1; l < kNCounters; ++l) {
288 ctr_.assert0(ctr_.ite0(&b, ps[i].c[l]));
289 b = L.lor(&b, ps[i + 1].sel[l]);
297 std::vector<EltW> prod(kNCounters);
298 auto one = L.konst(1);
299 for (
size_t l = 0; l < kNCounters; ++l) {
300 auto f = [&](
size_t i) {
301 EltW cc = ctr_.znz_indicator(ps[i].c[l]);
302 return L.mux(&ps[i + 1].sel[l], &cc, one);
304 prod[l] = L.mul(0, n - 1, f);
307 EltW p = L.mul(0, kNCounters, [&](
size_t l) {
return prod[l]; });
308 auto want_one = L.mul(&p, gw.invprod_parse);
309 L.assert_eq(&want_one, one);
315 void assert_text_at(
size_t n,
const vindex& j,
size_t len,
316 const uint8_t bytes[],
317 const decode ds[])
const {
319 const Routing<Logic> R(L);
322 proofs::check(len < 24,
"len < 24");
324 assert_header(n, j, ds);
326 std::vector<EltW> A(n);
327 for (
size_t i = 0; i < n; ++i) {
328 A[i] = ds[i].bd.as_scalar;
332 std::vector<EltW> B(len + 1);
333 const EltW defaultA = L.konst(256);
334 R.shift(j, len + 1, B.data(), n, A.data(), defaultA, 3);
336 size_t expected_header = (3 << 5) + len;
337 L.assert_eq(&B[0], L.konst(expected_header));
338 for (
size_t i = 0; i < len; ++i) {
339 auto bi = L.konst(bytes[i]);
340 L.assert_eq(&B[i + 1], bi);
347 void assert_unsigned_at(
size_t n,
const vindex& j, uint64_t u,
348 const decode ds[])
const {
350 proofs::check(u < 24,
"u < 24");
352 size_t expected = (0 << 5) + u;
353 assert_atom_at(n, j, l_.konst(expected), ds);
360 void assert_negative_at(
size_t n,
const vindex& j, uint64_t u,
361 const decode ds[])
const {
363 proofs::check(u < 24,
"u < 24");
365 size_t expected = (1 << 5) + u;
366 assert_atom_at(n, j, l_.konst(expected), ds);
373 void assert_bool_at(
size_t n,
const vindex& j,
bool val,
374 const decode ds[])
const {
375 size_t expected = (7 << 5) + (val ? 21 : 20);
376 assert_atom_at(n, j, l_.konst(expected), ds);
380 void date_helper(
size_t n,
const vindex& j,
const decode ds[],
381 std::vector<v8>& B )
const {
383 const Routing<Logic> R(L);
384 assert_header(n, j, ds);
386 std::vector<v8> A(n);
387 for (
size_t i = 0; i < n; ++i) {
388 A[i] = ds[i].bd.as_bits;
392 L.template vbit<8>(0);
393 R.shift(j, 20 + 2, B.data(), n, A.data(), defaultA, 3);
396 L.vassert_eq(&B[0], L.template vbit<8>(0xc0));
399 L.vassert_eq(&B[1], L.template vbit<8>(0x74));
406 void assert_date_before_at(
size_t n,
const vindex& j,
const v8 now[],
407 const decode ds[])
const {
409 const Memcmp<Logic> CMP(L);
410 std::vector<v8> B(20 + 2);
411 date_helper(n, j, ds, B);
412 auto lt = CMP.lt(20, &B[2], now);
420 void assert_date_after_at(
size_t n,
const vindex& j,
const v8 now[],
421 const decode ds[])
const {
423 const Memcmp<Logic> CMP(L);
424 std::vector<v8> B(20 + 2);
425 date_helper(n, j, ds, B);
426 auto lt = CMP.lt(20, now, &B[2]);
434 void assert_atom_at(
size_t n,
const vindex& j,
const EltW& expected,
435 const decode ds[])
const {
437 const Routing<Logic> R(L);
439 assert_header(n, j, ds);
441 std::vector<EltW> A(n);
442 for (
size_t i = 0; i < n; ++i) {
443 A[i] = ds[i].bd.as_scalar;
448 R.shift(j, 1, B, n, A.data(), L.konst(256), unroll);
449 L.assert_eq(&B[0], expected);
455 void assert_header(
size_t n,
const vindex& j,
const decode ds[])
const {
461 auto f = [&](
size_t i) {
return L.land(&ds[i].header, L.veq(j, i)); };
462 L.assert1(L.lor_exclusive(0, n, f));
468 void assert_map_header(
size_t n,
const vindex& j,
469 const decode ds[])
const {
475 auto f = [&](
size_t i) {
476 auto eq_ji = L.veq(j, i);
477 auto dsi = L.land(&ds[i].bd.mapp, ds[i].header);
478 return L.land(&eq_ji, dsi);
480 L.assert1(L.lor_exclusive(0, n, f));
487 void assert_map_entry(
size_t n,
const vindex& m,
size_t level,
488 const vindex& k,
const vindex& v,
const vindex& j,
492 const Routing<Logic> R(L);
494 assert_map_header(n, m, ds);
495 assert_header(n, k, ds);
496 assert_header(n, v, ds);
498 for (
size_t l = 0; l < kNCounters; ++l) {
501 std::vector<EltW> A(n);
502 for (
size_t i = 0; i < n; ++i) {
509 const size_t unroll = 3;
510 R.shift(m, 1, &cm.e, n, A.data(), L.konst(0), unroll);
511 R.shift(k, 1, &ck.e, n, A.data(), L.konst(0), unroll);
512 R.shift(v, 1, &cv.e, n, A.data(), L.konst(0), unroll);
517 ctr_.assert_eq(&cm, ck);
518 ctr_.assert_eq(&cm, cv);
519 }
else if (l == level + 1) {
520 CEltW one = ctr_.as_counter(1);
521 CEltW two = ctr_.as_counter(2);
525 CEltW jctr = ctr_.as_counter(j);
526 CEltW twoj = ctr_.add(&jctr, jctr);
527 ctr_.assert_eq(&cm, ctr_.add(&ck, ctr_.add(&twoj, one)));
528 ctr_.assert_eq(&cm, ctr_.add(&cv, ctr_.add(&twoj, two)));
541 void assert_input_starts_at(
size_t n,
const vindex& jroot,
542 const vindex& input_len,
543 const decode ds[])
const {
546 L.assert1(L.vleq(input_len, n));
547 L.assert1(L.vlt(jroot, n));
548 auto tot = L.vadd(jroot, input_len);
549 L.vassert_eq(tot, n);
551 for (
size_t i = 0; i < n; ++i) {
552 L.assert0(L.lmul(&ds[i].bd.as_scalar, L.vlt(i, jroot)));
561 void decode_all(
size_t n,
decode ds[],
const v8 in[],
563 for (
size_t i = 0; i < n; ++i) {
564 ds[i].bd = bd_.decode_one_v8(in[i]);
565 ds[i].header = bp_.pluckb(pw[i].encoded_sel_header);
569 void decode_and_assert_decode(
size_t n,
decode ds[],
const v8 in[],
572 decode_all(n, ds, in, pw);
573 assert_decode(n, ds, pw, gw);
576 void decode_and_assert_decode_and_parse(
size_t n,
decode ds[],
581 decode_and_assert_decode(n, ds, in, pw, gw);
582 parse(n, ps, ds, pw, gw);
583 assert_parse(n, ds, ps, gw);
590 const CborPlucker<Logic, kNCounters> bp_;