1use crate::asn1::ber::{
3 BerBitStringFmt, BerCharStringFmt, BerOctetStringFmt, BerSequenceFmt, BerSequenceOfFmt,
4};
5use crate::asn1::tag::Class;
6use crate::asn1::{ASN1Fmt, Tag};
7use crate::combinators::mapped::spec::{FnSpecMapper, SpecMapper};
8use crate::combinators::{Choice, Mapped, Optional, Pair, Ref, Refined};
9use crate::core::exec::output::*;
10use crate::core::exec::{
11 input::{InputBuf, InputSlice},
12 parser::{PResult, Parser},
13 serializer::{ByteLen, PreSerializeError, Prepare, Serializer},
14 ParseError,
15};
16use crate::core::{proof::*, spec::*};
17use vstd::prelude::*;
18use OutputBuf;
19
20verus! {
21
22pub trait Retaggable: Copy {
27 spec fn spec_retagged(&self, tag: Tag) -> Self;
28
29 fn retagged(&self, tag: Tag) -> (retagged: Self)
30 returns
31 self.spec_retagged(tag),
32 ;
33}
34
35#[derive(Copy)]
37pub struct ImplicitlyTaggedFmt<F>(pub Tag, pub F);
38
39impl<F: Clone> Clone for ImplicitlyTaggedFmt<F> {
40 fn clone(&self) -> (cloned: Self)
41 ensures
42 cloned.0 == self.0,
43 call_ensures(F::clone, (&self.1,), cloned.1),
44 {
45 Self(self.0, self.1.clone())
46 }
47}
48
49impl<C: Copy, const DER: bool> Retaggable for ASN1Fmt<C, DER> {
54 open spec fn spec_retagged(&self, tag: Tag) -> Self {
55 ASN1Fmt(
56 Tag { class: tag.class, constructed: self.0.constructed, number: tag.number },
57 self.1,
58 )
59 }
60
61 fn retagged(&self, tag: Tag) -> Self {
62 ASN1Fmt(
63 Tag { class: tag.class, constructed: self.0.constructed, number: tag.number },
64 self.1,
65 )
66 }
67}
68
69impl<C: Copy> Retaggable for BerSequenceFmt<C> {
75 open spec fn spec_retagged(&self, tag: Tag) -> Self {
76 Self(Tag { class: tag.class, constructed: true, number: tag.number }, self.1)
77 }
78
79 fn retagged(&self, tag: Tag) -> Self {
80 Self(Tag { class: tag.class, constructed: true, number: tag.number }, self.1)
81 }
82}
83
84impl<C: Copy> Retaggable for BerSequenceOfFmt<C> {
90 open spec fn spec_retagged(&self, tag: Tag) -> Self {
91 Self(Tag { class: tag.class, constructed: true, number: tag.number }, self.1)
92 }
93
94 fn retagged(&self, tag: Tag) -> Self {
95 Self(Tag { class: tag.class, constructed: true, number: tag.number }, self.1)
96 }
97}
98
99impl<const LIMIT: usize> Retaggable for BerOctetStringFmt<LIMIT> {
105 open spec fn spec_retagged(&self, tag: Tag) -> Self {
106 Self(Tag { class: tag.class, constructed: false, number: tag.number })
107 }
108
109 fn retagged(&self, tag: Tag) -> Self {
110 Self(Tag { class: tag.class, constructed: false, number: tag.number })
111 }
112}
113
114impl<const LIMIT: usize> Retaggable for BerBitStringFmt<LIMIT> {
119 open spec fn spec_retagged(&self, tag: Tag) -> Self {
120 Self(Tag { class: tag.class, constructed: false, number: tag.number })
121 }
122
123 fn retagged(&self, tag: Tag) -> Self {
124 Self(Tag { class: tag.class, constructed: false, number: tag.number })
125 }
126}
127
128impl<C: Copy, const LIMIT: usize> Retaggable for BerCharStringFmt<C, LIMIT> {
134 open spec fn spec_retagged(&self, tag: Tag) -> Self {
135 Self(Tag { class: tag.class, constructed: false, number: tag.number }, self.1)
136 }
137
138 fn retagged(&self, tag: Tag) -> Self {
139 Self(Tag { class: tag.class, constructed: false, number: tag.number }, self.1)
140 }
141}
142
143impl<F: Retaggable> Retaggable for ImplicitlyTaggedFmt<F> {
148 open spec fn spec_retagged(&self, tag: Tag) -> Self {
149 Self(tag, self.1)
150 }
151
152 fn retagged(&self, tag: Tag) -> Self {
153 Self(tag, self.1)
154 }
155}
156
157impl<F, P> Retaggable for Refined<F, P> where F: Retaggable, P: Copy {
161 open spec fn spec_retagged(&self, tag: Tag) -> Self {
162 Refined(self.0.spec_retagged(tag), self.1)
163 }
164
165 fn retagged(&self, tag: Tag) -> Self {
166 Refined(self.0.retagged(tag), self.1)
167 }
168}
169
170impl<F, M> Retaggable for Mapped<F, M> where F: Retaggable, M: Copy {
174 open spec fn spec_retagged(&self, tag: Tag) -> Self {
175 Mapped { inner: self.inner.spec_retagged(tag), mapper: self.mapper }
176 }
177
178 fn retagged(&self, tag: Tag) -> Self {
179 Mapped { inner: self.inner.retagged(tag), mapper: self.mapper }
180 }
181}
182
183impl<F> Retaggable for Ref<F> where F: Retaggable {
187 open spec fn spec_retagged(&self, tag: Tag) -> Self {
188 Ref(self.0.spec_retagged(tag))
189 }
190
191 fn retagged(&self, tag: Tag) -> Self {
192 Ref(self.0.retagged(tag))
193 }
194}
195
196mod implicit_specs {
197 use super::*;
198
199 impl<F> SpecParser for ImplicitlyTaggedFmt<F> where F: Retaggable + SpecParser {
200 type PVal = <F as SpecParser>::PVal;
201
202 open spec fn spec_parse(&self, ibuf: Seq<u8>) -> Option<(int, Self::PVal)> {
203 self.1.spec_retagged(self.0).spec_parse(ibuf)
204 }
205 }
206
207 impl<F> Consistency for ImplicitlyTaggedFmt<F> where F: Retaggable + Consistency {
208 type Val = <F as Consistency>::Val;
209
210 open spec fn consistent(&self, value: Self::Val) -> bool {
211 self.1.spec_retagged(self.0).consistent(value)
212 }
213 }
214
215 impl<F> SpecSerializerDps for ImplicitlyTaggedFmt<F> where F: Retaggable + SpecSerializerDps {
216 type SValue = <F as SpecSerializerDps>::SValue;
217
218 open spec fn spec_serialize_dps(&self, value: Self::SValue, obuf: Seq<u8>) -> Seq<u8> {
219 self.1.spec_retagged(self.0).spec_serialize_dps(value, obuf)
220 }
221 }
222
223 impl<F> SpecSerializer for ImplicitlyTaggedFmt<F> where F: Retaggable + SpecSerializer {
224 type SVal = <F as SpecSerializer>::SVal;
225
226 open spec fn spec_serialize(&self, value: Self::SVal) -> Seq<u8> {
227 self.1.spec_retagged(self.0).spec_serialize(value)
228 }
229 }
230
231 impl<F> SpecByteLen for ImplicitlyTaggedFmt<F> where F: Retaggable + SpecByteLen {
232 type T = <F as SpecByteLen>::T;
233
234 open spec fn byte_len(&self, value: Self::T) -> nat {
235 self.1.spec_retagged(self.0).byte_len(value)
236 }
237 }
238
239}
240
241mod implicit_proofs {
242 use super::*;
243
244 impl<F> SafeParser for ImplicitlyTaggedFmt<F> where F: Retaggable + SafeParser {
245 open spec fn safe_inv(&self) -> bool {
246 self.1.spec_retagged(self.0).safe_inv()
247 }
248
249 proof fn lemma_parse_safe(&self, ibuf: Seq<u8>) {
250 self.1.spec_retagged(self.0).lemma_parse_safe(ibuf);
251 }
252 }
253
254 impl<F> Productive for ImplicitlyTaggedFmt<F> where F: Retaggable + Productive {
255 open spec fn productive_inv(&self) -> bool {
256 self.1.spec_retagged(self.0).productive_inv()
257 }
258
259 proof fn lemma_productive(&self, ibuf: Seq<u8>) {
260 self.1.spec_retagged(self.0).lemma_productive(ibuf);
261 }
262 }
263
264 impl<F> SoundParser for ImplicitlyTaggedFmt<F> where F: Retaggable + SoundParser {
265 open spec fn sound_inv(&self) -> bool {
266 self.1.spec_retagged(self.0).sound_inv()
267 }
268
269 proof fn lemma_parse_sound_consumption(&self, ibuf: Seq<u8>) {
270 self.1.spec_retagged(self.0).lemma_parse_sound_consumption(ibuf);
271 }
272
273 proof fn lemma_parse_sound_value(&self, ibuf: Seq<u8>) {
274 self.1.spec_retagged(self.0).lemma_parse_sound_value(ibuf);
275 }
276 }
277
278 impl<F> NonTailFmt for ImplicitlyTaggedFmt<F> where F: Retaggable + NonTailFmt {
279 open spec fn serialize_dps_inv(&self) -> bool {
280 self.1.spec_retagged(self.0).serialize_dps_inv()
281 }
282
283 proof fn lemma_serialize_dps_prepend(&self, value: Self::SValue, obuf: Seq<u8>) {
284 self.1.spec_retagged(self.0).lemma_serialize_dps_prepend(value, obuf);
285 }
286
287 proof fn lemma_serialize_dps_len(&self, value: Self::SValue, obuf: Seq<u8>) {
288 self.1.spec_retagged(self.0).lemma_serialize_dps_len(value, obuf);
289 }
290 }
291
292 impl<F> GoodSerializer for ImplicitlyTaggedFmt<F> where F: Retaggable + GoodSerializer {
293 open spec fn serialize_inv(&self) -> bool {
294 self.1.spec_retagged(self.0).serialize_inv()
295 }
296
297 proof fn lemma_serialize_len(&self, value: Self::SVal) {
298 self.1.spec_retagged(self.0).lemma_serialize_len(value);
299 }
300 }
301
302 impl<F> SPRoundTripDps for ImplicitlyTaggedFmt<F> where F: Retaggable + SPRoundTripDps {
303 open spec fn unambiguous(&self) -> bool {
304 self.1.spec_retagged(self.0).unambiguous()
305 }
306
307 proof fn theorem_serialize_dps_parse_roundtrip(&self, value: Self::T, obuf: Seq<u8>) {
308 self.1.spec_retagged(self.0).theorem_serialize_dps_parse_roundtrip(value, obuf);
309 }
310 }
311
312 impl<F> NonMalleable for ImplicitlyTaggedFmt<F> where F: Retaggable + NonMalleable {
313 open spec fn nonmal_inv(&self) -> bool {
314 self.1.spec_retagged(self.0).nonmal_inv()
315 }
316
317 proof fn lemma_parse_non_malleable(&self, buf1: Seq<u8>, buf2: Seq<u8>) {
318 self.1.spec_retagged(self.0).lemma_parse_non_malleable(buf1, buf2);
319 }
320 }
321
322 impl<F> NoLookAhead for ImplicitlyTaggedFmt<F> where F: Retaggable + NoLookAhead {
323 open spec fn no_lookahead_inv(&self) -> bool {
324 self.1.spec_retagged(self.0).no_lookahead_inv()
325 }
326
327 proof fn lemma_no_lookahead(&self, ibuf1: Seq<u8>, ibuf2: Seq<u8>) {
328 self.1.spec_retagged(self.0).lemma_no_lookahead(ibuf1, ibuf2);
329 }
330 }
331
332 impl<F> EquivSerializersGeneral for ImplicitlyTaggedFmt<F> where
333 F: Retaggable + EquivSerializersGeneral,
334 {
335 open spec fn equiv_general_inv(&self) -> bool {
336 self.1.spec_retagged(self.0).equiv_general_inv()
337 }
338
339 proof fn lemma_serialize_equiv(&self, value: Self::SVal, obuf: Seq<u8>) {
340 self.1.spec_retagged(self.0).lemma_serialize_equiv(value, obuf);
341 }
342 }
343
344 impl<F> EquivSerializers for ImplicitlyTaggedFmt<F> where F: Retaggable + EquivSerializers {
345 open spec fn equiv_inv(&self) -> bool {
346 self.1.spec_retagged(self.0).equiv_inv()
347 }
348
349 proof fn lemma_serialize_equiv_on_empty(&self, value: Self::SVal) {
350 self.1.spec_retagged(self.0).lemma_serialize_equiv_on_empty(value);
351 }
352 }
353
354}
355
356impl<Input, F> Parser<Input> for ImplicitlyTaggedFmt<F> where
357 Input: InputBuf,
358 F: Retaggable + Parser<Input>,
359 {
360 type PT = <F as Parser<Input>>::PT;
361
362 open spec fn exec_inv(&self) -> bool {
363 <F as Parser<Input>>::exec_inv(&self.1.spec_retagged(self.0))
364 }
365
366 fn parse(&self, ibuf: &Input) -> PResult<Self::PT> {
367 self.1.retagged(self.0).parse(ibuf)
368 }
369}
370
371impl<Output, F, T> Serializer<Output, T> for ImplicitlyTaggedFmt<F> where
372 Output: OutputBuf,
373 T: DeepView + ?Sized,
374 F: Retaggable + Serializer<Output, T>,
375 {
376 #[verifier::prophetic]
377 open spec fn exec_inv(&self) -> bool {
378 <F as Serializer<Output, T>>::exec_inv(&self.1.spec_retagged(self.0))
379 }
380
381 fn serialize_into(&self, value: &T, obuf: &mut Output) {
382 self.1.retagged(self.0).serialize_into(value, obuf)
383 }
384}
385
386impl<F, T> Prepare<T> for ImplicitlyTaggedFmt<F> where
387 T: DeepView + ?Sized,
388 F: Retaggable + Prepare<T>,
389 {
390 open spec fn exec_inv(&self) -> bool {
391 <F as Prepare<T>>::exec_inv(&self.1.spec_retagged(self.0))
392 }
393
394 fn prepare(&self, value: &T) -> Result<usize, PreSerializeError> {
395 self.1.retagged(self.0).prepare(value)
396 }
397}
398
399impl<F, T> ByteLen<T> for ImplicitlyTaggedFmt<F> where
400 T: DeepView + ?Sized,
401 F: Retaggable + ByteLen<T>,
402 {
403 open spec fn exec_inv(&self) -> bool {
404 <F as ByteLen<T>>::exec_inv(&self.1.spec_retagged(self.0))
405 }
406
407 fn length(&self, value: &T) -> usize {
408 self.1.retagged(self.0).length(value)
409 }
410}
411
412pub type ImplicitFmt<F> = ImplicitlyTaggedFmt<F>;
414
415#[allow(non_snake_case)]
420#[verifier::allow_in_spec]
421pub const fn implicitly_tagged<C: Copy>(class: Class, number: u64, inner: C) -> ImplicitFmt<C>
422 returns
423 ImplicitlyTaggedFmt(
424 Tag { class, constructed: false, number: super::tag::tag_num_from_uint(number) },
425 inner,
426 ),
427{
428 ImplicitlyTaggedFmt(
429 Tag { class, constructed: false, number: super::tag::tag_num_from_uint(number) },
430 inner,
431 )
432}
433
434#[allow(non_snake_case)]
436#[verifier::allow_in_spec]
437pub const fn IMPLICIT<C: Copy>(number: u64, inner: C) -> ImplicitFmt<C>
438 returns
439 implicitly_tagged(Class::ContextSpecific, number, inner),
440{
441 implicitly_tagged(Class::ContextSpecific, number, inner)
442}
443
444#[allow(non_snake_case)]
446#[verifier::allow_in_spec]
447pub const fn IMPLICIT_APPLICATION<C: Copy>(number: u64, inner: C) -> ImplicitFmt<C>
448 returns
449 implicitly_tagged(Class::Application, number, inner),
450{
451 implicitly_tagged(Class::Application, number, inner)
452}
453
454#[allow(non_snake_case)]
456#[verifier::allow_in_spec]
457pub const fn IMPLICIT_PRIVATE<C: Copy>(number: u64, inner: C) -> ImplicitFmt<C>
458 returns
459 implicitly_tagged(Class::Private, number, inner),
460{
461 implicitly_tagged(Class::Private, number, inner)
462}
463
464#[allow(non_snake_case)]
466#[verifier::allow_in_spec]
467pub const fn OPTIONAL<Field, Rest>(field: Field, rest: Rest) -> Optional<Field, Rest>
468 returns
469 Optional(field, rest),
470{
471 Optional(field, rest)
472}
473
474#[allow(non_snake_case)]
476#[verifier::allow_in_spec]
477pub const fn REQUIRED<Field, Rest>(field: Field, rest: Rest) -> Pair<Field, Rest>
478 returns
479 Pair(field, rest),
480{
481 Pair(field, rest)
482}
483
484#[allow(non_snake_case)]
486#[verifier::allow_in_spec]
487pub const fn CHOICE<Left, Right>(left: Left, right: Right) -> Choice<Left, Right>
488 returns
489 Choice(left, right),
490{
491 Choice(left, right)
492}
493
494#[verifier::allow_in_spec]
496pub const fn explicit_tag(class: Class, number: u64) -> Tag
497 returns
498 (Tag { class, constructed: true, number: super::tag::tag_num_from_uint(number) }),
499{
500 Tag { class, constructed: true, number: super::tag::tag_num_from_uint(number) }
501}
502
503#[derive(Copy)]
509pub struct DefaultedFmt<Field, Default, Rest, const DER: bool = true>(
510 pub Field,
511 pub Default,
512 pub Rest,
513);
514
515#[verifier::allow_in_spec]
517pub const fn defaulted<Field, Rest, const DER: bool>(
518 field: Field,
519 default: Field::T,
520 rest: Rest,
521) -> DefaultedFmt<Field, Field::T, Rest, DER> where Field: SpecByteLen
522 returns
523 DefaultedFmt::<Field, Field::T, Rest, DER>(field, default, rest),
524{
525 DefaultedFmt::<Field, Field::T, Rest, DER>(field, default, rest)
526}
527
528impl<Field: Clone, Default: Clone, Rest: Clone, const DER: bool> Clone for DefaultedFmt<
529 Field,
530 Default,
531 Rest,
532 DER,
533> {
534 fn clone(&self) -> (cloned: Self)
535 ensures
536 call_ensures(Field::clone, (&self.0,), cloned.0),
537 call_ensures(Default::clone, (&self.1,), cloned.1),
538 call_ensures(Rest::clone, (&self.2,), cloned.2),
539 {
540 DefaultedFmt(self.0.clone(), self.1.clone(), self.2.clone())
541 }
542}
543
544pub type DefaultedInnerFmt<Field, Rest, T, U, const DER: bool> = Mapped<
545 Refined<Optional<Field, Rest>, PredFnSpec<(Option<T>, U)>>,
546 FnSpecMapper<(Option<T>, U), (T, U)>,
547>;
548
549pub open spec fn defaulted_fmt<Field: SpecByteLen, Rest: SpecByteLen, const DER: bool>(
550 field: Field,
551 default: Field::T,
552 rest: Rest,
553) -> DefaultedInnerFmt<Field, Rest, Field::T, Rest::T, DER> {
554 Mapped {
555 inner: Refined(
556 Optional(field, rest),
557 |pair: (Option<Field::T>, Rest::T)|
558 DER ==> (pair matches (Some(value), _) ==> value != default),
559 ),
560 mapper: (
561 |parsed: (Option<Field::T>, Rest::T)|
562 (
563 match parsed.0 {
564 Some(value) => value,
565 None => default,
566 },
567 parsed.1,
568 ),
569 |value: (Field::T, Rest::T)|
570 (
571 if value.0 == default {
572 None
573 } else {
574 Some(value.0)
575 },
576 value.1,
577 ),
578 ),
579 }
580}
581
582mod derived_specs {
583 use super::*;
584
585 impl<Field, Rest, const DER: bool> SpecParser for DefaultedFmt<
586 Field,
587 Field::PVal,
588 Rest,
589 DER,
590 > where
591 Field: SpecByteLen + SpecParser<PVal = Field::T>,
592 Rest: SpecByteLen + SpecParser<PVal = Rest::T>,
593 {
594 type PVal = (Field::PVal, Rest::PVal);
595
596 open spec fn spec_parse(&self, ibuf: Seq<u8>) -> Option<(int, Self::PVal)> {
597 defaulted_fmt::<Field, Rest, DER>(self.0, self.1, self.2).spec_parse(ibuf)
598 }
599 }
600
601 impl<Field, Rest, const DER: bool> Consistency for DefaultedFmt<
602 Field,
603 Field::Val,
604 Rest,
605 DER,
606 > where
607 Field: SpecByteLen + Consistency<Val = Field::T>,
608 Rest: SpecByteLen + Consistency<Val = Rest::T>,
609 {
610 type Val = (Field::Val, Rest::Val);
611
612 open spec fn consistent(&self, v: Self::Val) -> bool {
613 defaulted_fmt::<Field, Rest, DER>(self.0, self.1, self.2).consistent(v)
614 }
615 }
616
617 impl<Field, Rest, const DER: bool> SpecSerializerDps for DefaultedFmt<
618 Field,
619 Field::SValue,
620 Rest,
621 DER,
622 > where
623 Field: SpecByteLen + SpecSerializerDps<SValue = Field::T>,
624 Rest: SpecByteLen + SpecSerializerDps<SValue = Rest::T>,
625 {
626 type SValue = (Field::SValue, Rest::SValue);
627
628 open spec fn spec_serialize_dps(&self, v: Self::SValue, obuf: Seq<u8>) -> Seq<u8> {
629 defaulted_fmt::<Field, Rest, DER>(self.0, self.1, self.2).spec_serialize_dps(v, obuf)
630 }
631 }
632
633 impl<Field, Rest, const DER: bool> SpecSerializer for DefaultedFmt<
634 Field,
635 Field::SVal,
636 Rest,
637 DER,
638 > where
639 Field: SpecByteLen + SpecSerializer<SVal = Field::T>,
640 Rest: SpecByteLen + SpecSerializer<SVal = Rest::T>,
641 {
642 type SVal = (Field::SVal, Rest::SVal);
643
644 open spec fn spec_serialize(&self, v: Self::SVal) -> Seq<u8> {
645 defaulted_fmt::<Field, Rest, DER>(self.0, self.1, self.2).spec_serialize(v)
646 }
647 }
648
649 impl<Field, Rest, const DER: bool> SpecByteLen for DefaultedFmt<
650 Field,
651 Field::T,
652 Rest,
653 DER,
654 > where Field: SpecByteLen, Rest: SpecByteLen {
655 type T = (Field::T, Rest::T);
656
657 open spec fn byte_len(&self, v: Self::T) -> nat {
658 defaulted_fmt::<Field, Rest, DER>(self.0, self.1, self.2).byte_len(v)
659 }
660 }
661
662}
663
664mod derived_proofs {
665 use super::*;
666
667 impl<Field, Rest, const DER: bool> SafeParser for DefaultedFmt<
668 Field,
669 Field::PVal,
670 Rest,
671 DER,
672 > where
673 Field: SpecByteLen + SafeParser<PVal = Field::T>,
674 Rest: SpecByteLen + SafeParser<PVal = Rest::T>,
675 {
676 open spec fn safe_inv(&self) -> bool {
677 defaulted_fmt::<Field, Rest, DER>(self.0, self.1, self.2).safe_inv()
678 }
679
680 proof fn lemma_parse_safe(&self, ibuf: Seq<u8>) {
681 defaulted_fmt::<Field, Rest, DER>(self.0, self.1, self.2).lemma_parse_safe(ibuf);
682 }
683 }
684
685 impl<Field, Rest, const DER: bool> Productive for DefaultedFmt<
686 Field,
687 Field::PVal,
688 Rest,
689 DER,
690 > where
691 Field: SpecByteLen + Productive<PVal = Field::T>,
692 Rest: SpecByteLen + Productive<PVal = Rest::T>,
693 {
694 open spec fn productive_inv(&self) -> bool {
695 defaulted_fmt::<Field, Rest, DER>(self.0, self.1, self.2).productive_inv()
696 }
697
698 proof fn lemma_productive(&self, s: Seq<u8>) {
699 defaulted_fmt::<Field, Rest, DER>(self.0, self.1, self.2).lemma_productive(s);
700 }
701 }
702
703 impl<Field, Rest, const DER: bool> SoundParser for DefaultedFmt<
704 Field,
705 Field::PVal,
706 Rest,
707 DER,
708 > where Field: SoundParser, Rest: SoundParser {
709 open spec fn sound_inv(&self) -> bool {
710 defaulted_fmt::<Field, Rest, DER>(self.0, self.1, self.2).sound_inv()
711 }
712
713 proof fn lemma_parse_sound_consumption(&self, ibuf: Seq<u8>) {
714 defaulted_fmt::<Field, Rest, DER>(self.0, self.1, self.2).lemma_parse_sound_consumption(
715 ibuf,
716 );
717 }
718
719 proof fn lemma_parse_sound_value(&self, ibuf: Seq<u8>) {
720 defaulted_fmt::<Field, Rest, DER>(self.0, self.1, self.2).lemma_parse_sound_value(ibuf);
721 }
722 }
723
724 impl<Field, Rest, const DER: bool> NonTailFmt for DefaultedFmt<
725 Field,
726 Field::SValue,
727 Rest,
728 DER,
729 > where Field: NonTailFmt, Rest: NonTailFmt {
730 open spec fn serialize_dps_inv(&self) -> bool {
731 defaulted_fmt::<Field, Rest, DER>(self.0, self.1, self.2).serialize_dps_inv()
732 }
733
734 proof fn lemma_serialize_dps_prepend(&self, v: Self::SValue, obuf: Seq<u8>) {
735 defaulted_fmt::<Field, Rest, DER>(self.0, self.1, self.2).lemma_serialize_dps_prepend(
736 v,
737 obuf,
738 );
739 }
740
741 proof fn lemma_serialize_dps_len(&self, v: Self::SValue, obuf: Seq<u8>) {
742 defaulted_fmt::<Field, Rest, DER>(self.0, self.1, self.2).lemma_serialize_dps_len(
743 v,
744 obuf,
745 );
746 }
747 }
748
749 impl<Field, Rest, const DER: bool> GoodSerializer for DefaultedFmt<
750 Field,
751 Field::SVal,
752 Rest,
753 DER,
754 > where Field: GoodSerializer, Rest: GoodSerializer {
755 open spec fn serialize_inv(&self) -> bool {
756 defaulted_fmt::<Field, Rest, DER>(self.0, self.1, self.2).serialize_inv()
757 }
758
759 proof fn lemma_serialize_len(&self, v: Self::SVal) {
760 defaulted_fmt::<Field, Rest, DER>(self.0, self.1, self.2).lemma_serialize_len(v);
761 }
762 }
763
764 impl<Field, Rest, const DER: bool> SPRoundTripDps for DefaultedFmt<
765 Field,
766 Field::T,
767 Rest,
768 DER,
769 > where Field: SPRoundTripDps + NonTailFmt, Rest: SPRoundTripDps {
770 open spec fn unambiguous(&self) -> bool {
771 defaulted_fmt::<Field, Rest, DER>(self.0, self.1, self.2).unambiguous()
772 }
773
774 proof fn theorem_serialize_dps_parse_roundtrip(&self, v: Self::T, obuf: Seq<u8>) {
775 defaulted_fmt::<Field, Rest, DER>(
776 self.0,
777 self.1,
778 self.2,
779 ).theorem_serialize_dps_parse_roundtrip(v, obuf);
780 }
781 }
782
783 impl<Field, Rest, const DER: bool> NoLookAhead for DefaultedFmt<
784 Field,
785 Field::PVal,
786 Rest,
787 DER,
788 > where
789 Field: SpecByteLen + NoLookAhead<PVal = Field::T>,
790 Rest: SpecByteLen + NoLookAhead<PVal = Rest::T>,
791 {
792 open spec fn no_lookahead_inv(&self) -> bool {
793 defaulted_fmt::<Field, Rest, DER>(self.0, self.1, self.2).no_lookahead_inv()
794 }
795
796 proof fn lemma_no_lookahead(&self, i1: Seq<u8>, i2: Seq<u8>) {
797 defaulted_fmt::<Field, Rest, DER>(self.0, self.1, self.2).lemma_no_lookahead(i1, i2);
798 }
799 }
800
801 impl<Field, Rest, const DER: bool> NonMalleable for DefaultedFmt<
802 Field,
803 Field::PVal,
804 Rest,
805 DER,
806 > where Field: SoundParser + NonMalleable, Rest: SoundParser + NonMalleable {
807 open spec fn nonmal_inv(&self) -> bool {
808 defaulted_fmt::<Field, Rest, DER>(self.0, self.1, self.2).nonmal_inv()
809 }
810
811 proof fn lemma_parse_non_malleable(&self, buf1: Seq<u8>, buf2: Seq<u8>) {
812 defaulted_fmt::<Field, Rest, DER>(self.0, self.1, self.2).lemma_parse_non_malleable(
813 buf1,
814 buf2,
815 );
816 }
817 }
818
819 impl<Field, Rest, const DER: bool> EquivSerializersGeneral for DefaultedFmt<
820 Field,
821 Field::SVal,
822 Rest,
823 DER,
824 > where
825 Field: SpecByteLen + EquivSerializersGeneral<SVal = Field::T>,
826 Rest: SpecByteLen + EquivSerializersGeneral<SVal = Rest::T>,
827 {
828 open spec fn equiv_general_inv(&self) -> bool {
829 defaulted_fmt::<Field, Rest, DER>(self.0, self.1, self.2).equiv_general_inv()
830 }
831
832 proof fn lemma_serialize_equiv(&self, v: Self::SVal, obuf: Seq<u8>) {
833 defaulted_fmt::<Field, Rest, DER>(self.0, self.1, self.2).lemma_serialize_equiv(
834 v,
835 obuf,
836 );
837 }
838 }
839
840 impl<Field, Rest, const DER: bool> EquivSerializers for DefaultedFmt<
841 Field,
842 Field::SVal,
843 Rest,
844 DER,
845 > where
846 Field: SpecByteLen + EquivSerializersGeneral<SVal = Field::T>,
847 Rest: SpecByteLen + EquivSerializers<SVal = Rest::T>,
848 {
849 open spec fn equiv_inv(&self) -> bool {
850 defaulted_fmt::<Field, Rest, DER>(self.0, self.1, self.2).equiv_inv()
851 }
852
853 proof fn lemma_serialize_equiv_on_empty(&self, v: Self::SVal) {
854 defaulted_fmt::<Field, Rest, DER>(
855 self.0,
856 self.1,
857 self.2,
858 ).lemma_serialize_equiv_on_empty(v);
859 }
860 }
861
862}
863
864impl<I, Field, Rest, const DER: bool> Parser<I> for DefaultedFmt<Field, Field::T, Rest, DER> where
870 I: InputBuf,
871 Field: Parser<I, PT = Field::T> + SafeParser<PVal = Field::T> + SpecByteLen,
872 Rest: Parser<I> + SafeParser<PVal = Rest::T> + SpecByteLen,
873 Field::T: DeepView<V = Field::T> + PartialEq + Structural + Copy,
874 {
875 type PT = (Field::PT, Rest::PT);
876
877 open spec fn exec_inv(&self) -> bool {
878 &&& self.0.exec_inv()
879 &&& self.0.safe_inv()
880 &&& self.2.exec_inv()
881 &&& self.2.safe_inv()
882 &&& forall|v: Field::T| v.deep_view() == v
883 &&& vstd::laws_eq::obeys_concrete_eq::<Field::T>()
884 }
885
886 fn parse(&self, ibuf: &I) -> PResult<Self::PT> {
887 broadcast use crate::core::spec::SafeParser::lemma_parse_safe;
888
889 reveal(vstd::laws_eq::obeys_concrete_eq);
890
891 let (n, (field, rest)) = Optional(&self.0, &self.2).parse(ibuf)?;
892
893 if DER {
894 if let Some(v) = field {
895 if v == self.1 {
896 return Err(ParseError::non_canonical());
897 }
898 }
899 }
900 let field = match field {
901 Some(v) => v,
902 None => self.1,
903 };
904
905 Ok((n, (field, rest)))
906 }
907}
908
909impl<Output: OutputBuf, Field, Default, Rest, R, const DER: bool> Serializer<
910 Output,
911 (Default, R),
912> for DefaultedFmt<Field, Default, Rest, DER> where
913 Field: SpecByteLen<T = Default> + Serializer<Output, Default>,
914 Rest: SpecByteLen<T = R::V> + Serializer<Output, R>,
915 Default: DeepView<V = Default> + PartialEq + Structural + Copy,
916 R: DeepView,
917 {
918 #[verifier::prophetic]
919 open spec fn exec_inv(&self) -> bool {
920 &&& self.0.exec_inv()
921 &&& self.2.exec_inv()
922 &&& forall|v: Default| v.deep_view() == v
923 }
924
925 fn serialize_into(&self, v: &(Default, R), obuf: &mut Output) {
926 broadcast use crate::core::exec::output::outbuf_lemmas;
927
928 if v.0 != self.1 {
929 self.0.serialize_into(&v.0, obuf);
930 }
931 self.2.serialize_into(&v.1, obuf);
932 }
933}
934
935impl<Field, Default, Rest, R, const DER: bool> Prepare<(Default, R)> for DefaultedFmt<
936 Field,
937 Default,
938 Rest,
939 DER,
940> where
941 Field: SpecByteLen<T = Default> + Prepare<Default>,
942 Rest: SpecByteLen<T = R::V> + Prepare<R>,
943 Default: DeepView<V = Default> + PartialEq + Structural + Copy,
944 R: DeepView,
945 {
946 open spec fn exec_inv(&self) -> bool {
947 &&& self.0.exec_inv()
948 &&& self.2.exec_inv()
949 &&& forall|v: Default| v.deep_view() == v
950 }
951
952 fn prepare(&self, v: &(Default, R)) -> Result<usize, PreSerializeError> {
953 let n0 = if v.0 == self.1 {
954 0
955 } else {
956 self.0.prepare(&v.0)?
957 };
958 let n1 = self.2.prepare(&v.1)?;
959 let total = n0.checked_add(n1).ok_or(PreSerializeError::length_too_large())?;
960 Ok(total)
961 }
962}
963
964impl<Field, Default, Rest, R, const DER: bool> ByteLen<(Default, R)> for DefaultedFmt<
965 Field,
966 Default,
967 Rest,
968 DER,
969> where
970 Field: SpecByteLen<T = Default> + ByteLen<Default>,
971 Rest: SpecByteLen<T = R::V> + ByteLen<R>,
972 Default: DeepView<V = Default> + PartialEq + Structural + Copy,
973 R: DeepView,
974 {
975 open spec fn exec_inv(&self) -> bool {
976 &&& self.0.exec_inv()
977 &&& self.2.exec_inv()
978 &&& forall|v: Default| v.deep_view() == v
979 }
980
981 fn length(&self, v: &(Default, R)) -> usize {
982 let n0 = if v.0 == self.1 {
983 0
984 } else {
985 self.0.length(&v.0)
986 };
987 let n1 = self.2.length(&v.1);
988 n0 + n1
989 }
990}
991
992}