36 using Field =
typename Logic::Field;
37 using EltW =
typename Logic::EltW;
39 using v8 =
typename Logic::v8;
40 static constexpr size_t kIndexBits = IndexBits;
41 static constexpr size_t kNCounters = CborConstants::kNCounters;
42 using bv_counters =
typename Logic::template bitvec<kNCounters>;
46 using vindex =
typename Logic::template bitvec<kIndexBits>;
49 static_assert(!Field::kCharacteristicTwo);
51 explicit Cbor(
const Logic& l)
52 : l_(l), ba_count_(l), ba_byte_(l), ba_index_(l), bp_(l) {}
61 EltW encoded_sel_header;
78 BitW length_plus_next_v8;
79 BitW count_is_next_v8;
82 EltW as_field_element;
83 EltW count_as_field_element;
88 struct decode decode_one_v8(const v8& v)
const {
94 auto count = L.template slice<0, 5>(v);
95 auto type = L.template slice<5, 8>(v);
97 s.itemsp = L.veqmask(type, 0b110, 0b100);
98 s.stringp = L.veqmask(type, 0b110, 0b010);
100 s.specialp = L.veq(type, 7);
101 s.tagp = L.veq(type, 6);
102 s.arrayp = L.land(&s.itemsp, L.lnot(type[0]));
103 s.mapp = L.land(&s.itemsp, type[0]);
106 s.count0_23 = L.lnot(L.veqmask(count, 0b11000, 0b11000));
108 s.count24 = L.veq(count, 24);
110 BitW count20_23 = L.veqmask(count, 0b11100, 0b10100);
111 s.simple_specialp = L.land(&s.specialp, count20_23);
114 s.length_plus_next_v8 =
115 L.veqmask(v, 0b110'11111, 0b010'11000);
119 L.veqmask(v, 0b110'11111, 0b100'11000);
122 auto lhs = L.land(&s.specialp, L.lnot(s.simple_specialp));
123 auto bad_count = L.lor_exclusive(&s.count24, s.count0_23);
124 s.invalid = L.lor(&lhs, L.lnot(bad_count));
126 s.count_as_field_element = ba_count_.as_field_element(count);
133 s.length = L.konst(1);
134 s.length = L.add(&s.length, L.eval(s.count24));
135 auto str_23 = L.land(&s.stringp, s.count0_23);
136 auto e_str_23 = L.eval(str_23);
137 auto adjust_if_string = L.mul(&e_str_23, s.count_as_field_element);
138 s.length = L.add(&s.length, adjust_if_string);
140 s.as_field_element = ba_byte_.as_field_element(v);
147 void assert_decode(
size_t n,
const decode ds[],
148 const position_witness pw[],
149 const global_witness& gw)
const {
155 for (
size_t i = 0; i < n; ++i) {
156 L.assert_implies(&ds[i].header, L.lnot(ds[i].invalid));
160 L.assert_implies(&ds[n - 1].header, L.lnot(ds[n - 1].length_plus_next_v8));
164 L.assert_implies(&ds[n - 1].header, L.lnot(ds[n - 1].count_is_next_v8));
170 std::vector<EltW> mone(n);
171 std::vector<BitW> header(n);
172 std::vector<EltW> length(n);
173 std::vector<EltW> slen_next(n);
175 for (
size_t i = 0; i + 1 < n; ++i) {
176 mone[i] = L.konst(L.mone());
177 header[i] = ds[i].header;
178 length[i] = ds[i].length;
181 L.lmul(&ds[i].length_plus_next_v8, ds[i + 1].as_field_element);
182 length[i] = L.add(&length[i], len_i);
186 SC.add(n, slen_next.data(), header.data(), length.data(), mone.data());
191 L.assert1(header[0]);
195 auto one = L.konst(1);
199 for (
size_t i = 0; i + 1 < n; ++i) {
200 auto implies = L.lmul(&header[i + 1], L.sub(&slen_next[i], one));
210 auto f = [&](
size_t i) {
211 return L.mux(&header[i + 1], &one, L.sub(&slen_next[i], one));
213 EltW prod = L.mul(0, n - 1, f);
214 auto want_one = L.mul(&prod, gw.invprod_decode);
215 L.assert_eq(&want_one, one);
223 using counters = std::array<EltW, kNCounters>;
231 std::vector<EltW> ddss(n);
232 std::vector<BitW> SS(n);
233 std::vector<EltW> AA(n);
234 std::vector<EltW> BB(n);
239 for (
size_t i = 0; i < n; ++i) {
240 ps[i].sel = bp_.pluckj(pw[i].encoded_sel_header);
243 auto mone = L.konst(L.mone());
244 for (
size_t l = 0; l < kNCounters; ++l) {
245 for (
size_t i = 0; i < n; ++i) {
247 auto dp = L.land(&ds[i].header, ps[i].sel[l]);
248 ddss[i] = L.lmul(&dp, mone);
272 SC.add(n, BB.data(), ddss.data());
274 SC.add(n, BB.data(), SS.data(), AA.data(), ddss.data());
278 for (
size_t i = 0; i < n; ++i) {
283 for (
size_t i = 0; i < n; ++i) {
284 EltW newc = L.eval(ds[i].tagp);
285 EltW count = ds[i].count_as_field_element;
287 count = L.mux(&ds[i].count_is_next_v8, &ds[i + 1].as_field_element,
290 newc = L.add(&newc, L.lmul(&ds[i].itemsp, count));
291 newc = L.add(&newc, L.lmul(&ds[i].mapp, count));
294 auto sel = L.land(&ps[i].sel[l], ds[i].header);
295 auto tag = L.lor(&ds[i].tagp, ds[i].itemsp);
296 SS[i] = L.land(&sel, tag);
302 for (
size_t i = 0; i < n; ++i) {
307 void assert_parse(
size_t n,
const decode ds[],
312 for (
size_t i = 0; i < n; ++i) {
317 for (
size_t l = 0; l < kNCounters; ++l) {
318 L.assert_is_bit(ps[i].sel[l]);
319 sum = L.lor_exclusive(&sum, ps[i].sel[l]);
321 L.assert_is_bit(sum);
324 L.assert_implies(&ds[i].header, sum);
330 for (
size_t l = 0; l < kNCounters; ++l) {
331 L.assert0(ps[n - 1].c[l]);
336 L.assert1(ps[0].sel[0]);
338 for (
size_t i = 0; i + 1 < n; ++i) {
344 BitW b = ps[i + 1].sel[0];
345 for (
size_t l = 1; l < kNCounters; ++l) {
347 L.assert0(L.lmul(&b, ps[i].c[l]));
348 b = L.lor(&b, ps[i + 1].sel[l]);
356 std::vector<EltW> prod(kNCounters);
358 auto one = L.konst(1);
359 for (
size_t l = 0; l < kNCounters; ++l) {
360 auto f = [&](
size_t i) {
361 return L.mux(&ps[i + 1].sel[l], &ps[i].c[l], one);
363 prod[l] = L.mul(0, n - 1, f);
366 EltW p = L.mul(0, kNCounters, [&](
size_t l) {
return prod[l]; });
367 auto want_one = L.mul(&p, gw.invprod_parse);
368 L.assert_eq(&want_one, one);
374 void assert_text_at(
size_t n,
const vindex& j,
size_t len,
375 const uint8_t bytes[],
376 const decode ds[])
const {
378 const Routing<Logic> R(L);
381 proofs::check(len < 24,
"len < 24");
383 assert_header(n, j, ds);
385 std::vector<EltW> A(n);
386 for (
size_t i = 0; i < n; ++i) {
387 A[i] = ds[i].as_field_element;
391 std::vector<EltW> B(len + 1);
392 const EltW defaultA = L.konst(256);
393 R.shift(j, len + 1, B.data(), n, A.data(), defaultA, 3);
395 size_t expected_header = (3 << 5) + len;
396 L.assert_eq(&B[0], L.konst(expected_header));
397 for (
size_t i = 0; i < len; ++i) {
398 auto bi = L.konst(bytes[i]);
399 L.assert_eq(&B[i + 1], bi);
406 void assert_unsigned_at(
size_t n,
const vindex& j, uint64_t u,
407 const decode ds[])
const {
409 proofs::check(u < 24,
"u < 24");
411 size_t expected = (0 << 5) + u;
412 assert_atom_at(n, j, l_.konst(expected), ds);
419 void assert_negative_at(
size_t n,
const vindex& j, uint64_t u,
420 const decode ds[])
const {
422 proofs::check(u < 24,
"u < 24");
424 size_t expected = (1 << 5) + u;
425 assert_atom_at(n, j, l_.konst(expected), ds);
432 void assert_bool_at(
size_t n,
const vindex& j,
bool val,
433 const decode ds[])
const {
434 size_t expected = (7 << 5) + (val ? 21 : 20);
435 assert_atom_at(n, j, l_.konst(expected), ds);
439 void date_helper(
size_t n,
const vindex& j,
const decode ds[],
440 std::vector<v8>& B )
const {
442 const Routing<Logic> R(L);
443 assert_header(n, j, ds);
445 std::vector<v8> A(n);
446 for (
size_t i = 0; i < n; ++i) {
447 A[i] = ds[i].as_bits;
451 L.template vbit<8>(0);
452 R.shift(j, 20 + 2, B.data(), n, A.data(), defaultA, 3);
455 L.vassert_eq(&B[0], L.template vbit<8>(0xc0));
458 L.vassert_eq(&B[1], L.template vbit<8>(0x74));
465 void assert_date_before_at(
size_t n,
const vindex& j,
const v8 now[],
466 const decode ds[])
const {
468 const Memcmp<Logic> CMP(L);
469 std::vector<v8> B(20 + 2);
470 date_helper(n, j, ds, B);
471 auto lt = CMP.lt(20, &B[2], now);
479 void assert_date_after_at(
size_t n,
const vindex& j,
const v8 now[],
480 const decode ds[])
const {
482 const Memcmp<Logic> CMP(L);
483 std::vector<v8> B(20 + 2);
484 date_helper(n, j, ds, B);
485 auto lt = CMP.lt(20, now, &B[2]);
493 void assert_atom_at(
size_t n,
const vindex& j,
const EltW& expected,
494 const decode ds[])
const {
496 const Routing<Logic> R(L);
498 assert_header(n, j, ds);
500 std::vector<EltW> A(n);
501 for (
size_t i = 0; i < n; ++i) {
502 A[i] = ds[i].as_field_element;
507 R.shift(j, 1, B, n, A.data(), L.konst(256), unroll);
508 L.assert_eq(&B[0], expected);
515 void assert_elt_as_be_bytes_at(
size_t n,
const vindex& j,
size_t len, EltW X,
516 const decode ds[])
const {
518 const Routing<Logic> R(L);
520 std::vector<EltW> A(n);
521 for (
size_t i = 0; i < n; ++i) {
522 A[i] = ds[i].as_field_element;
524 EltW tx = L.konst(0), k256 = L.konst(256);
526 std::vector<EltW> B(2 + len);
529 R.shift(j, len + 2, B.data(), n, A.data(), L.konst(0), unroll);
531 size_t expected_header = (2 << 5) + len;
532 auto eh = L.konst(expected_header);
533 L.assert_eq(&B[0], eh);
534 }
else if (len < 256) {
535 size_t expected_header = (2 << 5) + 24;
536 auto eh = L.konst(expected_header);
537 L.assert_eq(&B[0], eh);
538 L.assert_eq(&B[1], L.konst(len));
541 check(
false,
"len >= 256");
544 for (
size_t i = 0; i < len; ++i) {
545 auto tmp = L.mul(&tx, k256);
546 tx = L.add(&tmp, B[i + si]);
555 void assert_header(
size_t n,
const vindex& j,
const decode ds[])
const {
561 auto f = [&](
size_t i) {
return L.land(&ds[i].header, L.veq(j, i)); };
562 L.assert1(L.lor_exclusive(0, n, f));
568 void assert_map_header(
size_t n,
const vindex& j,
569 const decode ds[])
const {
575 auto f = [&](
size_t i) {
576 auto eq_ji = L.veq(j, i);
577 auto dsi = L.land(&ds[i].mapp, ds[i].header);
578 return L.land(&eq_ji, dsi);
580 L.assert1(L.lor_exclusive(0, n, f));
587 void assert_map_entry(
size_t n,
const vindex& m,
size_t level,
588 const vindex& k,
const vindex& v,
const vindex& j,
592 const Routing<Logic> R(L);
594 assert_map_header(n, m, ds);
595 assert_header(n, k, ds);
596 assert_header(n, v, ds);
598 for (
size_t l = 0; l < kNCounters; ++l) {
599 std::vector<EltW> A(n);
600 for (
size_t i = 0; i < n; ++i) {
607 const size_t unroll = 3;
608 R.shift(m, 1, &cm, n, A.data(), L.konst(0), unroll);
609 R.shift(k, 1, &ck, n, A.data(), L.konst(0), unroll);
610 R.shift(v, 1, &cv, n, A.data(), L.konst(0), unroll);
615 L.assert_eq(&cm, ck);
616 L.assert_eq(&cm, cv);
617 }
else if (l == level + 1) {
618 auto one = L.konst(1);
619 auto two = L.konst(2);
623 auto twoj = L.mul(&two, ba_index_.as_field_element(j));
624 L.assert_eq(&cm, L.add(&ck, L.add(&twoj, one)));
625 L.assert_eq(&cm, L.add(&cv, L.add(&twoj, two)));
638 void assert_input_starts_at(
size_t n,
const vindex& jroot,
639 const vindex& input_len,
640 const decode ds[])
const {
643 L.assert1(L.vleq(input_len, n));
644 L.assert1(L.vlt(jroot, n));
645 auto tot = L.vadd(jroot, input_len);
646 L.vassert_eq(tot, n);
648 for (
size_t i = 0; i < n; ++i) {
649 L.assert0(L.lmul(&ds[i].as_field_element, L.vlt(i, jroot)));
658 void decode_all(
size_t n,
decode ds[],
const v8 in[],
660 for (
size_t i = 0; i < n; ++i) {
661 ds[i] = decode_one_v8(in[i]);
662 ds[i].header = bp_.pluckb(pw[i].encoded_sel_header);
666 void decode_and_assert_decode(
size_t n,
decode ds[],
const v8 in[],
669 decode_all(n, ds, in, pw);
670 assert_decode(n, ds, pw, gw);
673 void decode_and_assert_decode_and_parse(
size_t n,
decode ds[],
678 decode_and_assert_decode(n, ds, in, pw, gw);
679 parse(n, ps, ds, pw, gw);
680 assert_parse(n, ds, ps, gw);
685 const BitAdder<Logic, 5> ba_count_;
686 const BitAdder<Logic, 8> ba_byte_;
687 const BitAdder<Logic, kIndexBits> ba_index_;
688 const CborPlucker<Logic, kNCounters> bp_;