1use crate::combinators::{
3 mapped::spec::{LosslessMapper, LossyMapper, SpecMap, SpecMapper},
4 Bind, Bits, Const, Empty, Mapped, Refined, Sum, U16Be, U32Be, U64Be, Void, U8,
5};
6use crate::core::exec::{
7 input::{InputBuf, InputSlice},
8 output::OutputBuf,
9 parser::{PResult, Parser},
10 serializer::{ByteLen, PreSerializeError, Prepare, Serializer},
11 ParseError,
12};
13use crate::core::{proof::*, spec::*};
14use crate::Never;
15use vstd::assert_seqs_equal;
16use vstd::prelude::*;
17
18use super::CborFloat;
19use Sum::Inl as L;
20use Sum::Inr as R;
21
22verus! {
23
24pub const ADDITIONAL_INFO_MASK: u8 = 0x1fu8;
25
26#[derive(Debug, Clone, Copy, PartialEq, Eq, Structural)]
28pub struct CborInitial {
29 pub major: u8,
31 pub additional: u8,
33}
34
35impl DeepView for CborInitial {
36 type V = Self;
37
38 open spec fn deep_view(&self) -> Self::V {
39 *self
40 }
41}
42
43#[verifier::allow_in_spec]
44pub fn unpack_initial(raw: u8) -> (fields: (u8, u8))
45 returns
46 ((raw >> 5, raw & ADDITIONAL_INFO_MASK)),
47{
48 (raw >> 5, raw & ADDITIONAL_INFO_MASK)
49}
50
51#[verifier::allow_in_spec]
52pub fn pack_initial(major: u8, additional: u8) -> (raw: u8)
53 returns
54 ((major << 5) | additional),
55{
56 (major << 5) | additional
57}
58
59#[verifier::allow_in_spec]
60pub fn initial_fields_in_bounds(major: u8, additional: u8) -> (valid: bool)
61 returns
62 (major < 8u8 && additional < 32u8),
63{
64 major < 8u8 && additional < 32u8
65}
66
67pub broadcast proof fn lemma_initial_unpack_pack(raw: u8)
68 by (bit_vector)
69 ensures
70 #[trigger] pack_initial(unpack_initial(raw).0, unpack_initial(raw).1) == raw,
71{
72}
73
74pub broadcast proof fn lemma_initial_pack_unpack(major: u8, additional: u8)
75 by (bit_vector)
76 requires
77 #[trigger] initial_fields_in_bounds(major, additional),
78 ensures
79 unpack_initial(pack_initial(major, additional)).0 == major,
80 unpack_initial(pack_initial(major, additional)).1 == additional,
81{
82}
83
84pub broadcast proof fn lemma_initial_unpack_in_bounds(raw: u8)
85 by (bit_vector)
86 ensures
87 #[trigger] initial_fields_in_bounds(unpack_initial(raw).0, unpack_initial(raw).1),
88{
89}
90
91type CborInitialInnerFmt = Bits<U8, (u8, u8), CborInitial>;
92
93pub open spec fn cbor_initial_fmt() -> CborInitialInnerFmt {
94 Bits {
95 repr: U8,
96 unpack: |raw: u8| unpack_initial(raw),
97 pack: |fields: (u8, u8)| pack_initial(fields.0, fields.1),
98 refinement: |_fields: (u8, u8)| true,
99 ctor: |fields: (u8, u8)| CborInitial { major: fields.0, additional: fields.1 },
100 dtor: |initial: CborInitial| (initial.major, initial.additional),
101 consistent: |initial: CborInitial|
102 { initial_fields_in_bounds(initial.major, initial.additional) },
103 }
104}
105
106#[derive(Debug, Clone, Copy)]
108pub struct CborInitialFmt;
109
110impl<'i> Parser<&'i [u8]> for CborInitialFmt {
111 type PT = CborInitial;
112
113 fn parse(&self, input: &&'i [u8]) -> PResult<Self::PT> {
114 let (n, raw) = U8.parse(input)?;
115 let (major, additional) = unpack_initial(raw);
116 Ok((n, CborInitial { major, additional }))
117 }
118}
119
120impl<Output: OutputBuf> Serializer<Output, CborInitial> for CborInitialFmt {
121 fn serialize_into(&self, value: &CborInitial, out: &mut Output) {
122 broadcast use crate::core::exec::output::outbuf_lemmas;
123
124 let ghost old_out = out@;
125 let r = pack_initial(value.major, value.additional);
126 U8.serialize_into(&r, out);
127 assert(out@ == old_out + self.spec_serialize(value.deep_view()));
128 }
129}
130
131impl Prepare<CborInitial> for CborInitialFmt {
132 fn prepare(&self, value: &CborInitial) -> Result<usize, PreSerializeError> {
133 if !initial_fields_in_bounds(value.major, value.additional) {
134 Err(PreSerializeError::custom("CBOR initial-byte field is out of range"))
135 } else {
136 let r = pack_initial(value.major, value.additional);
137 U8.prepare(&r)
138 }
139 }
140}
141
142impl ByteLen<CborInitial> for CborInitialFmt {
143 fn length(&self, value: &CborInitial) -> usize {
144 let r = pack_initial(value.major, value.additional);
145 U8.length(&r)
146 }
147}
148
149#[derive(Debug, Clone, Copy, PartialEq, Eq, Structural)]
151pub enum MajorType {
152 Unsigned,
153 Negative,
154 Bytes,
155 Text,
156 Array,
157 Map,
158 Tag,
159 Simple,
160}
161
162impl DeepView for MajorType {
163 type V = Self;
164
165 open spec fn deep_view(&self) -> Self::V {
166 *self
167 }
168}
169
170#[derive(Debug, Clone, Copy, PartialEq, Eq, Structural)]
172pub enum CborHeadValue {
173 Argument(u64),
174 Indefinite,
175 Simple(u8),
176 Float(CborFloat),
177 Break,
178}
179
180impl DeepView for CborHeadValue {
181 type V = Self;
182
183 open spec fn deep_view(&self) -> Self::V {
184 *self
185 }
186}
187
188#[derive(Debug, Clone, Copy, PartialEq, Eq, Structural)]
190pub struct CborHead {
191 pub major: MajorType,
192 pub value: CborHeadValue,
193}
194
195impl DeepView for CborHead {
196 type V = Self;
197
198 open spec fn deep_view(&self) -> Self::V {
199 *self
200 }
201}
202
203#[verifier::allow_in_spec]
204pub fn major_from_code(code: u8) -> MajorType
205 returns
206 (match code {
207 0 => MajorType::Unsigned,
208 1 => MajorType::Negative,
209 2 => MajorType::Bytes,
210 3 => MajorType::Text,
211 4 => MajorType::Array,
212 5 => MajorType::Map,
213 6 => MajorType::Tag,
214 _ => MajorType::Simple,
215 }),
216{
217 match code {
218 0 => MajorType::Unsigned,
219 1 => MajorType::Negative,
220 2 => MajorType::Bytes,
221 3 => MajorType::Text,
222 4 => MajorType::Array,
223 5 => MajorType::Map,
224 6 => MajorType::Tag,
225 _ => MajorType::Simple,
226 }
227}
228
229#[verifier::allow_in_spec]
230pub fn major_code(major: MajorType) -> u8
231 returns
232 (match major {
233 MajorType::Unsigned => 0u8,
234 MajorType::Negative => 1u8,
235 MajorType::Bytes => 2u8,
236 MajorType::Text => 3u8,
237 MajorType::Array => 4u8,
238 MajorType::Map => 5u8,
239 MajorType::Tag => 6u8,
240 MajorType::Simple => 7u8,
241 }),
242{
243 match major {
244 MajorType::Unsigned => 0u8,
245 MajorType::Negative => 1u8,
246 MajorType::Bytes => 2u8,
247 MajorType::Text => 3u8,
248 MajorType::Array => 4u8,
249 MajorType::Map => 5u8,
250 MajorType::Tag => 6u8,
251 MajorType::Simple => 7u8,
252 }
253}
254
255#[verifier::allow_in_spec]
256pub fn valid_simple(value: u8) -> bool
257 returns
258 (value <= 23u8 || value >= 32u8),
259{
260 value <= 23u8 || value >= 32u8
261}
262
263#[verifier::allow_in_spec]
264pub fn valid_head<const DET: bool>(head: CborHead) -> bool
265 returns
266 (match head.value {
267 CborHeadValue::Argument(_) => head.major != MajorType::Simple,
268 CborHeadValue::Indefinite => !DET && {
269 head.major == MajorType::Bytes || head.major == MajorType::Text || head.major
270 == MajorType::Array || head.major == MajorType::Map
271 },
272 CborHeadValue::Simple(value) => head.major == MajorType::Simple && valid_simple(value),
273 CborHeadValue::Float(_) => head.major == MajorType::Simple,
274 CborHeadValue::Break => head.major == MajorType::Simple,
275 }),
276{
277 match head.value {
278 CborHeadValue::Argument(_) => head.major != MajorType::Simple,
279 CborHeadValue::Indefinite => !DET && {
280 head.major == MajorType::Bytes || head.major == MajorType::Text || head.major
281 == MajorType::Array || head.major == MajorType::Map
282 },
283 CborHeadValue::Simple(value) => head.major == MajorType::Simple && valid_simple(value),
284 CborHeadValue::Float(_) => head.major == MajorType::Simple,
285 CborHeadValue::Break => head.major == MajorType::Simple,
286 }
287}
288
289#[verifier::allow_in_spec]
290pub fn minimal_u8_argument(value: u8) -> bool
291 returns
292 (value >= 24u8),
293{
294 value >= 24u8
295}
296
297#[verifier::allow_in_spec]
298pub fn minimal_u16_argument(value: u16) -> bool
299 returns
300 (value > u8::MAX as u16),
301{
302 value > u8::MAX as u16
303}
304
305#[verifier::allow_in_spec]
306pub fn minimal_u32_argument(value: u32) -> bool
307 returns
308 (value > u16::MAX as u32),
309{
310 value > u16::MAX as u32
311}
312
313#[verifier::allow_in_spec]
314pub fn minimal_u64_argument(value: u64) -> bool
315 returns
316 (value > u32::MAX as u64),
317{
318 value > u32::MAX as u64
319}
320
321type HeadWireValue = Sum<(), Sum<u8, Sum<u16, Sum<u32, Sum<u64, Sum<(), Never>>>>>>;
322
323type HeadBranchesFmt = Sum<Empty, Sum<U8, Sum<U16Be, Sum<U32Be, Sum<U64Be, Sum<Empty, Void>>>>>>;
324
325type HeadWireFmt<const DET: bool> = Bind<CborInitialFmt, spec_fn(CborInitial) -> HeadBranchesFmt>;
326
327type RefinedHeadWireFmt<const DET: bool> = Refined<
328 HeadWireFmt<DET>,
329 PredFnSpec<(CborInitial, HeadWireValue)>,
330>;
331
332type HeadMappedFmt<const DET: bool> = Mapped<RefinedHeadWireFmt<DET>, HeadMapper<DET>>;
333
334pub open spec fn head_wire<const DET: bool>() -> HeadWireFmt<DET> {
335 Bind(
336 CborInitialFmt,
337 |initial: CborInitial|
338 {
339 let major = major_from_code(initial.major);
340 match initial.additional {
341 ai if ai <= 23u8 => L(Empty),
342 24u8 => R(L(U8)),
343 25u8 => R(R(L(U16Be))),
344 26u8 => R(R(R(L(U32Be)))),
345 27u8 => R(R(R(R(L(U64Be))))),
346 31u8 if major == MajorType::Bytes || major == MajorType::Text || major
347 == MajorType::Array || major == MajorType::Map || major
348 == MajorType::Simple => R(R(R(R(R(L(Empty)))))),
349 _ => R(R(R(R(R(R(Void("Reserved or invalid CBOR additional information"))))))),
350 }
351 },
352 )
353}
354
355pub open spec fn valid_head_wire<const DET: bool>(wire: (CborInitial, HeadWireValue)) -> bool {
356 let major = major_from_code(wire.0.major);
357 match wire.1 {
358 L(()) => true,
359 R(L(value)) => {
360 if major == MajorType::Simple {
361 value >= 32u8
362 } else {
363 DET ==> minimal_u8_argument(value)
364 }
365 },
366 R(R(L(value))) => major == MajorType::Simple || (DET ==> minimal_u16_argument(value)),
367 R(R(R(L(value)))) => major == MajorType::Simple || (DET ==> minimal_u32_argument(value)),
368 R(R(R(R(L(value))))) => major == MajorType::Simple || (DET ==> minimal_u64_argument(value)),
369 R(R(R(R(R(L(())))))) => major == MajorType::Simple || !DET,
370 _ => false,
371 }
372}
373
374pub open spec fn decode_head_wire(wire: (CborInitial, HeadWireValue)) -> CborHead {
375 let (initial, rest) = wire;
376 let major = major_from_code(initial.major);
377 let ai = initial.additional;
378 let value = match rest {
379 L(()) => {
380 if major == MajorType::Simple {
381 CborHeadValue::Simple(ai)
382 } else {
383 CborHeadValue::Argument(ai as u64)
384 }
385 },
386 R(L(value)) => {
387 if major == MajorType::Simple {
388 CborHeadValue::Simple(value)
389 } else {
390 CborHeadValue::Argument(value as u64)
391 }
392 },
393 R(R(L(value))) => {
394 if major == MajorType::Simple {
395 CborHeadValue::Float(CborFloat::F16(value))
396 } else {
397 CborHeadValue::Argument(value as u64)
398 }
399 },
400 R(R(R(L(value)))) => {
401 if major == MajorType::Simple {
402 CborHeadValue::Float(CborFloat::F32(value))
403 } else {
404 CborHeadValue::Argument(value as u64)
405 }
406 },
407 R(R(R(R(L(value))))) => {
408 if major == MajorType::Simple {
409 CborHeadValue::Float(CborFloat::F64(value))
410 } else {
411 CborHeadValue::Argument(value)
412 }
413 },
414 R(R(R(R(R(L(())))))) => {
415 if major == MajorType::Simple {
416 CborHeadValue::Break
417 } else {
418 CborHeadValue::Indefinite
419 }
420 },
421 _ => arbitrary(),
422 };
423 CborHead { major, value }
424}
425
426pub open spec fn encode_head_wire(head: CborHead) -> (CborInitial, HeadWireValue) {
427 let major = major_code(head.major);
428 match head.value {
429 CborHeadValue::Argument(value) => {
430 if value <= 23u64 {
431 (CborInitial { major, additional: value as u8 }, L(()))
432 } else if value <= u8::MAX as u64 {
433 (CborInitial { major, additional: 24u8 }, R(L(value as u8)))
434 } else if value <= u16::MAX as u64 {
435 (CborInitial { major, additional: 25u8 }, R(R(L(value as u16))))
436 } else if value <= u32::MAX as u64 {
437 (CborInitial { major, additional: 26u8 }, R(R(R(L(value as u32)))))
438 } else {
439 (CborInitial { major, additional: 27u8 }, R(R(R(R(L(value))))))
440 }
441 },
442 CborHeadValue::Indefinite => (
443 CborInitial { major, additional: 31u8 },
444 R(R(R(R(R(L(())))))),
445 ),
446 CborHeadValue::Simple(value) => {
447 if value <= 23u8 {
448 (CborInitial { major, additional: value }, L(()))
449 } else {
450 (CborInitial { major, additional: 24u8 }, R(L(value)))
451 }
452 },
453 CborHeadValue::Float(CborFloat::F16(value)) => {
454 (CborInitial { major, additional: 25u8 }, R(R(L(value))))
455 },
456 CborHeadValue::Float(CborFloat::F32(value)) => {
457 (CborInitial { major, additional: 26u8 }, R(R(R(L(value)))))
458 },
459 CborHeadValue::Float(CborFloat::F64(value)) => {
460 (CborInitial { major, additional: 27u8 }, R(R(R(R(L(value))))))
461 },
462 CborHeadValue::Break => (CborInitial { major, additional: 31u8 }, R(R(R(R(R(L(()))))))),
463 }
464}
465
466#[derive(Clone, Copy)]
467pub struct HeadMapper<const DET: bool>;
468
469impl<const DET: bool> SpecMapper for HeadMapper<DET> {
470 type In = (CborInitial, HeadWireValue);
471
472 type Out = CborHead;
473
474 open spec fn spec_map(&self, wire: Self::In) -> Self::Out {
475 decode_head_wire(wire)
476 }
477
478 open spec fn spec_map_rev(&self, head: Self::Out) -> Self::In {
479 encode_head_wire(head)
480 }
481
482 open spec fn wf_in(&self, wire: Self::In) -> bool {
483 &&& head_wire::<DET>().consistent(wire)
484 &&& valid_head_wire::<DET>(wire)
485 }
486
487 open spec fn wf_out(&self, head: Self::Out) -> bool {
488 valid_head::<DET>(head)
489 }
490}
491
492impl<const DET: bool> LossyMapper for HeadMapper<DET> {
493 proof fn lemma_sound_mapper(&self, head: Self::Out) {
494 match head.value {
495 CborHeadValue::Argument(value) => {
496 if value <= 23u64 {
497 assert((value as u8) as u64 == value) by (bit_vector)
498 requires
499 value <= 23u64,
500 ;
501 } else if value <= u8::MAX as u64 {
502 assert((value as u8) as u64 == value) by (bit_vector)
503 requires
504 value <= u8::MAX as u64,
505 ;
506 } else if value <= u16::MAX as u64 {
507 assert((value as u16) as u64 == value) by (bit_vector)
508 requires
509 value <= u16::MAX as u64,
510 ;
511 } else if value <= u32::MAX as u64 {
512 assert((value as u32) as u64 == value) by (bit_vector)
513 requires
514 value <= u32::MAX as u64,
515 ;
516 }
517 },
518 _ => {},
519 }
520 }
521
522 proof fn lemma_mapper_wf_out_in(&self, head: Self::Out) {
523 }
524}
525
526impl LosslessMapper for HeadMapper<true> {
527 proof fn lemma_lossless_mapper(&self, wire: Self::In) {
528 }
529
530 proof fn lemma_mapper_wf_in_out(&self, wire: Self::In) {
531 }
532}
533
534pub open spec fn cbor_head_fmt<const DET: bool>() -> HeadMappedFmt<DET> {
535 Mapped {
536 inner: Refined(
537 head_wire::<DET>(),
538 |wire: (CborInitial, HeadWireValue)| valid_head_wire::<DET>(wire),
539 ),
540 mapper: HeadMapper::<DET>,
541 }
542}
543
544#[derive(Debug, Clone, Copy)]
550pub struct CborHeadFmt<const DET: bool>;
551
552pub type BreakFmt = Const<U8, u8>;
553
554pub const BREAK: BreakFmt = Const(U8, 0xffu8);
556
557impl<'i, const DET: bool> Parser<&'i [u8]> for CborHeadFmt<DET> {
558 type PT = CborHead;
559
560 fn parse(&self, input: &&'i [u8]) -> PResult<Self::PT> {
561 broadcast use crate::core::spec::SafeParser::lemma_parse_safe;
562
563 let (n1, initial) = CborInitialFmt.parse(input)?;
564 let major = major_from_code(initial.major);
565 let ai = initial.additional;
566 let rest = input.skip(n1);
567
568 match ai {
569 0..=23 => {
570 let value = if major == MajorType::Simple {
571 CborHeadValue::Simple(ai)
572 } else {
573 CborHeadValue::Argument(ai as u64)
574 };
575 Ok((1, CborHead { major, value }))
576 },
577 24 => {
578 let (_, value) = U8.parse(&rest)?;
579 if major == MajorType::Simple {
580 if value < 32 {
581 Err(ParseError::invalid_tag())
582 } else {
583 Ok((2, CborHead { major, value: CborHeadValue::Simple(value) }))
584 }
585 } else if DET && !minimal_u8_argument(value) {
586 Err(ParseError::non_canonical())
587 } else {
588 Ok((2, CborHead { major, value: CborHeadValue::Argument(value as u64) }))
589 }
590 },
591 25 => {
592 let (_, value) = U16Be.parse(&rest)?;
593 if major == MajorType::Simple {
594 Ok((3, CborHead { major, value: CborHeadValue::Float(CborFloat::F16(value)) }))
595 } else if DET && !minimal_u16_argument(value) {
596 Err(ParseError::non_canonical())
597 } else {
598 Ok((3, CborHead { major, value: CborHeadValue::Argument(value as u64) }))
599 }
600 },
601 26 => {
602 let (_, value) = U32Be.parse(&rest)?;
603 if major == MajorType::Simple {
604 Ok((5, CborHead { major, value: CborHeadValue::Float(CborFloat::F32(value)) }))
605 } else if DET && !minimal_u32_argument(value) {
606 Err(ParseError::non_canonical())
607 } else {
608 Ok((5, CborHead { major, value: CborHeadValue::Argument(value as u64) }))
609 }
610 },
611 27 => {
612 let (_, value) = U64Be.parse(&rest)?;
613 if major == MajorType::Simple {
614 Ok((9, CborHead { major, value: CborHeadValue::Float(CborFloat::F64(value)) }))
615 } else if DET && !minimal_u64_argument(value) {
616 Err(ParseError::non_canonical())
617 } else {
618 Ok((9, CborHead { major, value: CborHeadValue::Argument(value) }))
619 }
620 },
621 31 => {
622 if !DET && (major == MajorType::Bytes || major == MajorType::Text || major
623 == MajorType::Array || major == MajorType::Map) {
624 Ok((1, CborHead { major, value: CborHeadValue::Indefinite }))
625 } else if major == MajorType::Simple {
626 Ok((1, CborHead { major, value: CborHeadValue::Break }))
627 } else {
628 Err(ParseError::invalid_tag())
629 }
630 },
631 _ => Err(ParseError::invalid_tag()),
632 }
633 }
634}
635
636impl<Output: OutputBuf, const DET: bool> Serializer<Output, CborHead> for CborHeadFmt<DET> {
637 fn serialize_into(&self, head: &CborHead, out: &mut Output) {
638 broadcast use crate::core::exec::output::outbuf_lemmas;
639
640 let ghost old_out = out@;
641 let major = major_code(head.major);
642 match head.value {
643 CborHeadValue::Argument(value) => {
644 if value <= 23 {
645 CborInitialFmt.serialize_into(
646 &CborInitial { major, additional: value as u8 },
647 out,
648 );
649 } else if value <= u8::MAX as u64 {
650 CborInitialFmt.serialize_into(&CborInitial { major, additional: 24 }, out);
651 U8.serialize_into(&(value as u8), out);
652 } else if value <= u16::MAX as u64 {
653 CborInitialFmt.serialize_into(&CborInitial { major, additional: 25 }, out);
654 U16Be.serialize_into(&(value as u16), out);
655 } else if value <= u32::MAX as u64 {
656 CborInitialFmt.serialize_into(&CborInitial { major, additional: 26 }, out);
657 U32Be.serialize_into(&(value as u32), out);
658 } else {
659 CborInitialFmt.serialize_into(&CborInitial { major, additional: 27 }, out);
660 U64Be.serialize_into(&value, out);
661 }
662 },
663 CborHeadValue::Indefinite => {
664 CborInitialFmt.serialize_into(&CborInitial { major, additional: 31 }, out);
665 },
666 CborHeadValue::Simple(value) => {
667 if value <= 23 {
668 CborInitialFmt.serialize_into(&CborInitial { major, additional: value }, out);
669 } else {
670 CborInitialFmt.serialize_into(&CborInitial { major, additional: 24 }, out);
671 U8.serialize_into(&value, out);
672 }
673 },
674 CborHeadValue::Float(CborFloat::F16(value)) => {
675 CborInitialFmt.serialize_into(&CborInitial { major, additional: 25 }, out);
676 U16Be.serialize_into(&value, out);
677 },
678 CborHeadValue::Float(CborFloat::F32(value)) => {
679 CborInitialFmt.serialize_into(&CborInitial { major, additional: 26 }, out);
680 U32Be.serialize_into(&value, out);
681 },
682 CborHeadValue::Float(CborFloat::F64(value)) => {
683 CborInitialFmt.serialize_into(&CborInitial { major, additional: 27 }, out);
684 U64Be.serialize_into(&value, out);
685 },
686 CborHeadValue::Break => {
687 CborInitialFmt.serialize_into(
688 &CborInitial { major: major_code(MajorType::Simple), additional: 31 },
689 out,
690 );
691 },
692 }
693
694 assert(out@ =~= old_out + self.spec_serialize(head.deep_view()));
695 }
696}
697
698pub fn head_len<const DET: bool>(head: &CborHead) -> (len: usize)
699 ensures
700 len == CborHeadFmt::<DET>.byte_len(head.deep_view()),
701{
702 let len = match head.value {
703 CborHeadValue::Argument(value) => {
704 if value <= 23 {
705 1
706 } else if value <= u8::MAX as u64 {
707 2
708 } else if value <= u16::MAX as u64 {
709 3
710 } else if value <= u32::MAX as u64 {
711 5
712 } else {
713 9
714 }
715 },
716 CborHeadValue::Indefinite => 1,
717 CborHeadValue::Simple(value) => if value <= 23 {
718 1
719 } else {
720 2
721 },
722 CborHeadValue::Float(CborFloat::F16(_)) => 3,
723 CborHeadValue::Float(CborFloat::F32(_)) => 5,
724 CborHeadValue::Float(CborFloat::F64(_)) => 9,
725 CborHeadValue::Break => 1,
726 };
727 len
728}
729
730impl<const DET: bool> Prepare<CborHead> for CborHeadFmt<DET> {
731 fn prepare(&self, head: &CborHead) -> Result<usize, PreSerializeError> {
732 if !valid_head::<DET>(*head) {
733 Err(PreSerializeError::custom("Invalid CBOR head"))
734 } else {
735 let len = head_len::<DET>(head);
736 Ok(len)
737 }
738 }
739}
740
741impl<const DET: bool> ByteLen<CborHead> for CborHeadFmt<DET> {
742 fn length(&self, head: &CborHead) -> usize {
743 head_len::<DET>(head)
744 }
745}
746
747mod derived_specs {
748 use super::*;
749
750 impl SpecParser for CborInitialFmt {
751 type PVal = CborInitial;
752
753 open spec fn spec_parse(&self, input: Seq<u8>) -> Option<(int, Self::PVal)> {
754 cbor_initial_fmt().spec_parse(input)
755 }
756 }
757
758 impl Consistency for CborInitialFmt {
759 type Val = CborInitial;
760
761 open spec fn consistent(&self, value: Self::Val) -> bool {
762 cbor_initial_fmt().consistent(value)
763 }
764 }
765
766 impl SpecSerializerDps for CborInitialFmt {
767 type SValue = CborInitial;
768
769 open spec fn spec_serialize_dps(&self, value: Self::SValue, out: Seq<u8>) -> Seq<u8> {
770 cbor_initial_fmt().spec_serialize_dps(value, out)
771 }
772 }
773
774 impl SpecSerializer for CborInitialFmt {
775 type SVal = CborInitial;
776
777 open spec fn spec_serialize(&self, value: Self::SVal) -> Seq<u8> {
778 cbor_initial_fmt().spec_serialize(value)
779 }
780 }
781
782 impl SpecByteLen for CborInitialFmt {
783 type T = CborInitial;
784
785 open spec fn byte_len(&self, value: Self::T) -> nat {
786 cbor_initial_fmt().byte_len(value)
787 }
788 }
789
790 impl<const DET: bool> SpecParser for CborHeadFmt<DET> {
791 type PVal = CborHead;
792
793 open spec fn spec_parse(&self, input: Seq<u8>) -> Option<(int, Self::PVal)> {
794 cbor_head_fmt::<DET>().spec_parse(input)
795 }
796 }
797
798 impl<const DET: bool> Consistency for CborHeadFmt<DET> {
799 type Val = CborHead;
800
801 open spec fn consistent(&self, value: Self::Val) -> bool {
802 cbor_head_fmt::<DET>().consistent(value)
803 }
804 }
805
806 impl<const DET: bool> SpecSerializerDps for CborHeadFmt<DET> {
807 type SValue = CborHead;
808
809 open spec fn spec_serialize_dps(&self, value: Self::SValue, out: Seq<u8>) -> Seq<u8> {
810 cbor_head_fmt::<DET>().spec_serialize_dps(value, out)
811 }
812 }
813
814 impl<const DET: bool> SpecSerializer for CborHeadFmt<DET> {
815 type SVal = CborHead;
816
817 open spec fn spec_serialize(&self, value: Self::SVal) -> Seq<u8> {
818 cbor_head_fmt::<DET>().spec_serialize(value)
819 }
820 }
821
822 impl<const DET: bool> SpecByteLen for CborHeadFmt<DET> {
823 type T = CborHead;
824
825 open spec fn byte_len(&self, value: Self::T) -> nat {
826 cbor_head_fmt::<DET>().byte_len(value)
827 }
828 }
829
830}
831
832mod derived_proofs {
833 use super::*;
834
835 impl SafeParser for CborInitialFmt {
836 proof fn lemma_parse_safe(&self, input: Seq<u8>) {
837 cbor_initial_fmt().lemma_parse_safe(input);
838 }
839 }
840
841 impl Productive for CborInitialFmt {
842 proof fn lemma_productive(&self, input: Seq<u8>) {
843 cbor_initial_fmt().lemma_productive(input);
844 }
845 }
846
847 impl SoundParser for CborInitialFmt {
848 proof fn lemma_parse_sound_consumption(&self, input: Seq<u8>) {
849 broadcast use lemma_initial_unpack_pack, lemma_initial_unpack_in_bounds;
850
851 let fmt = cbor_initial_fmt();
852 assert(fmt.sound_inv());
853 fmt.lemma_parse_sound_consumption(input);
854 }
855
856 proof fn lemma_parse_sound_value(&self, input: Seq<u8>) {
857 broadcast use lemma_initial_unpack_pack, lemma_initial_unpack_in_bounds;
858
859 let fmt = cbor_initial_fmt();
860 assert(fmt.sound_inv());
861 fmt.lemma_parse_sound_value(input);
862 }
863 }
864
865 impl NonTailFmt for CborInitialFmt {
866 proof fn lemma_serialize_dps_prepend(&self, value: Self::SValue, out: Seq<u8>) {
867 cbor_initial_fmt().lemma_serialize_dps_prepend(value, out);
868 }
869
870 proof fn lemma_serialize_dps_len(&self, value: Self::SValue, out: Seq<u8>) {
871 cbor_initial_fmt().lemma_serialize_dps_len(value, out);
872 }
873 }
874
875 impl GoodSerializer for CborInitialFmt {
876 proof fn lemma_serialize_len(&self, value: Self::SVal) {
877 cbor_initial_fmt().lemma_serialize_len(value);
878 }
879 }
880
881 impl SPRoundTripDps for CborInitialFmt {
882 proof fn theorem_serialize_dps_parse_roundtrip(&self, value: Self::T, out: Seq<u8>) {
883 broadcast use lemma_initial_pack_unpack;
884
885 let fmt = cbor_initial_fmt();
886 assert(fmt.unambiguous());
887 fmt.theorem_serialize_dps_parse_roundtrip(value, out);
888 }
889 }
890
891 impl NonMalleable for CborInitialFmt {
892 proof fn lemma_parse_non_malleable(&self, left: Seq<u8>, right: Seq<u8>) {
893 broadcast use lemma_initial_unpack_pack, lemma_initial_unpack_in_bounds;
894
895 cbor_initial_fmt().lemma_parse_non_malleable(left, right);
896 }
897 }
898
899 impl NoLookAhead for CborInitialFmt {
900 proof fn lemma_no_lookahead(&self, left: Seq<u8>, right: Seq<u8>) {
901 cbor_initial_fmt().lemma_no_lookahead(left, right);
902 }
903 }
904
905 impl EquivSerializersGeneral for CborInitialFmt {
906 proof fn lemma_serialize_equiv(&self, value: Self::SVal, out: Seq<u8>) {
907 cbor_initial_fmt().lemma_serialize_equiv(value, out);
908 }
909 }
910
911 impl EquivSerializers for CborInitialFmt {
912 proof fn lemma_serialize_equiv_on_empty(&self, value: Self::SVal) {
913 cbor_initial_fmt().lemma_serialize_equiv_on_empty(value);
914 }
915 }
916
917 impl<const DET: bool> SafeParser for CborHeadFmt<DET> {
918 proof fn lemma_parse_safe(&self, input: Seq<u8>) {
919 cbor_head_fmt::<DET>().lemma_parse_safe(input);
920 }
921 }
922
923 impl<const DET: bool> Productive for CborHeadFmt<DET> {
924 proof fn lemma_productive(&self, input: Seq<u8>) {
925 cbor_head_fmt::<DET>().lemma_productive(input);
926 }
927 }
928
929 impl SoundParser for CborHeadFmt<true> {
930 proof fn lemma_parse_sound_consumption(&self, input: Seq<u8>) {
931 cbor_head_fmt::<true>().lemma_parse_sound_consumption(input);
932 }
933
934 proof fn lemma_parse_sound_value(&self, input: Seq<u8>) {
935 cbor_head_fmt::<true>().lemma_parse_sound_value(input);
936 }
937 }
938
939 impl<const DET: bool> GoodSerializer for CborHeadFmt<DET> {
940 proof fn lemma_serialize_len(&self, value: Self::SVal) {
941 cbor_head_fmt::<DET>().lemma_serialize_len(value);
942 }
943 }
944
945 impl<const DET: bool> NonTailFmt for CborHeadFmt<DET> {
946 proof fn lemma_serialize_dps_prepend(&self, value: Self::SValue, out: Seq<u8>) {
947 cbor_head_fmt::<DET>().lemma_serialize_dps_prepend(value, out);
948 }
949
950 proof fn lemma_serialize_dps_len(&self, value: Self::SValue, out: Seq<u8>) {
951 cbor_head_fmt::<DET>().lemma_serialize_dps_len(value, out);
952 }
953 }
954
955 impl<const DET: bool> SPRoundTripDps for CborHeadFmt<DET> {
956 proof fn theorem_serialize_dps_parse_roundtrip(&self, value: Self::T, out: Seq<u8>) {
957 cbor_head_fmt::<DET>().theorem_serialize_dps_parse_roundtrip(value, out);
958 }
959 }
960
961 impl NonMalleable for CborHeadFmt<true> {
962 proof fn lemma_parse_non_malleable(&self, left: Seq<u8>, right: Seq<u8>) {
963 cbor_head_fmt::<true>().lemma_parse_non_malleable(left, right);
964 }
965 }
966
967 impl<const DET: bool> NoLookAhead for CborHeadFmt<DET> {
968 proof fn lemma_no_lookahead(&self, i1: Seq<u8>, i2: Seq<u8>) {
969 cbor_head_fmt::<DET>().lemma_no_lookahead(i1, i2);
970 }
971 }
972
973 impl<const DET: bool> EquivSerializersGeneral for CborHeadFmt<DET> {
974 proof fn lemma_serialize_equiv(&self, value: Self::SVal, out: Seq<u8>) {
975 cbor_head_fmt::<DET>().lemma_serialize_equiv(value, out);
976 }
977 }
978
979 impl<const DET: bool> EquivSerializers for CborHeadFmt<DET> {
980 proof fn lemma_serialize_equiv_on_empty(&self, value: Self::SVal) {
981 cbor_head_fmt::<DET>().lemma_serialize_equiv_on_empty(value);
982 }
983 }
984
985}
986
987}