45 using v8 =
typename LogicCircuit::v8;
46 using v32 =
typename LogicCircuit::v32;
47 using v256 =
typename LogicCircuit::v256;
49 using vind =
typename LogicCircuit::template bitvec<kCborIndexBits>;
53 using ShaBlockWitness =
typename Flatsha::BlockWitness;
54 using sha_packed_v32 =
typename Flatsha::packed_v32;
63 void input(
const LogicCircuit& lc) {
64 for (
size_t j = 0; j < 32; ++j) {
65 attr[j] = lc.template vinput<8>();
67 for (
size_t j = 0; j < 64; ++j) {
68 v1[j] = lc.template vinput<8>();
70 len = lc.template vinput<8>();
75 void input(
const LogicCircuit& lc) {
76 k = lc.template vinput<kCborIndexBits>();
83 void input(
const LogicCircuit& lc) {
84 offset = lc.template vinput<kCborIndexBits>();
85 len = lc.template vinput<kCborIndexBits>();
91 v8 in_[64 * kMaxSHABlocks];
94 ShaBlockWitness sig_sha_[kMaxSHABlocks];
96 std::vector<std::vector<ShaBlockWitness>> attr_sha_;
97 std::vector<std::vector<v8>> attrb_;
102 std::vector<CborIndex> attr_mso_;
103 std::vector<AttrShift> attr_ei_;
104 std::vector<AttrShift> attr_ev_;
107 explicit Witness(
size_t num_attr) {
108 num_attr_ = num_attr;
109 attr_mso_.resize(num_attr);
110 attr_ei_.resize(num_attr);
111 attr_ev_.resize(num_attr);
112 attr_sha_.resize(num_attr);
113 for (
size_t i = 0; i < num_attr; ++i) {
114 attr_sha_[i].resize(2);
117 attrb_.resize(num_attr);
121 nb_ = lc.template vinput<8>();
124 for (
size_t i = 0; i + kCose1PrefixLen < 64 * kMaxSHABlocks; ++i) {
125 in_[i] = lc.template vinput<8>();
127 for (
size_t j = 0; j < kMaxSHABlocks; j++) {
128 sig_sha_[j].input(Q);
131 valid_from_.input(lc);
132 valid_until_.input(lc);
133 dev_key_info_.input(lc);
134 value_digests_.input(lc);
137 for (
size_t ai = 0; ai < num_attr_; ++ai) {
138 for (
size_t i = 0; i < 64 * 2; ++i) {
139 attrb_[ai].push_back(lc.template vinput<8>());
141 for (
size_t j = 0; j < 2; j++) {
142 attr_sha_[ai][j].input(Q);
144 attr_mso_[ai].input(lc);
145 attr_ei_[ai].input(lc);
146 attr_ev_[ai].input(lc);
151 explicit MdocHash(
const LogicCircuit& lc) : lc_(lc), sha_(lc), r_(lc) {}
154 const v8 now[],
const v256& e,
155 const v256& dpkx,
const v256& dpky,
156 const Witness& vw)
const {
157 sha_.assert_message_hash_with_prefix(kMaxSHABlocks, vw.nb_, vw.in_,
158 kCose1Prefix, kCose1PrefixLen, e,
162 const v8 zz = lc_.template vbit<8>(0);
163 std::vector<v8> cmp_buf(kMaxMsoLen);
171 r_.shift(vw.valid_from_.k, kValidFromLen + kDateLen, &cmp_buf[0],
172 kMaxMsoLen, vw.in_ + 5 + 2, zz, 3);
173 assert_bytes_at(kValidFromLen, &cmp_buf[0], kValidFromCheck);
174 auto cmp = CMP.leq(kDateLen, &cmp_buf[kValidFromLen], &now[0]);
178 r_.shift(vw.valid_until_.k, kValidUntilLen + kDateLen, &cmp_buf[0],
179 kMaxMsoLen, vw.in_ + 5 + 2, zz, 3);
180 assert_bytes_at(kValidUntilLen, &cmp_buf[0], kValidUntilCheck);
181 cmp = CMP.leq(kDateLen, &now[0], &cmp_buf[kValidUntilLen]);
185 r_.shift(vw.dev_key_info_.k, kDeviceKeyInfoLen + 3 + 32 + 32, &cmp_buf[0],
186 kMaxMsoLen, vw.in_ + 5 + 2, zz, 3);
187 assert_bytes_at(kDeviceKeyInfoLen, &cmp_buf[0], kDeviceKeyInfoCheck);
188 uint8_t dpkyCheck[] = {0x22, 0x58, 0x20};
189 assert_bytes_at(
sizeof(dpkyCheck), &cmp_buf[65], dpkyCheck);
191 assert_key(dpkx, &cmp_buf[kPkxInd]);
192 assert_key(dpky, &cmp_buf[kPkyInd]);
196 r_.shift(vw.value_digests_.k, kValueDigestsLen, cmp_buf.data(), kMaxMsoLen,
197 vw.in_ + 5 + 2, zz, 3);
198 assert_bytes_at(13, &cmp_buf[0], kValueDigestsCheck);
201 for (
size_t ai = 0; ai < vw.num_attr_; ++ai) {
204 r_.shift(vw.attr_mso_[ai].k, 2 + 32, &cmp_buf[0], kMaxMsoLen,
205 vw.in_ + 5 + 2, zz, 3);
208 assert_bytes_at(2, &cmp_buf[0], kTag32);
212 for (
size_t j = 0; j < 256; ++j) {
213 mm[j] = cmp_buf[2 + (255 - j) / 8][(j % 8)];
216 auto two = lc_.template vbit<8>(2);
217 sha_.assert_message_hash(2, two, vw.attrb_[ai].data(), mm,
218 vw.attr_sha_[ai].data());
221 r_.shift(vw.attr_ei_[ai].offset, 96, B, 128, vw.attrb_[ai].data(), zz, 3);
222 assert_attribute(96, oa[ai].len, B, oa[ai]);
227 void assert_bytes_at(
size_t len,
const v8 buf[],
228 const uint8_t want[])
const {
229 for (
size_t i = 0; i < len; ++i) {
230 auto want_i = lc_.template vbit<8>(want[i]);
231 lc_.vassert_eq(&buf[i], want_i);
237 void assert_attribute(
size_t max,
const v8& len,
const v8 got[],
241 for (
size_t j = 0; j < 32; ++j) {
242 want[j] = oa.attr[j];
244 for (
size_t j = 0; j < 64; ++j) {
245 want[32 + j] = oa.v1[j];
249 for (
size_t j = 0; j < max; ++j) {
250 auto ll = lc_.vlt(j, len);
251 auto same = lc_.eq(8, got[j].data(), want[j].data());
252 lc_.assert_implies(&ll, same);
257 void assert_key(v256 key,
const v8 buf_be[])
const {
259 for (
size_t i = 0; i < 256; ++i) {
260 m[i] = buf_be[31 - (i / 8)][i % 8];
262 lc_.vassert_eq(&m, key);
274 static constexpr uint8_t kValidFromCheck[] = {
275 0x69, 0x76, 0x61, 0x6C, 0x69, 0x64, 0x46, 0x72, 0x6F, 0x6D, 0xC0, 0x74};
276 static constexpr size_t kValidFromLen =
sizeof(kValidFromCheck);
279 static constexpr uint8_t kValidUntilCheck[] = {0x6A, 0x76, 0x61, 0x6C, 0x69,
280 0x64, 0x55, 0x6E, 0x74, 0x69,
282 static constexpr size_t kValidUntilLen =
sizeof(kValidUntilCheck);
291 static constexpr uint8_t kDeviceKeyInfoCheck[] = {
292 0x6D, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4B, 0x65, 0x79, 0x49,
293 0x6E, 0x66, 0x6F, 0xA1, 0x69, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65,
294 0x4B, 0x65, 0x79, 0xA4, 0x01, 0x02, 0x20, 0x01, 0x21, 0x58, 0x20};
295 static constexpr size_t kDeviceKeyInfoLen =
sizeof(kDeviceKeyInfoCheck);
296 static constexpr size_t kPkxInd = kDeviceKeyInfoLen;
297 static constexpr size_t kPkyInd = 68;
301 static constexpr uint8_t kValueDigestsCheck[] = {
302 0x6C, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x44, 0x69, 0x67,
303 0x65, 0x73, 0x74, 0x73,
305 static constexpr size_t kValueDigestsLen =
sizeof(kValueDigestsCheck);
307 static constexpr size_t kDateLen = 20;
309 const LogicCircuit& lc_;
311 Routing<LogicCircuit> r_;