36class mdoc_1f_witness {
37 using ECField =
typename EC::Field;
38 using ECElt =
typename ECField::Elt;
39 using ECNat =
typename ECField::N;
41 using Nat =
typename Field::N;
43 using CborWitness = CborWitness<Field>;
49 EcdsaWitness ew_, dkw_;
50 uint8_t now_[kMdoc1DateLen];
53 uint8_t signed_bytes_[kMdoc1MaxSHABlocks * 64];
58 std::vector<std::vector<uint8_t>> attr_bytes_;
59 std::vector<std::vector<FlatSHA256Witness::BlockWitness>> atw_;
61 std::vector<uint8_t> attr_n_;
62 std::vector<CborIndex> attr_mso_;
63 std::vector<AttrShift> attr_ei_;
64 std::vector<AttrShift> attr_ev_;
67 std::vector<typename CborWitness::v8> incb_;
68 std::vector<typename CborWitness::position_witness> pwcb_;
71 explicit mdoc_1f_witness(
size_t num_attr,
const EC& ec,
const ScalarField& Fn)
76 attr_bytes_(num_attr_),
82 incb_(kMdoc1MaxMsoLen),
83 pwcb_(kMdoc1MaxMsoLen) {}
88 for (
size_t k = 0; k < 48; ++k) {
89 filler.push_back(BPENC.mkpacked_v32(bw.outw[k]));
91 for (
size_t k = 0; k < 64; ++k) {
92 filler.push_back(BPENC.mkpacked_v32(bw.oute[k]));
93 filler.push_back(BPENC.mkpacked_v32(bw.outa[k]));
95 for (
size_t k = 0; k < 8; ++k) {
96 filler.push_back(BPENC.mkpacked_v32(bw.h1[k]));
101 df.push_back(attr.offset, kMdoc1CborIndexBits, ec_.f_);
102 df.push_back(attr.len, kMdoc1CborIndexBits, ec_.f_);
110 size_t padding_offset = 0)
const {
111 filler.push_back(ind.k + padding_offset, kMdoc1CborIndexBits, ec_.f_);
112 filler.push_back(ind.v + padding_offset, kMdoc1CborIndexBits, ec_.f_);
113 filler.push_back(ind.ndx, kMdoc1CborIndexBits, ec_.f_);
117 filler.push_back(e_);
118 filler.push_back(dpkx_);
119 filler.push_back(dpky_);
121 ew_.fill_witness(filler);
122 dkw_.fill_witness(filler);
124 filler.push_back(numb_, 8, ec_.f_);
125 for (
size_t i = kCose1PrefixLen; i < kMdoc1MaxSHABlocks * 64; ++i) {
126 filler.push_back(signed_bytes_[i], 8, ec_.f_);
128 for (
size_t j = 0; j < kMdoc1MaxSHABlocks; j++) {
129 fill_sha(filler, bw_[j]);
132 size_t prepad = kMdoc1MaxMsoLen - pm_.t_mso_.len + 5;
133 filler.push_back(prepad, kMdoc1CborIndexBits, ec_.f_);
134 filler.push_back(pm_.t_mso_.len - 5, kMdoc1CborIndexBits, ec_.f_);
135 for (
size_t i = 0; i < kMdoc1MaxMsoLen; ++i) {
136 filler.push_back(pwcb_[i].encoded_sel_header);
138 filler.push_back(gwcb_.invprod_decode);
139 filler.push_back(gwcb_.cc0);
140 filler.push_back(gwcb_.invprod_parse);
142 fill_cbor_index(filler, pm_.valid_, prepad);
143 fill_cbor_index(filler, pm_.valid_from_, prepad);
144 fill_cbor_index(filler, pm_.valid_until_, prepad);
145 fill_cbor_index(filler, pm_.dev_key_info_, prepad);
146 fill_cbor_index(filler, pm_.dev_key_, prepad);
147 fill_cbor_index(filler, pm_.dev_key_pkx_, prepad);
148 fill_cbor_index(filler, pm_.dev_key_pky_, prepad);
149 fill_cbor_index(filler, pm_.value_digests_, prepad);
150 fill_cbor_index(filler, pm_.org_, prepad);
153 for (
size_t ai = 0; ai < num_attr_; ++ai) {
154 for (
size_t i = 0; i < 2 * 64; ++i) {
155 filler.push_back(attr_bytes_[ai][i], 8, ec_.f_);
157 for (
size_t j = 0; j < 2; j++) {
158 fill_sha(filler, atw_[ai][j]);
164 fill_cbor_index(filler, attr_mso_[ai], prepad);
165 fill_attr_shift(filler, attr_ei_[ai]);
166 fill_attr_shift(filler, attr_ev_[ai]);
170 bool compute_witness(Elt pkX, Elt pkY,
const uint8_t mdoc[],
171 size_t len,
const uint8_t transcript[],
172 size_t tlen,
const uint8_t tnow[],
174 if (!pm_.parse_device_response(len, mdoc)) {
177 if (pm_.t_mso_.len >= kMdoc1MaxSHABlocks * 64 - 9 - kCose1PrefixLen) {
178 log(ERROR,
"tagged mso is too big: %zu", pm_.t_mso_.len);
182 Nat ne = nat_from_hash<Nat>(pm_.tagged_mso_bytes_.data(),
183 pm_.tagged_mso_bytes_.size());
184 e_ = ec_.f_.to_montgomery(ne);
187 const size_t l = pm_.sig_.len;
188 Nat nr = nat_from_be<Nat>(&mdoc[pm_.sig_.pos]);
189 Nat ns = nat_from_be<Nat>(&mdoc[pm_.sig_.pos + l / 2]);
190 ew_.compute_witness(pkX, pkY, ne, nr, ns);
192 Nat ne2 = compute_transcript_hash<Nat>(transcript, tlen, &pm_.doc_type_);
193 const size_t l2 = pm_.dksig_.len;
194 Nat nr2 = nat_from_be<Nat>(&mdoc[pm_.dksig_.pos]);
195 Nat ns2 = nat_from_be<Nat>(&mdoc[pm_.dksig_.pos + l2 / 2]);
196 size_t pmso = pm_.t_mso_.pos + 5;
197 dpkx_ = ec_.f_.to_montgomery(
198 nat_from_be<Nat>(&mdoc[pmso + pm_.dev_key_pkx_.pos]));
199 dpky_ = ec_.f_.to_montgomery(
200 nat_from_be<Nat>(&mdoc[pmso + pm_.dev_key_pky_.pos]));
201 e2_ = ec_.f_.to_montgomery(ne2);
202 dkw_.compute_witness(dpkx_, dpky_, ne2, nr2, ns2);
204 memcpy(now_, tnow, kMdoc1DateLen);
205 std::vector<uint8_t> buf;
207 buf.assign(std::begin(kCose1Prefix), std::end(kCose1Prefix));
209 buf.push_back((pm_.t_mso_.len >> 8) & 0xff);
210 buf.push_back(pm_.t_mso_.len & 0xff);
211 for (
size_t i = 0; i < pm_.t_mso_.len; ++i) {
212 buf.push_back(mdoc[pm_.t_mso_.pos + i]);
215 FlatSHA256Witness::transform_and_witness_message(
216 buf.size(), buf.data(), kMdoc1MaxSHABlocks, numb_, signed_bytes_, bw_);
221 size_t prepad = kMdoc1MaxMsoLen - pm_.t_mso_.len + 5;
223 buf.erase(buf.begin(), buf.begin() + kCose1PrefixLen + 2 + 5);
224 buf.insert(buf.begin(), prepad, 0);
226 CborWitness cw(ec_.f_);
227 cw.fill_witnesses(kMdoc1MaxMsoLen, pm_.t_mso_.len, buf.data(), incb_.data(),
228 pwcb_.data(), gwcb_);
231 for (
size_t i = 0; i < num_attr_; ++i) {
232 attr_bytes_[i].resize(128);
237 for (
size_t i = 0; i < num_attr_; ++i) {
239 for (
auto fa : pm_.attributes_) {
240 if (fa == attrs[i]) {
241 FlatSHA256Witness::transform_and_witness_message(
242 fa.tag_len, &fa.doc[fa.tag_ind], 2, attr_n_[i],
243 &attr_bytes_[i][0], &atw_[i][0]);
244 attr_mso_[i] = fa.mso;
245 attr_ei_[i].offset = fa.id_ind - fa.tag_ind;
246 attr_ei_[i].len = fa.witness_length(attrs[i]);
247 attr_ev_[i].offset = fa.val_ind - fa.tag_ind;
248 attr_ev_[i].len = fa.val_len;
254 log(ERROR,
"Could not find attribute %.*s", attrs[i].id_len,