1use crate::combinators::{Bind, Empty, Sum, Void};
3use crate::core::exec::input::*;
4use crate::core::exec::output::*;
5use crate::core::exec::{parser::*, serializer::*, ParseError, ParseErrorKind};
6use crate::primitives::base256::*;
7use crate::Never;
8use crate::{
9 combinators::{
10 implicit::*,
11 length::AsLen,
12 mapped::spec::{FnSpecMapper, LosslessMapper, LossyMapper, SpecMapper},
13 Alt, Choice, Const, Implicit, Mapped, Refined, TryMap, Varied, U8,
14 },
15 core::{proof::*, spec::*},
16};
17use vstd::arithmetic::power::*;
18use vstd::prelude::*;
19use OutputBuf;
20use Sum::Inl as L;
21use Sum::Inr as R;
22
23verus! {
24
25pub const SHORT_FORM_MAX: u8 = 0x7F;
26
27pub const LONG_FORM_MIN_COUNT: u8 = 1;
28
29pub const LONG_FORM_MAX_COUNT: u8 = 126;
30
31type LengthWireFmt<const DER: bool, const BOUNDED: bool = false> = Bind<
32 U8,
33 spec_fn(u8) -> Sum<Empty, Sum<Refined<Varied<u8>, PredFnSpec<Seq<u8>>>, Void>>,
34>;
35
36type NatLengthFmt<const DER: bool> = Mapped<
37 LengthWireFmt<DER>,
38 FnSpecMapper<(u8, Sum<(), Sum<Seq<u8>, Never>>), nat>,
39>;
40
41type LengthFmt<const DER: bool> = Mapped<
42 LengthWireFmt<DER, true>,
43 FnSpecMapper<(u8, Sum<(), Sum<Seq<u8>, Never>>), usize>,
44>;
45
46type BerLengthFmt__ = Mapped<
47 Choice<Const<U8, u8>, super::LengthFmt<false>>,
48 FnSpecMapper<Sum<u8, usize>, super::BerLength>,
49>;
50
51pub open spec fn ber_length_fmt() -> BerLengthFmt__ {
52 Mapped {
53 inner: Choice(Const(U8, 0x80u8), super::LengthFmt::<false>),
54 mapper: (
55 |v: Sum<u8, usize>|
56 match v {
57 L(_) => super::BerLength::Indefinite,
58 R(n) => super::BerLength::Definite(n),
59 },
60 |v: super::BerLength|
61 match v {
62 super::BerLength::Indefinite => L(0x80u8),
63 super::BerLength::Definite(n) => R(n),
64 },
65 ),
66 }
67}
68
69#[verusfmt::skip]
77pub(super) open(super) spec fn length_wire<const DER: bool, const BOUNDED: bool>() -> LengthWireFmt<DER, BOUNDED > {
78 Bind(U8, |b1: u8| {
79 match b1 {
80 b if b <= SHORT_FORM_MAX => L(Empty),
81 b if 0b1000_0000 < b < 0b1111_1111 => R(L(
82 Refined(Varied(b & 0b0111_1111), |bytes: Seq<u8>| {
84 &&& DER ==> der_long_len_bytes_minimal(bytes)
85 &&& BOUNDED ==> bytes.len() <= size_of_usize()
86 }),
87 ),
88 ),
89 _ => R(R(Void("Invalid first byte for ASN1 length"))),
90 }
91 })
92}
93
94pub(super) open(super) spec fn nat_length_fmt<const DER: bool>() -> NatLengthFmt<DER> {
95 Mapped {
96 inner: length_wire::<DER, false>(),
97 mapper: (
98 |r: (u8, Sum<(), Sum<Seq<u8>, Never>>)|
99 {
100 let (b1, rest) = r;
101 match rest {
102 L(()) => b1 as nat,
103 R(L(bytes)) => nat_from_be_bytes(bytes),
104 _ => arbitrary(), }
106 },
107 |n: nat|
108 if n <= SHORT_FORM_MAX as nat {
109 (n as u8, L(()))
110 } else {
111 let bytes = nat_to_be_bytes(n);
112 (0b1000_0000 | (bytes.len() as u8), R(L(bytes)))
114 },
115 ),
116 }
117}
118
119pub(super) open(super) spec fn length_fmt<const DER: bool>() -> LengthFmt<DER> {
120 Mapped {
121 inner: length_wire::<DER, true>(),
122 mapper: (
123 |r: (u8, Sum<(), Sum<Seq<u8>, Never>>)|
124 {
125 let (b1, rest) = r;
126 match rest {
127 L(()) => b1 as usize,
128 R(L(bytes)) => nat_from_be_bytes(bytes) as usize,
129 _ => arbitrary(), }
131 },
132 |n: usize|
133 if n <= SHORT_FORM_MAX as usize {
134 (n as u8, L(()))
135 } else {
136 let bytes = nat_to_be_bytes(n as nat);
137 (0b1000_0000 | (bytes.len() as u8), R(L(bytes)))
138 },
139 ),
140 }
141}
142
143pub open spec fn der_long_len_bytes_minimal(bytes: Seq<u8>) -> bool {
147 &&& bytes.len() == 1 ==> bytes[0] > SHORT_FORM_MAX
148 &&& bytes.len() > 1 ==> bytes[0] != 0x00u8
149}
150
151proof fn lemma_length_wire_long_form_roundtrip(b1: u8, bytes: Seq<u8>)
152 requires
153 0b1000_0000u8 < b1 < 0b1111_1111u8,
154 der_long_len_bytes_minimal(bytes),
155 bytes.len() == (b1 & 0b0111_1111) as nat,
156 ensures
157 nat_to_be_bytes(nat_from_be_bytes(bytes)) == bytes,
158 (0b1000_0000u8 | (bytes.len() as u8)) == b1,
159{
160 assert(bytes.len() > 0) by {
161 assert((b1 & 0b0111_1111u8) >= 1u8) by (bit_vector)
162 requires
163 0b1000_0000u8 < b1 < 0b1111_1111u8,
164 ;
165 }
166 lemma_from_to_be_bytes_roundtrip(bytes);
167 assert((0b1000_0000u8 | (b1 & 0b0111_1111u8)) == b1) by (bit_vector)
168 requires
169 0b1000_0000u8 < b1 < 0b1111_1111u8,
170 ;
171}
172
173proof fn lemma_length_fmt_sound_nonmal_inv()
174 ensures
175 nat_length_fmt::<true>().sound_inv(),
176 nat_length_fmt::<true>().nonmal_inv(),
177{
178 assert forall|v| nat_length_fmt::<true>().inner.consistent(v) implies (nat_length_fmt::<
179 true,
180 >().mapper.1)((nat_length_fmt::<true>().mapper.0)(v)) == v by {
181 let (b1, rest) = v;
182 if b1 <= SHORT_FORM_MAX {
183 } else if 0b1000_0000 < b1 < 0b1111_1111 {
184 match rest {
185 R(L(bytes)) => {
186 lemma_length_wire_long_form_roundtrip(b1, bytes);
187 },
188 _ => {},
189 }
190 }
191 }
192}
193
194proof fn lemma_length_fmt_unambiguous<const DER: bool>()
195 ensures
196 nat_length_fmt::<DER>().unambiguous(),
197{
198 assert forall|o: nat| nat_length_fmt::<DER>().consistent(o) implies (nat_length_fmt::<
199 DER,
200 >().mapper.0)((nat_length_fmt::<DER>().mapper.1)(o)) == o by {
201 if nat_length_fmt::<DER>().consistent(o) {
202 if o <= SHORT_FORM_MAX as nat {
203 } else {
204 lemma_to_from_be_bytes_roundtrip(o);
205 }
206 }
207 }
208}
209
210proof fn lemma_length_fmt_usize_sound_nonmal_inv()
211 ensures
212 length_fmt::<true>().sound_inv(),
213 length_fmt::<true>().nonmal_inv(),
214{
215 assert forall|v| length_fmt::<true>().inner.consistent(v) implies (length_fmt::<
216 true,
217 >().mapper.1)((length_fmt::<true>().mapper.0)(v)) == v by {
218 let (b1, rest) = v;
219 if b1 <= SHORT_FORM_MAX {
220 } else if 0b1000_0000 < b1 < 0b1111_1111 {
221 match rest {
222 R(L(bytes)) => {
223 assert(bytes.len() <= size_of_usize());
224 lemma_nat_from_be_bytes_fits_usize(bytes);
225 lemma_length_wire_long_form_roundtrip(b1, bytes);
226 },
227 _ => {},
228 }
229 }
230 }
231}
232
233proof fn lemma_length_fmt_usize_unambiguous<const DER: bool>()
235 ensures
236 length_fmt::<DER>().unambiguous(),
237{
238 assert forall|o: usize| length_fmt::<DER>().consistent(o) implies (length_fmt::<
239 DER,
240 >().mapper.0)((length_fmt::<DER>().mapper.1)(o)) == o by {
241 if length_fmt::<DER>().consistent(o) {
242 if o <= SHORT_FORM_MAX as usize {
243 } else {
244 lemma_to_from_be_bytes_roundtrip(o as nat);
245 }
246 }
247 }
248}
249
250proof fn lemma_length_fmt_usize_props<const DER: bool>(o: usize)
251 ensures
252 length_fmt::<DER>().consistent(o),
253 length_fmt::<DER>().byte_len(o) == if o <= SHORT_FORM_MAX as usize {
254 1
255 } else {
256 1 + nat_to_be_bytes(o as nat).len()
257 },
258{
259 lemma_to_be_bytes_props(o as nat);
260 lemma_usize_to_be_bytes_len_bound(o);
261 if o <= SHORT_FORM_MAX as usize {
262 } else {
263 let bytes = nat_to_be_bytes(o as nat);
264 let count = bytes.len() as u8;
265 let b1 = 0b1000_0000u8 | count;
266 if DER {
267 assert(der_long_len_bytes_minimal(bytes)) by {
268 reveal_with_fuel(nat_to_be_bytes, 2);
269 }
270 }
271 assert(0b1000_0000u8 < b1 < 0b1111_1111u8 && (b1 & 0b0111_1111u8) == count) by (bit_vector)
272 requires
273 0u8 < count <= 8u8,
274 b1 == (0b1000_0000u8 | count),
275 ;
276 }
277}
278
279pub(crate) proof fn lemma_length_fmt_byte_len_bound<const DER: bool>(value: usize)
280 ensures
281 super::LengthFmt::<DER>.byte_len(value) <= 1 + size_of::<usize>(),
282{
283 lemma_length_fmt_usize_props::<DER>(value);
284 lemma_usize_to_be_bytes_len_bound(value);
285}
286
287pub(crate) broadcast proof fn lemma_length_fmt_short_byte_len<const DER: bool>(o: usize)
288 requires
289 o <= SHORT_FORM_MAX as usize,
290 ensures
291 #[trigger] super::LengthFmt::<DER>.byte_len(o) == 1,
292{
293 lemma_length_fmt_usize_props::<DER>(o);
294}
295
296mod derived_specs {
297 use super::*;
298 use super::super::{NatLengthFmt, LengthFmt};
299
300 impl<const DER: bool> SpecParser for NatLengthFmt<DER> {
301 type PVal = nat;
302
303 open(super) spec fn spec_parse(&self, ibuf: Seq<u8>) -> Option<(int, Self::PVal)> {
304 nat_length_fmt::<DER>().spec_parse(ibuf)
305 }
306 }
307
308 impl<const DER: bool> Consistency for NatLengthFmt<DER> {
309 type Val = nat;
310
311 open(super) spec fn consistent(&self, v: Self::Val) -> bool {
312 nat_length_fmt::<DER>().consistent(v)
313 }
314 }
315
316 impl<const DER: bool> SpecSerializerDps for NatLengthFmt<DER> {
317 type SValue = nat;
318
319 open(super) spec fn spec_serialize_dps(&self, v: Self::SValue, obuf: Seq<u8>) -> Seq<u8> {
320 nat_length_fmt::<DER>().spec_serialize_dps(v, obuf)
321 }
322 }
323
324 impl<const DER: bool> SpecSerializer for NatLengthFmt<DER> {
325 type SVal = nat;
326
327 open(super) spec fn spec_serialize(&self, v: Self::SVal) -> Seq<u8> {
328 nat_length_fmt::<DER>().spec_serialize(v)
329 }
330 }
331
332 impl<const DER: bool> SpecByteLen for NatLengthFmt<DER> {
333 type T = nat;
334
335 open(super) spec fn byte_len(&self, v: Self::T) -> nat {
336 nat_length_fmt::<DER>().byte_len(v)
337 }
338 }
339
340 impl<const DER: bool> SpecParser for LengthFmt<DER> {
341 type PVal = usize;
342
343 open(super) spec fn spec_parse(&self, ibuf: Seq<u8>) -> Option<(int, Self::PVal)> {
344 length_fmt::<DER>().spec_parse(ibuf)
345 }
346 }
347
348 impl<const DER: bool> Consistency for LengthFmt<DER> {
349 type Val = usize;
350
351 open(super) spec fn consistent(&self, v: Self::Val) -> bool {
352 length_fmt::<DER>().consistent(v)
353 }
354 }
355
356 impl<const DER: bool> SpecSerializerDps for LengthFmt<DER> {
357 type SValue = usize;
358
359 open(super) spec fn spec_serialize_dps(&self, v: Self::SValue, obuf: Seq<u8>) -> Seq<u8> {
360 length_fmt::<DER>().spec_serialize_dps(v, obuf)
361 }
362 }
363
364 impl<const DER: bool> SpecSerializer for LengthFmt<DER> {
365 type SVal = usize;
366
367 open(super) spec fn spec_serialize(&self, v: Self::SVal) -> Seq<u8> {
368 length_fmt::<DER>().spec_serialize(v)
369 }
370 }
371
372 impl<const DER: bool> SpecByteLen for LengthFmt<DER> {
373 type T = usize;
374
375 open(super) spec fn byte_len(&self, v: Self::T) -> nat {
376 length_fmt::<DER>().byte_len(v)
377 }
378 }
379
380}
381
382mod derived_proofs {
383 use super::*;
384 use super::super::{NatLengthFmt, LengthFmt};
385
386 impl<const DER: bool> SafeParser for NatLengthFmt<DER> {
387 proof fn lemma_parse_safe(&self, ibuf: Seq<u8>) {
388 nat_length_fmt::<DER>().lemma_parse_safe(ibuf);
389 }
390 }
391
392 impl<const DER: bool> Productive for NatLengthFmt<DER> {
393 proof fn lemma_productive(&self, s: Seq<u8>) {
394 nat_length_fmt::<DER>().lemma_productive(s);
395 }
396 }
397
398 impl SoundParser for NatLengthFmt<true> {
399 proof fn lemma_parse_sound_consumption(&self, ibuf: Seq<u8>) {
400 lemma_length_fmt_sound_nonmal_inv();
401 nat_length_fmt::<true>().lemma_parse_sound_consumption(ibuf);
402 }
403
404 proof fn lemma_parse_sound_value(&self, ibuf: Seq<u8>) {
405 lemma_length_fmt_sound_nonmal_inv();
406 nat_length_fmt::<true>().lemma_parse_sound_value(ibuf);
407 }
408 }
409
410 impl<const DER: bool> NonTailFmt for NatLengthFmt<DER> {
411 proof fn lemma_serialize_dps_prepend(&self, v: Self::SValue, obuf: Seq<u8>) {
412 nat_length_fmt::<DER>().lemma_serialize_dps_prepend(v, obuf);
413 }
414
415 proof fn lemma_serialize_dps_len(&self, v: Self::SValue, obuf: Seq<u8>) {
416 nat_length_fmt::<DER>().lemma_serialize_dps_len(v, obuf);
417 }
418 }
419
420 impl<const DER: bool> GoodSerializer for NatLengthFmt<DER> {
421 proof fn lemma_serialize_len(&self, v: Self::SVal) {
422 nat_length_fmt::<DER>().lemma_serialize_len(v);
423 }
424 }
425
426 impl<const DER: bool> SPRoundTripDps for NatLengthFmt<DER> {
427 proof fn theorem_serialize_dps_parse_roundtrip(&self, v: Self::T, obuf: Seq<u8>) {
428 lemma_length_fmt_unambiguous::<DER>();
429 nat_length_fmt::<DER>().theorem_serialize_dps_parse_roundtrip(v, obuf);
430 }
431 }
432
433 impl<const DER: bool> NoLookAhead for NatLengthFmt<DER> {
434 proof fn lemma_no_lookahead(&self, i1: Seq<u8>, i2: Seq<u8>) {
435 nat_length_fmt::<DER>().lemma_no_lookahead(i1, i2);
436 }
437 }
438
439 impl NonMalleable for NatLengthFmt<true> {
440 proof fn lemma_parse_non_malleable(&self, buf1: Seq<u8>, buf2: Seq<u8>) {
441 lemma_length_fmt_sound_nonmal_inv();
442 nat_length_fmt::<true>().lemma_parse_non_malleable(buf1, buf2);
443 }
444 }
445
446 impl<const DER: bool> EquivSerializersGeneral for NatLengthFmt<DER> {
447 proof fn lemma_serialize_equiv(&self, v: Self::SVal, obuf: Seq<u8>) {
448 nat_length_fmt::<DER>().lemma_serialize_equiv(v, obuf);
449 }
450 }
451
452 impl<const DER: bool> EquivSerializers for NatLengthFmt<DER> {
453 proof fn lemma_serialize_equiv_on_empty(&self, v: Self::SVal) {
454 nat_length_fmt::<DER>().lemma_serialize_equiv_on_empty(v);
455 }
456 }
457
458 impl<const DER: bool> SafeParser for LengthFmt<DER> {
459 proof fn lemma_parse_safe(&self, ibuf: Seq<u8>) {
460 length_fmt::<DER>().lemma_parse_safe(ibuf);
461 }
462 }
463
464 impl<const DER: bool> Productive for LengthFmt<DER> {
465 proof fn lemma_productive(&self, s: Seq<u8>) {
466 length_fmt::<DER>().lemma_productive(s);
467 }
468 }
469
470 impl SoundParser for LengthFmt<true> {
471 proof fn lemma_parse_sound_consumption(&self, ibuf: Seq<u8>) {
472 lemma_length_fmt_usize_sound_nonmal_inv();
473 length_fmt::<true>().lemma_parse_sound_consumption(ibuf);
474 }
475
476 proof fn lemma_parse_sound_value(&self, ibuf: Seq<u8>) {
477 lemma_length_fmt_usize_sound_nonmal_inv();
478 length_fmt::<true>().lemma_parse_sound_value(ibuf);
479 }
480 }
481
482 impl<const DER: bool> NonTailFmt for LengthFmt<DER> {
483 proof fn lemma_serialize_dps_prepend(&self, v: Self::SValue, obuf: Seq<u8>) {
484 length_fmt::<DER>().lemma_serialize_dps_prepend(v, obuf);
485 }
486
487 proof fn lemma_serialize_dps_len(&self, v: Self::SValue, obuf: Seq<u8>) {
488 length_fmt::<DER>().lemma_serialize_dps_len(v, obuf);
489 }
490 }
491
492 impl<const DER: bool> GoodSerializer for LengthFmt<DER> {
493 proof fn lemma_serialize_len(&self, v: Self::SVal) {
494 length_fmt::<DER>().lemma_serialize_len(v);
495 }
496 }
497
498 impl<const DER: bool> SPRoundTripDps for LengthFmt<DER> {
499 proof fn theorem_serialize_dps_parse_roundtrip(&self, v: Self::T, obuf: Seq<u8>) {
500 lemma_length_fmt_usize_unambiguous::<DER>();
501 length_fmt::<DER>().theorem_serialize_dps_parse_roundtrip(v, obuf);
502 }
503 }
504
505 impl<const DER: bool> NoLookAhead for LengthFmt<DER> {
506 proof fn lemma_no_lookahead(&self, i1: Seq<u8>, i2: Seq<u8>) {
507 length_fmt::<DER>().lemma_no_lookahead(i1, i2);
508 }
509 }
510
511 impl NonMalleable for LengthFmt<true> {
512 proof fn lemma_parse_non_malleable(&self, buf1: Seq<u8>, buf2: Seq<u8>) {
513 lemma_length_fmt_usize_sound_nonmal_inv();
514 length_fmt::<true>().lemma_parse_non_malleable(buf1, buf2);
515 }
516 }
517
518 impl<const DER: bool> EquivSerializersGeneral for LengthFmt<DER> {
519 proof fn lemma_serialize_equiv(&self, v: Self::SVal, obuf: Seq<u8>) {
520 length_fmt::<DER>().lemma_serialize_equiv(v, obuf);
521 }
522 }
523
524 impl<const DER: bool> EquivSerializers for LengthFmt<DER> {
525 proof fn lemma_serialize_equiv_on_empty(&self, v: Self::SVal) {
526 length_fmt::<DER>().lemma_serialize_equiv_on_empty(v);
527 }
528 }
529
530}
531
532impl<const DER: bool> Parser<&[u8]> for super::LengthFmt<DER> {
533 type PT = usize;
534
535 fn parse(&self, ibuf: &&[u8]) -> PResult<usize> {
536 broadcast use crate::core::spec::SafeParser::lemma_parse_safe;
537 broadcast use crate::core::spec::SoundParser::lemma_parse_sound_value;
538
539 let (n1, b1): (usize, u8) = U8.parse(ibuf)?;
540 let rest = ibuf.skip(n1);
541
542 if b1 <= SHORT_FORM_MAX {
543 Ok((n1, b1 as usize))
544 } else if 0b1000_0000 < b1 && b1 < 0b1111_1111 {
545 let count = b1 & 0b0111_1111;
546 let (n2, len_bytes) = Varied(count).parse(&rest)?;
547 if DER {
548 if count == 1 && len_bytes[0] <= SHORT_FORM_MAX {
549 return Err(ParseError::non_canonical());
550 }
551 if count > 1 && len_bytes[0] == 0x00u8 {
552 return Err(ParseError::non_canonical());
553 }
554 }
555 match usize::BITS {
556 32 if len_bytes.len() > 4 => return Err(ParseError::overflow()),
557 64 if len_bytes.len() > 8 => return Err(ParseError::overflow()),
558 _ => {},
559 }
560 let value = usize_from_be_bytes_exec(len_bytes);
561 Ok((n1 + n2, value))
562 } else {
563 Err(ParseError::invalid_length())
564 }
565 }
566}
567
568impl<Output: OutputBuf, const DER: bool> Serializer<Output, usize> for super::LengthFmt<DER> {
569 fn serialize_into(&self, v: &usize, obuf: &mut Output) {
570 broadcast use crate::core::exec::output::outbuf_lemmas;
571
572 if *v <= SHORT_FORM_MAX as usize {
573 U8.serialize_into(&(*v as u8), obuf);
574 } else {
575 let count = usize_to_be_bytes_len(*v);
576 let mut bytes = [0u8;size_of::<usize>()];
577 let (encoded, _) = bytes.split_at_mut(count);
578 usize_to_be_bytes_in_place(*v, encoded);
579 U8.serialize_into(&(0b1000_0000 | (count as u8)), obuf);
580 Varied(count).serialize_into(&bytes[0..count], obuf);
581 }
582 }
583}
584
585impl<const DER: bool> Prepare<usize> for super::LengthFmt<DER> {
586 fn prepare(&self, v: &usize) -> Result<usize, PreSerializeError> {
587 proof {
588 lemma_length_fmt_usize_props::<DER>(*v);
589 }
590 if *v <= SHORT_FORM_MAX as usize {
591 Ok(1usize)
592 } else {
593 Ok(1 + usize_to_be_bytes_len(*v))
594 }
595 }
596}
597
598impl<const DER: bool> ByteLen<usize> for super::LengthFmt<DER> {
599 fn length(&self, v: &usize) -> usize {
600 proof {
601 lemma_length_fmt_usize_props::<DER>(*v);
602 }
603 if *v <= SHORT_FORM_MAX as usize {
604 1
605 } else {
606 1 + usize_to_be_bytes_len(*v)
607 }
608 }
609}
610
611impl SpecParser for super::BerLengthFmt {
612 type PVal = super::BerLength;
613
614 open spec fn spec_parse(&self, ibuf: Seq<u8>) -> Option<(int, Self::PVal)> {
615 ber_length_fmt().spec_parse(ibuf)
616 }
617}
618
619impl Consistency for super::BerLengthFmt {
620 type Val = super::BerLength;
621
622 open spec fn consistent(&self, v: Self::Val) -> bool {
623 ber_length_fmt().consistent(v)
624 }
625}
626
627impl SpecSerializerDps for super::BerLengthFmt {
628 type SValue = super::BerLength;
629
630 open spec fn spec_serialize_dps(&self, v: Self::SValue, obuf: Seq<u8>) -> Seq<u8> {
631 ber_length_fmt().spec_serialize_dps(v, obuf)
632 }
633}
634
635impl SpecSerializer for super::BerLengthFmt {
636 type SVal = super::BerLength;
637
638 open spec fn spec_serialize(&self, v: Self::SVal) -> Seq<u8> {
639 ber_length_fmt().spec_serialize(v)
640 }
641}
642
643impl SpecByteLen for super::BerLengthFmt {
644 type T = super::BerLength;
645
646 open spec fn byte_len(&self, v: Self::T) -> nat {
647 ber_length_fmt().byte_len(v)
648 }
649}
650
651impl SafeParser for super::BerLengthFmt {
652 proof fn lemma_parse_safe(&self, ibuf: Seq<u8>) {
653 ber_length_fmt().lemma_parse_safe(ibuf)
654 }
655}
656
657impl Productive for super::BerLengthFmt {
658 proof fn lemma_productive(&self, ibuf: Seq<u8>) {
659 ber_length_fmt().lemma_productive(ibuf)
660 }
661}
662
663impl NonTailFmt for super::BerLengthFmt {
664 proof fn lemma_serialize_dps_prepend(&self, v: Self::SValue, obuf: Seq<u8>) {
665 ber_length_fmt().lemma_serialize_dps_prepend(v, obuf)
666 }
667
668 proof fn lemma_serialize_dps_len(&self, v: Self::SValue, obuf: Seq<u8>) {
669 ber_length_fmt().lemma_serialize_dps_len(v, obuf)
670 }
671}
672
673impl GoodSerializer for super::BerLengthFmt {
674 proof fn lemma_serialize_len(&self, v: Self::SVal) {
675 ber_length_fmt().lemma_serialize_len(v)
676 }
677}
678
679impl SPRoundTripDps for super::BerLengthFmt {
680 proof fn theorem_serialize_dps_parse_roundtrip(&self, v: Self::T, obuf: Seq<u8>) {
681 reveal(disjoint_domains);
682 assert(disjoint_domains(Const(U8, 0x80u8), super::LengthFmt::<false>));
683 ber_length_fmt().theorem_serialize_dps_parse_roundtrip(v, obuf)
684 }
685}
686
687impl NoLookAhead for super::BerLengthFmt {
688 proof fn lemma_no_lookahead(&self, i1: Seq<u8>, i2: Seq<u8>) {
689 reveal(disjoint_domains);
690 assert(disjoint_domains(Const(U8, 0x80u8), super::LengthFmt::<false>));
691 ber_length_fmt().lemma_no_lookahead(i1, i2)
692 }
693}
694
695impl EquivSerializersGeneral for super::BerLengthFmt {
696 proof fn lemma_serialize_equiv(&self, v: Self::SVal, obuf: Seq<u8>) {
697 ber_length_fmt().lemma_serialize_equiv(v, obuf)
698 }
699}
700
701impl EquivSerializers for super::BerLengthFmt {
702 proof fn lemma_serialize_equiv_on_empty(&self, v: Self::SVal) {
703 ber_length_fmt().lemma_serialize_equiv_on_empty(v)
704 }
705}
706
707impl Parser<&[u8]> for super::BerLengthFmt {
708 type PT = super::BerLength;
709
710 fn parse(&self, ibuf: &&[u8]) -> PResult<Self::PT> {
711 let (n, first) = U8.parse(ibuf)?;
712 if first == 0x80u8 {
713 Ok((n, super::BerLength::Indefinite))
714 } else {
715 let (n, len) = super::LengthFmt::<false>.parse(ibuf)?;
716 Ok((n, super::BerLength::Definite(len)))
717 }
718 }
719}
720
721impl<Output: OutputBuf> Serializer<Output, super::BerLength> for super::BerLengthFmt {
722 fn serialize_into(&self, v: &super::BerLength, obuf: &mut Output) {
723 match v {
724 super::BerLength::Indefinite => U8.serialize_into(&0x80u8, obuf),
725 super::BerLength::Definite(n) => super::LengthFmt::<false>.serialize_into(n, obuf),
726 }
727 }
728}
729
730impl Prepare<super::BerLength> for super::BerLengthFmt {
731 fn prepare(&self, v: &super::BerLength) -> Result<usize, PreSerializeError> {
732 match v {
733 super::BerLength::Indefinite => Ok(1),
734 super::BerLength::Definite(n) => super::LengthFmt::<false>.prepare(n),
735 }
736 }
737}
738
739impl ByteLen<super::BerLength> for super::BerLengthFmt {
740 fn length(&self, v: &super::BerLength) -> usize {
741 match v {
742 super::BerLength::Indefinite => 1,
743 super::BerLength::Definite(n) => super::LengthFmt::<false>.length(n),
744 }
745 }
746}
747
748}