Longfellow ZK 0290cb32
Loading...
Searching...
No Matches
cbor_byte_decoder.h
1// Copyright 2025 Google LLC.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#ifndef PRIVACY_PROOFS_ZK_LIB_CIRCUITS_CBOR_PARSER_CBOR_BYTE_DECODER_H_
16#define PRIVACY_PROOFS_ZK_LIB_CIRCUITS_CBOR_PARSER_CBOR_BYTE_DECODER_H_
17
18#include <stddef.h>
19#include <stdint.h>
20
21#include "circuits/logic/counter.h"
22
23namespace proofs {
24template <class Logic>
25class CborByteDecoder {
26 public:
27 using CounterL = Counter<Logic>;
28 using Field = typename Logic::Field;
29 using EltW = typename Logic::EltW;
30 using CEltW = typename CounterL::CEltW;
31 using BitW = typename Logic::BitW;
32 using v8 = typename Logic::v8;
33
34 explicit CborByteDecoder(const Logic& l) : l_(l), ctr_(l) {}
35
36 //------------------------------------------------------------
37 // Decoder (lexer)
38 //------------------------------------------------------------
39 struct decode {
40 BitW atomp;
41 BitW itemsp;
42 BitW stringp;
43 BitW arrayp;
44 BitW mapp;
45 BitW tagp;
46 BitW specialp;
47 BitW simple_specialp; // One of false, true, null, or undefined.
48 BitW count0_23;
49 BitW count24_27;
50 BitW count24;
51 BitW count25;
52 BitW count26;
53 BitW count27;
54 BitW length_plus_next_v8;
55 BitW count_is_next_v8;
56 BitW invalid;
57 CEltW length; // of this item
58 EltW as_scalar;
59 CEltW as_counter;
60 CEltW count_as_counter;
61 v8 as_bits;
62 };
63
64 // Extract whatever we can from one v8 alone, without looking
65 // at witnesses, assuming that
66 // this v8 is the start of a cbor token.
67 struct decode decode_one_v8(const v8& v) const {
68 const Logic& L = l_; // shorthand
69 struct decode s;
70 L.vassert_is_bit(v);
71
72 // v = type:3 count:5
73 auto count = L.template slice<0, 5>(v);
74 auto type = L.template slice<5, 8>(v);
75
76 s.atomp = L.veqmask(type, /*mask*/ 0b110, /*val*/ 0b000);
77 s.stringp = L.veqmask(type, /*mask*/ 0b110, /*val*/ 0b010);
78 s.itemsp = L.veqmask(type, /*mask*/ 0b110, /*val*/ 0b100);
79
80 s.specialp = L.veq(type, 7);
81 s.tagp = L.veq(type, 6);
82 s.arrayp = L.land(&s.itemsp, L.lnot(type[0]));
83 s.mapp = L.land(&s.itemsp, type[0]);
84
85 // count0_23 = (0 <= count < 24) = ~(count == 11xxx)
86 s.count0_23 = L.lnot(L.veqmask(count, /*mask*/ 0b11000, /*val*/ 0b11000));
87 s.count24_27 = L.veqmask(count, /*mask*/ 0b11100, /*val*/ 0b11000);
88
89 s.count24 = L.veq(count, 24);
90 s.count25 = L.veq(count, 25);
91 s.count26 = L.veq(count, 26);
92 s.count27 = L.veq(count, 27);
93
94 BitW count20_23 = L.veqmask(count, /*mask*/ 0b11100, /*val*/ 0b10100);
95 s.simple_specialp = L.land(&s.specialp, count20_23);
96
97 // stringp && count24
98 s.length_plus_next_v8 =
99 L.veqmask(v, /*mask*/ 0b110'11111, /*val*/ 0b010'11000);
100
101 // itemsp && count24
102 s.count_is_next_v8 =
103 L.veqmask(v, /*mask*/ 0b110'11111, /*val*/ 0b100'11000);
104
105 BitW count0_24 = L.lor_exclusive(&s.count24, s.count0_23);
106 BitW atom_or_tag = L.lor_exclusive(&s.atomp, s.tagp);
107
108 // count0_24 works for all types (except invalid special)
109 // but atom_or_tag supports count <= 27
110 BitW good_count = L.lor(&count0_24, L.land(&atom_or_tag, s.count24_27));
111 BitW invalid_special = L.land(&s.specialp, L.lnot(s.simple_specialp));
112 s.invalid = L.lor(&invalid_special, L.lnot(good_count));
113
114 s.count_as_counter = ctr_.as_counter(count);
115
116 // Hack to compute the length. Unclear what the right
117 // abstraction should be.
118
119 // Compute l24_27, the length assuming count24_27
120 CEltW l1 = ctr_.as_counter(1 + 1);
121 CEltW l2 = ctr_.as_counter(1 + 2);
122 CEltW l4 = ctr_.as_counter(1 + 4);
123 CEltW l8 = ctr_.as_counter(1 + 8);
124 CEltW l24_25 = ctr_.mux(&count[0], &l2, l1);
125 CEltW l26_27 = ctr_.mux(&count[0], &l8, l4);
126 CEltW l24_27 = ctr_.mux(&count[1], &l26_27, l24_25);
127
128 // choose between count0_23 and count24_27
129 CEltW x1 = ctr_.as_counter(1);
130 s.length = ctr_.mux(&s.count0_23, &x1, l24_27);
131
132 // adjust for strings
133 BitW str_23 = L.land(&s.stringp, s.count0_23);
134 CEltW adjust_if_string = ctr_.ite0(&str_23, s.count_as_counter);
135 s.length = ctr_.add(&s.length, adjust_if_string);
136
137 s.as_counter = ctr_.as_counter(v);
138 s.as_scalar = L.as_scalar(v);
139 s.as_bits = v;
140
141 return s;
142 }
143
144 private:
145 const Logic& l_;
146 const CounterL ctr_;
147};
148} // namespace proofs
149
150#endif // PRIVACY_PROOFS_ZK_LIB_CIRCUITS_CBOR_PARSER_CBOR_BYTE_DECODER_H_
Definition logic.h:38
Definition cbor_byte_decoder.h:39
Definition logic.h:130