vest_lib/properties.rs
1pub use crate::buf_traits::*;
2pub use crate::errors::*;
3use alloc::boxed::Box;
4
5use vstd::prelude::*;
6use vstd::*;
7
8verus! {
9
10/// The parse result of a combinator.
11pub type PResult<T, E> = Result<(usize, T), E>;
12
13/// The serialize result of a combinator.
14pub type SResult<T, E> = Result<T, E>;
15
16/// Specification for parser and serializer [`Combinator`]s. All Vest combinators must implement this
17/// trait.
18pub trait SpecCombinator {
19 /// The view of [`Combinator::Result`].
20 type Type;
21
22 /// Well-formedness of the format [`Self::type`] (e.g., refinements on the type).
23 open spec fn wf(&self, v: Self::Type) -> bool {
24 true
25 }
26
27 /// Pre-conditions for parsing and serialization.
28 ///
29 /// ## Examples
30 ///
31 /// - Sequencing combinators require that the first combinator is prefix-secure.
32 /// - Repetition combinators require that the inner combinator is prefix-secure.
33 /// - [`crate::regular::repetition::Repeat`] combinator requires that the
34 /// inner combinator is productive.
35 /// - [`crate::regular::variant::Choice`] combinator requires that `Snd` is [`crate::regular::disjoint::DisjointFrom`] `Fst`.
36 open spec fn requires(&self) -> bool {
37 true
38 }
39
40 /// The specification of [`Combinator::parse`].
41 spec fn spec_parse(&self, s: Seq<u8>) -> Option<(int, Self::Type)>;
42
43 /// The specification of [`Combinator::serialize`].
44 spec fn spec_serialize(&self, v: Self::Type) -> Seq<u8>;
45}
46
47/// Theorems and lemmas that must be proven for a combinator to be considered correct and secure.
48pub trait SecureSpecCombinator: SpecCombinator {
49 /// One of the top-level roundtrip properties
50 /// It reads "if we serialize a (well-formed) value, then parsing the serialized bytes should
51 /// give us the same value back."
52 /// If we somehow get a different value, it means that different high-level values can
53 /// correspond to the same low-level representation, or put differently, the same byte
54 /// sequences can be parsed into different values.
55 ///
56 /// This property can be understood as
57 /// 1. injectivity of serialization: different values should serialize to different byte
58 /// sequences
59 /// 2. surjectivity of parsing: every valid high-level value should associate with at least one
60 /// low-level representation.
61 /// 3. correctness of parsing: given a correct serializer that produces some byte sequence from
62 /// a value, the corresponding parser should be able to parse the byte sequence back to the
63 /// same value (can lead to format-confusion attacks if not satisfied).
64 proof fn theorem_serialize_parse_roundtrip(&self, v: Self::Type)
65 requires
66 self.requires(),
67 ensures
68 self.wf(v) ==> self.spec_parse(self.spec_serialize(v)) == Some(
69 (self.spec_serialize(v).len() as int, v),
70 ),
71 ;
72
73 /// Followed from `theorem_serialize_parse_roundtrip`
74 proof fn corollary_parse_surjective(&self, v: Self::Type)
75 requires
76 self.requires(),
77 self.wf(v),
78 ensures
79 exists|b: Seq<u8>| #[trigger] self.spec_parse(b) matches Some((_, v_)) && v_ == v,
80 {
81 self.theorem_serialize_parse_roundtrip(v);
82 }
83
84 /// Followed from `theorem_serialize_parse_roundtrip`
85 proof fn corollary_serialize_injective(&self, v1: Self::Type, v2: Self::Type)
86 requires
87 self.requires(),
88 ensures
89 self.wf(v1) && self.wf(v2) ==> self.spec_serialize(v1) == self.spec_serialize(v2) ==> v1
90 == v2,
91 {
92 self.theorem_serialize_parse_roundtrip(v1);
93 self.theorem_serialize_parse_roundtrip(v2);
94 }
95
96 /// Followed from `theorem_serialize_parse_roundtrip`
97 proof fn corollary_serialize_injective_contraposition(&self, v1: Self::Type, v2: Self::Type)
98 requires
99 self.requires(),
100 ensures
101 self.wf(v1) && self.wf(v2) ==> v1 != v2 ==> self.spec_serialize(v1)
102 != self.spec_serialize(v2),
103 {
104 self.theorem_serialize_parse_roundtrip(v1);
105 self.theorem_serialize_parse_roundtrip(v2);
106 }
107
108 /// One of the top-level roundtrip properties
109 /// It reads "if we successfully parse a byte sequence, then serializing the parsed value should
110 /// give us the same byte sequence back."
111 /// If we somehow get a different byte sequence, it means that different low-level representations
112 /// can correspond to the same high-level value, or put differently, the same value can be
113 /// serialized into different byte sequences.
114 ///
115 /// This property can be understood as
116 /// 1. injectivity of parsing: different byte sequences should parse to different values (can
117 /// lead to parser mallability attacks if not satisfied)
118 /// 2. correctness of serialization: given a correct parser that produces some value from a byte
119 /// sequence, the corresponding serializer should be able to serialize the value back to the same
120 /// byte sequence (up to the number of bytes consumed).
121 proof fn theorem_parse_serialize_roundtrip(&self, buf: Seq<u8>)
122 requires
123 self.requires(),
124 ensures
125 self.spec_parse(buf) matches Some((n, v)) ==> {
126 &&& self.wf(v)
127 &&& self.spec_serialize(v) == buf.take(n)
128 },
129 ;
130
131 /// Followed from `theorem_parse_serialize_roundtrip`
132 proof fn corollary_parse_non_malleable(&self, buf1: Seq<u8>, buf2: Seq<u8>)
133 requires
134 self.requires(),
135 ensures
136 self.spec_parse(buf1) matches Some((n1, v1)) ==> self.spec_parse(buf2) matches Some(
137 (n2, v2),
138 ) ==> v1 == v2 ==> buf1.take(n1) == buf2.take(n2),
139 {
140 self.theorem_parse_serialize_roundtrip(buf1);
141 self.theorem_parse_serialize_roundtrip(buf2);
142 }
143
144 /// Like an associated constant, denotes whether the combinator is prefix-secure.
145 spec fn is_prefix_secure() -> bool;
146
147 /// This prefix-secure lemma is used in the proof of the roundtrip properties for sequencing
148 /// and repeating combinators.
149 proof fn lemma_prefix_secure(&self, s1: Seq<u8>, s2: Seq<u8>)
150 requires
151 self.requires(),
152 ensures
153 Self::is_prefix_secure() ==> self.spec_parse(s1) is Some ==> self.spec_parse(s1 + s2)
154 == self.spec_parse(s1),
155 ;
156
157 /// The parser-length lemma is used in the proof of the roundtrip properties and the prefix-secure
158 /// lemma
159 proof fn lemma_parse_length(&self, s: Seq<u8>)
160 requires
161 self.requires(),
162 ensures
163 self.spec_parse(s) matches Some((n, _)) ==> 0 <= n <= s.len(),
164 ;
165
166 /// Like an associated constant, denotes whether the combinator is productive
167 spec fn is_productive(&self) -> bool;
168
169 /// This lemma is used in the proof of the roundtrip properties for optional and unbounded
170 /// repeating combinators.
171 proof fn lemma_parse_productive(&self, s: Seq<u8>)
172 requires
173 self.requires(),
174 ensures
175 self.is_productive() ==> (self.spec_parse(s) matches Some((n, _)) ==> n > 0),
176 ;
177
178 /// This lemma is used in the proof of the roundtrip properties for optional and unbounded
179 /// repeating combinators.
180 proof fn lemma_serialize_productive(&self, v: Self::Type)
181 requires
182 self.requires(),
183 self.wf(v),
184 ensures
185 self.is_productive() ==> self.spec_serialize(v).len() > 0,
186 {
187 self.theorem_serialize_parse_roundtrip(v);
188 self.lemma_parse_productive(self.spec_serialize(v));
189 }
190}
191
192/// Implementation for parser and serializer combinators. A combinator's view must be a
193/// [`SecureSpecCombinator`].
194pub trait Combinator<'x, I, O>: View where
195 I: VestInput,
196 O: VestOutput<I>,
197 Self::V: SecureSpecCombinator<Type = <Self::Type as View>::V>,
198 {
199 /// The result type of parsing
200 type Type: View;
201
202 /// The input type of serialization, often a reference to [`Self::Type`].
203 /// For "structural" formats though (e.g., [`crate::regular::sequence::Pair`] and [`crate::regular::variant::Choice`]),
204 /// this is the tuple/sum of the corresponding [`Combinator::SType`] types.
205 type SType: View<V = <Self::Type as View>::V>;
206
207 /// The length of the output buffer.
208 /// This can be used to optimize serialization by pre-allocating the buffer.
209 fn length(&self, v: Self::SType) -> (len: usize)
210 requires
211 self@.requires(),
212 self.ex_requires(),
213 self@.wf(v@),
214 self@.spec_serialize(v@).len() <= usize::MAX,
215 ensures
216 len == self@.spec_serialize(v@).len(),
217 ;
218
219 /// Additional pre-conditions for parsing and serialization
220 ///
221 /// e.g., [`crate::regular::sequence::Pair`] combinator requires that the
222 /// [`crate::regular::sequence::Continuation`] is well-formed w.r.t. the
223 /// `spec_fn` closure.
224 open spec fn ex_requires(&self) -> bool {
225 true
226 }
227
228 /// The parsing function.
229 /// To enable "zero-copy" parsing, implementations of `parse` should not
230 /// consume/deepcopy the input buffer `I`, but rather return a slice of the
231 /// input buffer for `Self::Type` whenever possible.
232 /// See [`crate::buf_traits::VestInput`] and [`crate::buf_traits::VestPublicInput`] for
233 /// more details.
234 ///
235 /// ## Pre-conditions
236 ///
237 /// - [`SpecCombinator::requires`]
238 /// - [`Combinator::ex_requires`]
239 ///
240 /// ## Post-conditions
241 /// Essentially, the implementation of `parse` is functionally correct with respect to the
242 /// specification `spec_parse` on both success and failure cases.
243 fn parse(&self, s: I) -> (res: PResult<Self::Type, ParseError>)
244 requires
245 self@.requires(),
246 self.ex_requires(),
247 s@.len() <= usize::MAX,
248 ensures
249 res matches Ok((n, v)) ==> self@.spec_parse(s@) == Some((n as int, v@)),
250 self@.spec_parse(s@) matches Some((n, v)) ==> res matches Ok((m, u)) && m == n && v
251 == u@,
252 res is Err ==> self@.spec_parse(s@) is None,
253 self@.spec_parse(s@) is None ==> res is Err,
254 ;
255
256 /// The serialization function.
257 /// The intended use of `serialize` is to serialize a value `v` into the
258 /// buffer `buf` at the position `pos` "in-place" (i.e., without
259 /// allocating a new buffer or extending the buffer).
260 ///
261 /// ## Pre-conditions
262 ///
263 /// - [`SpecCombinator::requires`]
264 /// - [`Combinator::ex_requires`]
265 /// - [`SpecCombinator::wf`]
266 /// - `pos` is less than or equal to the length of the buffer, whose length
267 /// is less than or equal to `usize::MAX`.
268 ///
269 /// ## Post-conditions
270 /// `serialize` ensures that it is functionally correct with respect to the
271 /// specification `spec_serialize` when it returns `Ok`. This is because
272 /// `serialize` being a partial function can fail (e.g.,
273 /// insufficient buffer space), while `spec_serialize` is a
274 /// total function (with infinite buffer size) and will never fail.
275 fn serialize(&self, v: Self::SType, buf: &mut O, pos: usize) -> (res: SResult<
276 usize,
277 SerializeError,
278 >)
279 requires
280 self@.requires(),
281 self.ex_requires(),
282 self@.wf(v@),
283 pos <= old(buf)@.len() <= usize::MAX,
284 ensures
285 res matches Ok(n) ==> {
286 &&& buf@.len() == old(buf)@.len()
287 &&& pos <= usize::MAX - n && pos + n <= buf@.len()
288 &&& n == self@.spec_serialize(v@).len()
289 &&& buf@ == seq_splice(old(buf)@, pos, self@.spec_serialize(v@))
290 },
291 ;
292}
293
294impl<C: SpecCombinator> SpecCombinator for &C {
295 type Type = C::Type;
296
297 open spec fn wf(&self, v: Self::Type) -> bool {
298 (*self).wf(v)
299 }
300
301 open spec fn requires(&self) -> bool {
302 (*self).requires()
303 }
304
305 open spec fn spec_parse(&self, s: Seq<u8>) -> Option<(int, Self::Type)> {
306 (*self).spec_parse(s)
307 }
308
309 open spec fn spec_serialize(&self, v: Self::Type) -> Seq<u8> {
310 (*self).spec_serialize(v)
311 }
312}
313
314impl<C: SecureSpecCombinator> SecureSpecCombinator for &C {
315 open spec fn is_prefix_secure() -> bool {
316 C::is_prefix_secure()
317 }
318
319 open spec fn is_productive(&self) -> bool {
320 (*self).is_productive()
321 }
322
323 proof fn theorem_serialize_parse_roundtrip(&self, v: Self::Type) {
324 (*self).theorem_serialize_parse_roundtrip(v)
325 }
326
327 proof fn theorem_parse_serialize_roundtrip(&self, buf: Seq<u8>) {
328 (*self).theorem_parse_serialize_roundtrip(buf)
329 }
330
331 proof fn lemma_prefix_secure(&self, s1: Seq<u8>, s2: Seq<u8>) {
332 (*self).lemma_prefix_secure(s1, s2)
333 }
334
335 proof fn lemma_parse_length(&self, s: Seq<u8>) {
336 (*self).lemma_parse_length(s)
337 }
338
339 proof fn lemma_parse_productive(&self, s: Seq<u8>) {
340 (*self).lemma_parse_productive(s)
341 }
342}
343
344impl<'x, I, O, C: Combinator<'x, I, O>> Combinator<'x, I, O> for &C where
345 I: VestInput,
346 O: VestOutput<I>,
347 C::V: SecureSpecCombinator<Type = <C::Type as View>::V>,
348 {
349 type Type = C::Type;
350
351 type SType = C::SType;
352
353 fn length(&self, v: Self::SType) -> usize {
354 assert(self.ex_requires());
355 (*self).length(v)
356 }
357
358 open spec fn ex_requires(&self) -> bool {
359 (*self).ex_requires()
360 }
361
362 fn parse(&self, s: I) -> (res: Result<(usize, Self::Type), ParseError>) {
363 (*self).parse(s)
364 }
365
366 fn serialize(&self, v: Self::SType, data: &mut O, pos: usize) -> (res: Result<
367 usize,
368 SerializeError,
369 >) {
370 (*self).serialize(v, data, pos)
371 }
372}
373
374impl<C: SpecCombinator> SpecCombinator for Box<C> {
375 type Type = C::Type;
376
377 open spec fn wf(&self, v: Self::Type) -> bool {
378 (**self).wf(v)
379 }
380
381 open spec fn requires(&self) -> bool {
382 (**self).requires()
383 }
384
385 open spec fn spec_parse(&self, s: Seq<u8>) -> Option<(int, Self::Type)> {
386 (**self).spec_parse(s)
387 }
388
389 open spec fn spec_serialize(&self, v: Self::Type) -> Seq<u8> {
390 (**self).spec_serialize(v)
391 }
392}
393
394impl<C: SecureSpecCombinator> SecureSpecCombinator for Box<C> {
395 open spec fn is_prefix_secure() -> bool {
396 C::is_prefix_secure()
397 }
398
399 open spec fn is_productive(&self) -> bool {
400 (**self).is_productive()
401 }
402
403 proof fn theorem_serialize_parse_roundtrip(&self, v: Self::Type) {
404 (**self).theorem_serialize_parse_roundtrip(v)
405 }
406
407 proof fn theorem_parse_serialize_roundtrip(&self, buf: Seq<u8>) {
408 (**self).theorem_parse_serialize_roundtrip(buf)
409 }
410
411 proof fn lemma_prefix_secure(&self, s1: Seq<u8>, s2: Seq<u8>) {
412 (**self).lemma_prefix_secure(s1, s2)
413 }
414
415 proof fn lemma_parse_length(&self, s: Seq<u8>) {
416 (**self).lemma_parse_length(s)
417 }
418
419 proof fn lemma_parse_productive(&self, s: Seq<u8>) {
420 (**self).lemma_parse_productive(s)
421 }
422}
423
424impl<'x, I, O, C: Combinator<'x, I, O>> Combinator<'x, I, O> for Box<C> where
425 I: VestInput,
426 O: VestOutput<I>,
427 C::V: SecureSpecCombinator<Type = <C::Type as View>::V>,
428 {
429 type Type = C::Type;
430
431 type SType = C::SType;
432
433 fn length(&self, v: Self::SType) -> usize {
434 (**self).length(v)
435 }
436
437 open spec fn ex_requires(&self) -> bool {
438 (**self).ex_requires()
439 }
440
441 fn parse(&self, s: I) -> (res: Result<(usize, Self::Type), ParseError>) {
442 (**self).parse(s)
443 }
444
445 fn serialize(&self, v: Self::SType, data: &mut O, pos: usize) -> (res: Result<
446 usize,
447 SerializeError,
448 >) {
449 (**self).serialize(v, data, pos)
450 }
451}
452
453// The following is an attempt to support `Fn`s as combinators.
454// I started implementing it because Verus doesn't support existential types (impl Trait) yet,
455// which is required to be able to put `Depend` combinator in the function's return type,
456// but more generally, I think it's probably also good to have a way in our framework to define
457// combinators as a group of (parsing and serializing) functions.
458//
459// Overall this is doable, but it's a bit tricky to implement because of the current limitations of Verus:
460// - Verus doesn't have general support for struct invariants yet, which means we have to add
461// pre-conditions to the security properties (i.e. the struct containing a pair of parsing and
462// serializing functions must be "well-formed" in some sense).
463// - Verus doesn't have general support for `&mut` types yet, which means for serialization we
464// cannot freely pass around the `&mut Vec<u8>`
465//
466// In theory, we could factor out all the lifetime parameters in `Combinator` trait and use generic
467// type parameters instead for both parsing and serialization, but that would require another
468// entire-codebase refactoring, which I think is not worth it at this point.
469//
470// #[verifier::reject_recursive_types(Type)]
471// pub struct SpecCombinatorFn<Type, const Prefix: u8> {
472// pub parse: spec_fn(Seq<u8>) -> PResult<Type, ()>,
473// pub serialize: spec_fn(Type) -> SResult<Seq<u8>, ()>,
474// }
475//
476// impl<Type, const Prefix: u8> SpecCombinatorFn<Type, Prefix> {
477// pub open spec fn new(
478// parse: spec_fn(Seq<u8>) -> PResult<Type, ()>,
479// serialize: spec_fn(Type) -> SResult<Seq<u8>, ()>,
480// ) -> (o: Self)
481// recommends
482// forall|v| Self::theorem_serialize_parse_roundtrip(parse, serialize, v),
483// forall|buf| Self::theorem_parse_serialize_roundtrip(parse, serialize, buf),
484// forall|s1, s2| Self::lemma_prefix_secure(parse, s1, s2),
485// {
486// Self { parse, serialize }
487// }
488//
489// pub open spec fn theorem_serialize_parse_roundtrip(
490// parse: spec_fn(Seq<u8>) -> PResult<Type, ()>,
491// serialize: spec_fn(Type) -> SResult<Seq<u8>, ()>,
492// v: Type,
493// ) -> bool {
494// serialize(v) matches Ok(b) ==> parse(b) == Ok::<_, ()>((b.len() as usize, v))
495// }
496//
497// pub open spec fn theorem_parse_serialize_roundtrip(
498// parse: spec_fn(Seq<u8>) -> Result<(usize, Type), ()>,
499// serialize: spec_fn(Type) -> Result<Seq<u8>, ()>,
500// buf: Seq<u8>,
501// ) -> bool {
502// buf.len() <= usize::MAX ==> ( parse(buf) matches Ok((n, v)) ==> serialize(v) == Ok::<
503// _,
504// (),
505// >(buf.take(n as int)) )
506// }
507//
508// pub open spec fn lemma_prefix_secure(
509// parse: spec_fn(Seq<u8>) -> Result<(usize, Type), ()>,
510// s1: Seq<u8>,
511// s2: Seq<u8>,
512// ) -> bool {
513// s1.len() + s2.len() <= usize::MAX && (Prefix == 1) ==>
514// parse(s1) is Ok ==> parse(s1 + s2) == parse(s1)
515// }
516// }
517//
518//
519// impl<Type, const Prefix: u8> SpecCombinator for SpecCombinatorFn<Type, Prefix> {
520// type Type = Type;
521//
522// open spec fn spec_parse(&self, s: Seq<u8>) -> Result<(usize, Self::Type), ()> {
523// if let Ok((n, v)) = (self.parse)(s) {
524// if n <= s.len() {
525// Ok((n, v))
526// } else {
527// Err(())
528// }
529// } else {
530// Err(())
531// }
532// }
533//
534// open spec fn spec_serialize(&self, v: Self::Type) -> Result<Seq<u8>, ()> {
535// (self.serialize)(v)
536// }
537//
538// proof fn spec_parse_wf(&self, s: Seq<u8>) {
539// }
540// }
541//
542// impl<Type, const Prefix: u8> SecureSpecCombinator for SpecCombinatorFn<Type, Prefix> {
543// open spec fn is_prefix_secure() -> bool {
544// Prefix == 1
545// }
546//
547// proof fn theorem_serialize_parse_roundtrip(&self, v: Self::Type) {
548// assume(Self::theorem_serialize_parse_roundtrip(self.parse, self.serialize, v));
549// }
550//
551// proof fn theorem_parse_serialize_roundtrip(&self, buf: Seq<u8>) {
552// assume(Self::theorem_parse_serialize_roundtrip(self.parse, self.serialize, buf));
553// }
554//
555// proof fn lemma_prefix_secure(&self, s1: Seq<u8>, s2: Seq<u8>) {
556// assume(Self::lemma_prefix_secure(self.parse, s1, s2));
557// }
558// }
559//
560// pub struct CombinatorFn<I, O, R, P, S, const Prefix: u8> where
561// I: VestInput,
562// O: VestOutput<I>,
563// R: View,
564// P: Continuation<I, Output = PResult<R, ParseError>>,
565// S: for<'a> Continuation<(R, &'a mut O, usize), Output = SResult<usize, SerializeError>>,
566// {
567// pub parse: P,
568// pub serialize: S,
569// pub spec_parse: Ghost<spec_fn(Seq<u8>) -> PResult<R::V, ()>>,
570// pub spec_serialize: Ghost<spec_fn(R::V) -> SResult<Seq<u8>, ()>>,
571// phantom: std::marker::PhantomData<(I, O)>,
572// }
573//
574// impl<'a, 'b, R, P, S, const Prefix: u8> View for CombinatorFn<'a, 'b, R, P, S, Prefix> where
575// R: View,
576// P: Fn(&'a [u8]) -> Result<(usize, R), ()>,
577// S: Fn(R, &'b mut Vec<u8>, usize) -> Result<usize, ()>,
578// {
579// type V = SpecCombinatorFn<R::V, Prefix>;
580//
581// open spec fn view(&self) -> Self::V {
582// let Ghost(parse) = self.spec_parse;
583// let Ghost(serialize) = self.spec_serialize;
584// SpecCombinatorFn {
585// parse,
586// serialize,
587// }
588// }
589// }
590//
591// impl<'a, 'b, R, P, S, const Prefix: u8> Combinator for CombinatorFn<'a, 'b, R, P, S, Prefix> where
592// R: View,
593// P: Fn(&'a [u8]) -> Result<(usize, R), ()>,
594// S: Fn(R, &'b mut Vec<u8>, usize) -> Result<usize, ()>,
595// Self::V: SecureSpecCombinator<Type = R::V>,
596// {
597// type Result<'c> = R;
598//
599// type Owned = R;
600//
601// open spec fn spec_length(&self) -> Option<usize> {
602// None
603// }
604//
605// fn length(&self) -> Option<usize> {
606// None
607// }
608//
609// fn exec_is_prefix_secure() -> bool {
610// Prefix == 1
611// }
612//
613// fn parse<'c>(&self, s: &'c [u8]) -> Result<(usize, Self::Result<'c>), ()> where 'c: 'a {
614// (self.parse)(s)
615// }
616//
617// fn serialize(&self, v: Self::Result<'_>, data: &mut Vec<u8>, pos: usize) -> Result<usize, ()> {
618// (self.serialize)(v, data, pos)
619// }
620// }
621} // verus!
622// ///////// Separating the parsing and serializing functions
623// ///////// Unsuccesful due to conflicting trait impls and Verus limitations (&mut support)
624// // pub trait Parser<I, O>
625// // where
626// // I: VestInput,
627// // {
628// // type Type;
629// //
630// // fn parse_fn(&self, s: I) -> PResult<Self::Type, ParseError>;
631// // }
632// //
633// // pub trait Serializer<I, O>
634// // where
635// // I: VestInput,
636// // O: VestOutput<I>,
637// // {
638// // type Type;
639// //
640// // fn serialize_fn(
641// // &self,
642// // v: Self::Type,
643// // data: &mut O,
644// // pos: usize,
645// // ) -> SResult<usize, SerializeError>;
646// // }
647// //
648// // impl<I, O, Type, F> Parser<I, O> for F
649// // where
650// // I: VestInput,
651// // F: Fn(I) -> PResult<Type, ParseError>,
652// // {
653// // type Type = Type;
654// //
655// // fn parse_fn(&self, s: I) -> PResult<Self::Type, ParseError> {
656// // self(s)
657// // }
658// // }
659// //
660// // impl<I, O, Fst, Snd> Parser<I, O> for (Fst, Snd)
661// // where
662// // I: VestInput,
663// // O: VestOutput<I>,
664// // Fst: Combinator<I, O>,
665// // Snd: Combinator<I, O>,
666// // Fst::V: SecureSpecCombinator<Type = <Fst::Type as View>::V>,
667// // Snd::V: SecureSpecCombinator<Type = <Snd::Type as View>::V>,
668// // {
669// // type Type = (Fst::Type, Snd::Type);
670// //
671// // fn parse_fn(&self, s: I) -> PResult<Self::Type, ParseError> {
672// // (&self.0, &self.1).parse(s)
673// // }
674// // }
675// //
676// // impl<I: VestPublicInput, O: VestPublicOutput<I>> Parser<I, O> for crate::regular::uints::U8 {
677// // type Type = u8;
678// //
679// // fn parse_fn(&self, s: I) -> PResult<Self::Type, ParseError> {
680// // <_ as Combinator<I, O>>::parse(self, s)
681// // }
682// // }
683// //
684// // fn parse_pair_of_u8<I, O>(s: I) -> PResult<(u8, u8), ParseError>
685// // where
686// // I: VestPublicInput,
687// // O: VestPublicOutput<I>,
688// // {
689// // <_ as Parser<I, O>>::parse_fn(&(crate::regular::uints::U8, crate::regular::uints::U8), s)
690// // }
691// //
692// // fn test<I, O, P: Parser<I, O>>(p: P, s: I) -> PResult<P::Type, ParseError>
693// // where
694// // I: VestPublicInput,
695// // {
696// // p.parse_fn(s)
697// // }
698// //
699// // fn test2() {
700// // let s = Vec::new();
701// // let r = test::<_, Vec<u8>, _>(parse_pair_of_u8::<&[u8], Vec<u8>>, s.as_slice());
702// // }
703// // fn parse_pair<I, O, Fst, Snd>(
704// // fst: Fst,
705// // snd: Snd,
706// // s: I,
707// // ) -> PResult<(Fst::Type, Snd::Type), ParseError>
708// // where
709// // I: VestInput,
710// // O: VestOutput<I>,
711// // Fst: Parser<I, O>,
712// // Snd: Parser<I, O>,
713// // {
714// // // (fst, snd).parse(s)
715// // }
716// // impl<I, O, C: Combinator<I, O>> Parser<I, O> for C
717// // where
718// // I: VestInput,
719// // O: VestOutput<I>,
720// // C::V: SecureSpecCombinator<Type = <C::Type as View>::V>,
721// // {
722// // type Type = C::Type;
723// //
724// // fn parse_fn(&self, s: I) -> PResult<Self::Type, ParseError> {
725// // self.parse(s)
726// // }
727// // }
728// // impl<I, O, C: Combinator<I, O>> Serializer<I, O> for C
729// // where
730// // I: VestInput,
731// // O: VestOutput<I>,
732// // C::V: SecureSpecCombinator<Type = <C::Type as View>::V>,
733// // {
734// // type Type = C::Type;
735// //
736// // fn serialize_fn(
737// // &self,
738// // v: Self::Type,
739// // data: &mut O,
740// // pos: usize,
741// // ) -> SResult<usize, SerializeError> {
742// // self.serialize(v, data, pos)
743// // }
744// // }
745// // fn parse_pair<I, O, Fst, Snd>(
746// // fst: &Fst,
747// // snd: &Snd,
748// // s: I,
749// // ) -> PResult<(Fst::Type, Snd::Type), ParseError>
750// // where
751// // I: VestInput,
752// // O: VestOutput<I>,
753// // Fst: Parser<I, Type = Fst::Type>,
754// // Snd: Parser<I, Type = Snd::Type>,
755// // {
756// // let (n, v1) = fst.parse(s.clone())?;
757// // let s_ = s.subrange(n, s.len());
758// // let (m, v2) = snd.parse(s_)?;
759// // if let Some(nm) = n.checked_add(m) {
760// // Ok((nm, (v1, v2)))
761// // } else {
762// // Err(ParseError::SizeOverflow)
763// // }
764// // }
765// ///////// "Lazy" combinators (`dyn` not supported by Verus yet) to support recursive formats
766// // impl<C: View> View for dyn crate::regular::depend::Continuation<(), Output = C> {
767// // type V = C::V;
768// //
769// // // spec fn view(&self) -> Self::V;
770// // }
771// // impl<I, O, C: Combinator<I, O>> Combinator<I, O>
772// // for Box<dyn crate::regular::depend::Continuation<(), Output = C>>
773// // where
774// // I: VestInput,
775// // O: VestOutput<I>,
776// // C::V: SecureSpecCombinator<Type = <C::Type as View>::V>,
777// // {
778// // type Type = Box<C::Type>;
779// //
780// // fn length(&self) -> Option<usize> {
781// // None
782// // }
783// //
784// // fn parse(&self, s: I) -> Result<(usize, Self::Type), ParseError> {
785// // match self.apply(()).parse(s) {
786// // Ok((n, v)) => Ok((n, Box::new(v))),
787// // Err(e) => Err(e),
788// // }
789// // }
790// //
791// // fn serialize(&self, v: Self::Type, data: &mut O, pos: usize) -> Result<usize, SerializeError> {
792// // self.apply(()).serialize(*v, data, pos)
793// // }
794// // }
795// //////// The following works, but currently we cannot verify it due to Verus limitations
796// // pub const INSTR_BASE: u8 = 0;
797// // pub const AUXBLOCK_BEGIN: u8 = 1;
798// // pub const AUXBLOCK_END: u8 = 11;
799// //
800// // #[derive(Debug)]
801// // struct InstrFmt(Either<u8, Box<AuxBlockFmt>>);
802// // #[derive(Debug)]
803// // struct AuxBlockFmt((u8, (RepeatResult<Box<InstrFmt>>, u8)));
804// //
805// // impl vstd::view::View for InstrFmt {
806// // type V = Self;
807// // }
808// // impl vstd::view::View for AuxBlockFmt {
809// // type V = Self;
810// // }
811// //
812// // struct InstrCom(
813// // pub OrdChoice<Refined<U8, TagPred<u8>>, Box<dyn Continuation<(), Output = AuxBlockCom>>>,
814// // );
815// // struct AuxBlockCom(
816// // pub (
817// // Refined<U8, TagPred<u8>>,
818// // (
819// // Star<Box<dyn Continuation<(), Output = InstrCom>>>,
820// // Refined<U8, TagPred<u8>>,
821// // ),
822// // ),
823// // );
824// // impl vstd::view::View for InstrCom {
825// // type V = Self;
826// // }
827// // impl vstd::view::View for AuxBlockCom {
828// // type V = Self;
829// // }
830// // impl SpecCombinator for InstrCom {
831// // type Type = InstrFmt;
832// // }
833// // impl SecureSpecCombinator for InstrCom {}
834// // impl SpecCombinator for AuxBlockCom {
835// // type Type = AuxBlockFmt;
836// // }
837// // impl SecureSpecCombinator for AuxBlockCom {}
838// //
839// // impl DisjointFrom<Refined<U8, TagPred<u8>>> for AuxBlockCom {}
840// //
841// // impl<'a> Combinator<&'a [u8], Vec<u8>> for InstrCom {
842// // type Type = InstrFmt;
843// // fn length(&self) -> Option<usize> {
844// // <_ as Combinator<&[u8], Vec<u8>>>::length(&self.0)
845// // }
846// // fn parse(&self, s: &'a [u8]) -> Result<(usize, Self::Type), ParseError> {
847// // match <_ as Combinator<&[u8], Vec<u8>>>::parse(&self.0, s) {
848// // Ok((n, Either::Left(v))) => Ok((n, InstrFmt(Either::Left(v)))),
849// // Ok((n, Either::Right(v))) => Ok((n, InstrFmt(Either::Right(v)))),
850// // Err(e) => Err(e),
851// // }
852// // }
853// // fn serialize(
854// // &self,
855// // v: Self::Type,
856// // data: &mut Vec<u8>,
857// // pos: usize,
858// // ) -> Result<usize, SerializeError> {
859// // <_ as Combinator<&[u8], Vec<u8>>>::serialize(&self.0, v.0, data, pos)
860// // }
861// // }
862// //
863// // impl<'a> Combinator<&'a [u8], Vec<u8>> for AuxBlockCom {
864// // type Type = AuxBlockFmt;
865// // fn length(&self) -> Option<usize> {
866// // <_ as Combinator<&[u8], Vec<u8>>>::length(&self.0)
867// // }
868// // fn parse(&self, s: &'a [u8]) -> Result<(usize, Self::Type), ParseError> {
869// // match <_ as Combinator<&[u8], Vec<u8>>>::parse(&self.0, s) {
870// // Ok((n, (a, (b, c)))) => Ok((n, AuxBlockFmt((a, (b, c))))),
871// // Err(e) => Err(e),
872// // }
873// // }
874// // fn serialize(
875// // &self,
876// // v: Self::Type,
877// // data: &mut Vec<u8>,
878// // pos: usize,
879// // ) -> Result<usize, SerializeError> {
880// // <_ as Combinator<&[u8], Vec<u8>>>::serialize(&self.0, v.0, data, pos)
881// // }
882// // }
883// //
884// // struct AuxBlockCont;
885// // struct InstrCont;
886// //
887// // impl Continuation<()> for AuxBlockCont {
888// // type Output = AuxBlockCom;
889// //
890// // fn apply(&self, i: ()) -> Self::Output {
891// // AuxBlockCom((
892// // Refined {
893// // inner: U8,
894// // predicate: TagPred(AUXBLOCK_BEGIN),
895// // },
896// // (
897// // Star(Box::new(InstrCont)),
898// // Refined {
899// // inner: U8,
900// // predicate: TagPred(AUXBLOCK_END),
901// // },
902// // ),
903// // ))
904// // }
905// // }
906// //
907// // impl Continuation<()> for InstrCont {
908// // type Output = InstrCom;
909// //
910// // fn apply(&self, i: ()) -> Self::Output {
911// // InstrCom(OrdChoice(
912// // Refined {
913// // inner: U8,
914// // predicate: TagPred(INSTR_BASE),
915// // },
916// // Box::new(AuxBlockCont),
917// // ))
918// // }
919// // }
920// //
921// // fn test() {
922// // // let buf = vec![0x00];
923// // let buf = vec![0x01, 0, 0, 0x01, 0, 0, 0, 0x0B, 0, 0x0B];
924// // let aux_block = AuxBlockCont.apply(());
925// // let instr = InstrCont.apply(());
926// // let (consumed, parsed) = instr.parse(&buf).unwrap_or_else(|e| {
927// // panic!("Failed to parse: {}", e);
928// // });
929// // println!("consumed: {}", consumed);
930// // println!("parsed: {:?}", parsed);
931// // }
932//
933// // Monomorphized approach to lazy combinators
934// // Would work if Verus fix https://github.com/verus-lang/verus/issues/1487
935// // use crate::regular::choice::Either;
936// // use crate::regular::choice::OrdChoice;
937// // use crate::regular::depend::Continuation;
938// // use crate::regular::disjoint::DisjointFrom;
939// // use crate::regular::refined::Refined;
940// // use crate::regular::repeat::RepeatResult;
941// // use crate::regular::star::Star;
942// // use crate::regular::tag::TagPred;
943// // use crate::regular::uints::U8;
944// // use crate::regular::map::Iso;
945// // use crate::regular::map::Mapped;
946// // use crate::regular::map::SpecIso;
947// //
948// // verus! {
949// //
950// // trait LazyCombinator {
951// // type Comb: View;
952// //
953// // spec fn spec_thunk(&self) -> Option<<Self::Comb as View>::V>;
954// //
955// // fn thunk(&self) -> (o: Option<Self::Comb>) ensures o matches Some(c) ==> c@ == self.spec_thunk().unwrap();
956// // }
957// //
958// // struct LazyInstrCom(usize);
959// // struct LazyAuxBlockCom(usize);
960// //
961// // impl View for LazyInstrCom {
962// // type V = Self;
963// //
964// // open spec fn view(&self) -> Self::V {
965// // *self
966// // }
967// // }
968// //
969// // impl View for LazyAuxBlockCom {
970// // type V = Self;
971// //
972// // open spec fn view(&self) -> Self::V {
973// // *self
974// // }
975// // }
976// //
977// // impl LazyCombinator for LazyInstrCom {
978// // type Comb = InstrCom;
979// //
980// // closed spec fn spec_thunk(&self) -> Option<<InstrCom as View>::V> {
981// // match self.0 {
982// // 0usize => None,
983// // _ => Some(
984// // SpecInstrCom(
985// // Mapped {
986// // inner: OrdChoice(
987// // Refined { inner: U8, predicate: TagPred(INSTR_BASE) },
988// // LazyAuxBlockCom((self.0 - 1) as usize),
989// // ),
990// // mapper: InstrIso,
991// // },
992// // )
993// // )
994// // }
995// // }
996// //
997// // fn thunk(&self) -> Option<InstrCom> {
998// // match self.0 {
999// // 0 => None,
1000// // _ => Some(
1001// // InstrCom(
1002// // Mapped {
1003// // inner: OrdChoice(
1004// // Refined { inner: U8, predicate: TagPred(INSTR_BASE) },
1005// // LazyAuxBlockCom(self.0 - 1),
1006// // ),
1007// // mapper: InstrIso,
1008// // },
1009// // )
1010// // )
1011// // }
1012// // }
1013// // }
1014// //
1015// // impl LazyCombinator for LazyAuxBlockCom {
1016// // type Comb = AuxBlockCom;
1017// //
1018// // closed spec fn spec_thunk(&self) -> Option<<AuxBlockCom as View>::V> {
1019// // match self.0 {
1020// // 0usize => None,
1021// // _ => Some(
1022// // SpecAuxBlockCom(
1023// // Mapped {
1024// // inner: (
1025// // Refined { inner: U8, predicate: TagPred(AUXBLOCK_BEGIN) },
1026// // (
1027// // Star(LazyInstrCom((self.0 - 1) as usize)),
1028// // Refined { inner: U8, predicate: TagPred(AUXBLOCK_END) },
1029// // ),
1030// // ),
1031// // mapper: AuxBlockIso,
1032// // },
1033// // )
1034// // )
1035// // }
1036// // }
1037// //
1038// // fn thunk(&self) -> Option<AuxBlockCom> {
1039// // match self.0 {
1040// // 0 => None,
1041// // _ => Some(
1042// // AuxBlockCom(
1043// // Mapped {
1044// // inner: (
1045// // Refined { inner: U8, predicate: TagPred(AUXBLOCK_BEGIN) },
1046// // (
1047// // Star(LazyInstrCom(self.0 - 1)),
1048// // Refined { inner: U8, predicate: TagPred(AUXBLOCK_END) },
1049// // ),
1050// // ),
1051// // mapper: AuxBlockIso,
1052// // },
1053// // )
1054// // )
1055// // }
1056// // }
1057// // }
1058// //
1059// // impl SpecCombinator for LazyInstrCom {
1060// // type Type = SpecInstrFmt;
1061// //
1062// // closed spec fn spec_parse(&self, s: Seq<u8>) -> PResult<Self::Type, ()> {
1063// // match self.spec_thunk() {
1064// // Some(c) => c.spec_parse(s),
1065// // None => Err(()),
1066// // }
1067// // // Self::spec_thunk().spec_parse(s)
1068// // }
1069// //
1070// // closed spec fn spec_serialize(&self, v: Self::Type) -> SResult<Seq<u8>, ()> {
1071// // match self.spec_thunk() {
1072// // Some(c) => c.spec_serialize(v),
1073// // None => Err(()),
1074// // }
1075// // // Self::spec_thunk().spec_serialize(v)
1076// // }
1077// // }
1078// //
1079// // impl SecureSpecCombinator for LazyInstrCom {
1080// // closed spec fn is_prefix_secure() -> bool {
1081// // <<Self as LazyCombinator>::Comb as View>::V::is_prefix_secure()
1082// // }
1083// //
1084// // closed spec fn is_productive(&self) -> bool {
1085// // match self.spec_thunk() {
1086// // Some(c) => c.is_productive(),
1087// // None => false,
1088// // }
1089// // }
1090// //
1091// // proof fn theorem_serialize_parse_roundtrip(&self, v: Self::Type) {
1092// // match self.spec_thunk() {
1093// // Some(c) => c.theorem_serialize_parse_roundtrip(v),
1094// // None => {}
1095// // }
1096// // }
1097// //
1098// // proof fn theorem_parse_serialize_roundtrip(&self, buf: Seq<u8>) {
1099// // match self.spec_thunk() {
1100// // Some(c) => c.theorem_parse_serialize_roundtrip(buf),
1101// // None => {}
1102// // }
1103// // }
1104// //
1105// // proof fn lemma_prefix_secure(&self, s1: Seq<u8>, s2: Seq<u8>) {
1106// // match self.spec_thunk() {
1107// // Some(c) => c.lemma_prefix_secure(s1, s2),
1108// // None => {}
1109// // }
1110// // }
1111// //
1112// // proof fn lemma_parse_length(&self, s: Seq<u8>) {
1113// // match self.spec_thunk() {
1114// // Some(c) => c.lemma_parse_length(s),
1115// // None => {}
1116// // }
1117// // }
1118// //
1119// // proof fn lemma_parse_productive(&self, s: Seq<u8>) {
1120// // match self.spec_thunk() {
1121// // Some(c) => c.lemma_parse_productive(s),
1122// // None => {}
1123// // }
1124// // }
1125// // }
1126// //
1127// // impl SpecCombinator for LazyAuxBlockCom {
1128// // type Type = SpecAuxBlockFmt;
1129// //
1130// // closed spec fn spec_parse(&self, s: Seq<u8>) -> PResult<Self::Type, ()> {
1131// // match self.spec_thunk() {
1132// // Some(c) => c.spec_parse(s),
1133// // None => Err(()),
1134// // }
1135// // }
1136// //
1137// // closed spec fn spec_serialize(&self, v: Self::Type) -> SResult<Seq<u8>, ()> {
1138// // match self.spec_thunk() {
1139// // Some(c) => c.spec_serialize(v),
1140// // None => Err(()),
1141// // }
1142// // }
1143// // }
1144// //
1145// // impl SecureSpecCombinator for LazyAuxBlockCom {
1146// // closed spec fn is_prefix_secure() -> bool {
1147// // <<Self as LazyCombinator>::Comb as View>::V::is_prefix_secure()
1148// // }
1149// //
1150// // closed spec fn is_productive(&self) -> bool {
1151// // match self.spec_thunk() {
1152// // Some(c) => c.is_productive(),
1153// // None => false,
1154// // }
1155// // }
1156// //
1157// // proof fn theorem_serialize_parse_roundtrip(&self, v: Self::Type) {
1158// // match self.spec_thunk() {
1159// // Some(c) => c.theorem_serialize_parse_roundtrip(v),
1160// // None => {}
1161// // }
1162// // }
1163// //
1164// // proof fn theorem_parse_serialize_roundtrip(&self, buf: Seq<u8>) {
1165// // match self.spec_thunk() {
1166// // Some(c) => c.theorem_parse_serialize_roundtrip(buf),
1167// // None => {}
1168// // }
1169// // }
1170// //
1171// // proof fn lemma_prefix_secure(&self, s1: Seq<u8>, s2: Seq<u8>) {
1172// // match self.spec_thunk() {
1173// // Some(c) => c.lemma_prefix_secure(s1, s2),
1174// // None => {}
1175// // }
1176// // }
1177// //
1178// // proof fn lemma_parse_length(&self, s: Seq<u8>) {
1179// // match self.spec_thunk() {
1180// // Some(c) => c.lemma_parse_length(s),
1181// // None => {}
1182// // }
1183// // }
1184// //
1185// // proof fn lemma_parse_productive(&self, s: Seq<u8>) {
1186// // match self.spec_thunk() {
1187// // Some(c) => c.lemma_parse_productive(s),
1188// // None => {}
1189// // }
1190// // }
1191// // }
1192// //
1193// // impl DisjointFrom<Refined<U8, TagPred<u8>>> for LazyAuxBlockCom {
1194// // closed spec fn disjoint_from(&self, other: &Refined<U8, TagPred<u8>>) -> bool {
1195// // match self.spec_thunk() {
1196// // Some(c) => c.0.inner.0.disjoint_from(other),
1197// // None => false,
1198// // }
1199// // // Self::spec_thunk().0.inner.0.disjoint_from(other)
1200// // // (self.0)().0.inner.0.disjoint_from(other)
1201// // }
1202// //
1203// // proof fn parse_disjoint_on(&self, other: &Refined<U8, TagPred<u8>>, buf: Seq<u8>) {
1204// // match self.spec_thunk() {
1205// // Some(c) => c.0.inner.0.parse_disjoint_on(other, buf),
1206// // None => {}
1207// // }
1208// // // Self::spec_thunk().0.inner.0.parse_disjoint_on(other, buf)
1209// // // (self.0)().0.inner.0.parse_disjoint_on(other, buf)
1210// // }
1211// // }
1212// //
1213// // impl<'a> Combinator<&'a [u8], Vec<u8>> for LazyInstrCom
1214// // {
1215// // type Type = Box<InstrFmt>;
1216// //
1217// // closed spec fn spec_length(&self) -> Option<usize> {
1218// // None
1219// // }
1220// //
1221// // fn length(&self) -> Option<usize> {
1222// // None
1223// // }
1224// //
1225// // closed spec fn parse_requires(&self) -> bool {
1226// // forall |c: <Self as LazyCombinator>::Comb| c.parse_requires()
1227// // }
1228// //
1229// // fn parse(&self, s: &[u8]) -> PResult<Self::Type, ParseError> {
1230// // match self.thunk() {
1231// // Some(c) => match c.parse(s) {
1232// // Ok((n, v)) => Ok((n, Box::new(v))),
1233// // Err(e) => Err(e),
1234// // },
1235// // None => Err(ParseError::Other("Ran out of fuels".to_string())),
1236// // }
1237// // }
1238// //
1239// // closed spec fn serialize_requires(&self) -> bool {
1240// // forall |c: <Self as LazyCombinator>::Comb| c.serialize_requires()
1241// // }
1242// //
1243// // fn serialize(&self, v: Self::Type, data: &mut Vec<u8>, pos: usize) -> SResult<usize, SerializeError> {
1244// // match self.thunk() {
1245// // Some(c) => c.serialize(*v, data, pos),
1246// // None => Err(SerializeError::Other("Ran out of fuels".to_string())),
1247// // }
1248// // }
1249// // }
1250// //
1251// // impl<'a> Combinator<&'a [u8], Vec<u8>> for LazyAuxBlockCom
1252// // {
1253// // type Type = Box<AuxBlockFmt>;
1254// //
1255// // closed spec fn spec_length(&self) -> Option<usize> {
1256// // None
1257// // }
1258// //
1259// // fn length(&self) -> Option<usize> {
1260// // None
1261// // }
1262// //
1263// // closed spec fn parse_requires(&self) -> bool {
1264// // forall |c: <Self as LazyCombinator>::Comb| c.parse_requires()
1265// // }
1266// //
1267// // fn parse(&self, s: &[u8]) -> PResult<Self::Type, ParseError> {
1268// // match self.thunk() {
1269// // Some(c) => match c.parse(s) {
1270// // Ok((n, v)) => Ok((n, Box::new(v))),
1271// // Err(e) => Err(e),
1272// // },
1273// // None => Err(ParseError::Other("Ran out of fuels".to_string())),
1274// // }
1275// // }
1276// //
1277// // closed spec fn serialize_requires(&self) -> bool {
1278// // forall |c: <Self as LazyCombinator>::Comb| c.serialize_requires()
1279// // }
1280// //
1281// // fn serialize(&self, v: Self::Type, data: &mut Vec<u8>, pos: usize) -> SResult<usize, SerializeError> {
1282// // match self.thunk() {
1283// // Some(c) => c.serialize(*v, data, pos),
1284// // None => Err(SerializeError::Other("Ran out of fuels".to_string())),
1285// // }
1286// // }
1287// // }
1288// //
1289// //
1290// // // impl<T: SpecCombinator> SpecCombinator for spec_fn() -> T {
1291// // // type Type = T::Type;
1292// // //
1293// // // open spec fn spec_parse(&self, s: Seq<u8>) -> Result<(usize, Self::Type), ()> {
1294// // // self().spec_parse(s)
1295// // // }
1296// // //
1297// // // open spec fn spec_serialize(&self, v: Self::Type) -> Result<Seq<u8>, ()> {
1298// // // self().spec_serialize(v)
1299// // // }
1300// // // }
1301// // //
1302// // // impl<T: SecureSpecCombinator> SecureSpecCombinator for spec_fn() -> T {
1303// // // open spec fn is_prefix_secure() -> bool {
1304// // // T::is_prefix_secure()
1305// // // }
1306// // //
1307// // // open spec fn is_productive(&self) -> bool {
1308// // // self().is_productive()
1309// // // }
1310// // //
1311// // // proof fn theorem_serialize_parse_roundtrip(&self, v: Self::Type) {
1312// // // self().theorem_serialize_parse_roundtrip(v)
1313// // // }
1314// // //
1315// // // proof fn theorem_parse_serialize_roundtrip(&self, buf: Seq<u8>) {
1316// // // self().theorem_parse_serialize_roundtrip(buf)
1317// // // }
1318// // //
1319// // // proof fn lemma_prefix_secure(&self, s1: Seq<u8>, s2: Seq<u8>) {
1320// // // self().lemma_prefix_secure(s1, s2)
1321// // // }
1322// // //
1323// // // proof fn lemma_parse_length(&self, s: Seq<u8>) {
1324// // // self().lemma_parse_length(s)
1325// // // }
1326// // //
1327// // // proof fn lemma_parse_productive(&self, s: Seq<u8>) {
1328// // // self().lemma_parse_productive(s)
1329// // // }
1330// // // }
1331// //
1332// //
1333// // pub const INSTR_BASE: u8 = 0;
1334// //
1335// // pub const AUXBLOCK_BEGIN: u8 = 1;
1336// //
1337// // pub const AUXBLOCK_END: u8 = 11;
1338// //
1339// // ghost enum SpecInstrFmt {
1340// // Base(u8),
1341// // Block(SpecAuxBlockFmt),
1342// // }
1343// //
1344// // type SpecInstrFmtAlias = Either<u8, SpecAuxBlockFmt>;
1345// //
1346// // ghost struct SpecAuxBlockFmt {
1347// // begin: u8,
1348// // instrs: Seq<SpecInstrFmt>,
1349// // end: u8,
1350// // }
1351// //
1352// // type SpecAuxBlockFmtAlias = (u8, (Seq<SpecInstrFmt>, u8));
1353// //
1354// // #[derive(Debug)]
1355// // enum InstrFmt {
1356// // Base(u8),
1357// // Block(Box<AuxBlockFmt>),
1358// // }
1359// //
1360// // type InstrFmtAlias = Either<u8, Box<AuxBlockFmt>>;
1361// //
1362// // #[derive(Debug)]
1363// // struct AuxBlockFmt {
1364// // begin: u8,
1365// // instrs: RepeatResult<Box<InstrFmt>>,
1366// // end: u8,
1367// // }
1368// //
1369// // type AuxBlockFmtAlias = (u8, (RepeatResult<Box<InstrFmt>>, u8));
1370// //
1371// // impl View for InstrFmt {
1372// // type V = SpecInstrFmt;
1373// //
1374// // closed spec fn view(&self) -> Self::V {
1375// // match self {
1376// // InstrFmt::Base(v) => SpecInstrFmt::Base(*v),
1377// // InstrFmt::Block(v) => SpecInstrFmt::Block(v@),
1378// // }
1379// // }
1380// // }
1381// //
1382// // impl View for AuxBlockFmt {
1383// // type V = SpecAuxBlockFmt;
1384// //
1385// // closed spec fn view(&self) -> Self::V {
1386// // SpecAuxBlockFmt { begin: self.begin, instrs: self.instrs.view(), end: self.end }
1387// // }
1388// // }
1389// //
1390// // impl SpecFrom<SpecInstrFmtAlias> for SpecInstrFmt {
1391// // closed spec fn spec_from(v: SpecInstrFmtAlias) -> Self {
1392// // match v {
1393// // Either::Left(v) => SpecInstrFmt::Base(v),
1394// // Either::Right(v) => SpecInstrFmt::Block(v),
1395// // }
1396// // }
1397// // }
1398// //
1399// // impl SpecFrom<SpecInstrFmt> for SpecInstrFmtAlias {
1400// // closed spec fn spec_from(v: SpecInstrFmt) -> Self {
1401// // match v {
1402// // SpecInstrFmt::Base(v) => Either::Left(v),
1403// // SpecInstrFmt::Block(v) => Either::Right(v),
1404// // }
1405// // }
1406// // }
1407// //
1408// // impl SpecFrom<SpecAuxBlockFmtAlias> for SpecAuxBlockFmt {
1409// // closed spec fn spec_from(v: SpecAuxBlockFmtAlias) -> Self {
1410// // let (begin, (instrs, end)) = v;
1411// // SpecAuxBlockFmt { begin, instrs, end }
1412// // }
1413// // }
1414// //
1415// // impl SpecFrom<SpecAuxBlockFmt> for SpecAuxBlockFmtAlias {
1416// // closed spec fn spec_from(v: SpecAuxBlockFmt) -> Self {
1417// // (v.begin, (v.instrs, v.end))
1418// // }
1419// // }
1420// //
1421// // impl From<InstrFmtAlias> for InstrFmt {
1422// // fn ex_from(v: InstrFmtAlias) -> Self {
1423// // match v {
1424// // Either::Left(v) => InstrFmt::Base(v),
1425// // Either::Right(v) => InstrFmt::Block(v),
1426// // }
1427// // }
1428// // }
1429// //
1430// // impl From<InstrFmt> for InstrFmtAlias {
1431// // fn ex_from(v: InstrFmt) -> Self {
1432// // match v {
1433// // InstrFmt::Base(v) => Either::Left(v),
1434// // InstrFmt::Block(v) => Either::Right(v),
1435// // }
1436// // }
1437// // }
1438// //
1439// // impl From<AuxBlockFmtAlias> for AuxBlockFmt {
1440// // fn ex_from(v: AuxBlockFmtAlias) -> Self {
1441// // let (begin, (instrs, end)) = v;
1442// // AuxBlockFmt { begin, instrs, end }
1443// // }
1444// // }
1445// //
1446// // impl From<AuxBlockFmt> for AuxBlockFmtAlias {
1447// // fn ex_from(v: AuxBlockFmt) -> Self {
1448// // (v.begin, (v.instrs, v.end))
1449// // }
1450// // }
1451// //
1452// // struct InstrIso;
1453// //
1454// // impl View for InstrIso {
1455// // type V = Self;
1456// //
1457// // closed spec fn view(&self) -> Self::V {
1458// // InstrIso
1459// // }
1460// // }
1461// //
1462// // impl SpecIso for InstrIso {
1463// // type Src = SpecInstrFmtAlias;
1464// //
1465// // type Dst = SpecInstrFmt;
1466// //
1467// // proof fn spec_iso(s: Self::Src) {
1468// // }
1469// //
1470// // proof fn spec_iso_rev(s: Self::Dst) {
1471// // }
1472// // }
1473// //
1474// // impl Iso for InstrIso {
1475// // type Src = InstrFmtAlias;
1476// //
1477// // type Dst = InstrFmt;
1478// // }
1479// //
1480// // struct AuxBlockIso;
1481// //
1482// // impl View for AuxBlockIso {
1483// // type V = Self;
1484// //
1485// // closed spec fn view(&self) -> Self::V {
1486// // AuxBlockIso
1487// // }
1488// // }
1489// //
1490// // impl SpecIso for AuxBlockIso {
1491// // type Src = SpecAuxBlockFmtAlias;
1492// //
1493// // type Dst = SpecAuxBlockFmt;
1494// //
1495// // proof fn spec_iso(s: Self::Src) {
1496// // }
1497// //
1498// // proof fn spec_iso_rev(s: Self::Dst) {
1499// // }
1500// // }
1501// //
1502// // impl Iso for AuxBlockIso {
1503// // type Src = AuxBlockFmtAlias;
1504// //
1505// // type Dst = AuxBlockFmt;
1506// // }
1507// //
1508// // struct InstrCom(pub Mapped<OrdChoice<Refined<U8, TagPred<u8>>, LazyAuxBlockCom>, InstrIso>);
1509// //
1510// // struct AuxBlockCom(
1511// // pub Mapped<
1512// // (Refined<U8, TagPred<u8>>, (Star<LazyInstrCom>, Refined<U8, TagPred<u8>>)),
1513// // AuxBlockIso,
1514// // >,
1515// // );
1516// //
1517// // struct SpecInstrCom(pub SpecInstrComInner);
1518// //
1519// // struct SpecAuxBlockCom(pub SpecAuxBlockComInner);
1520// //
1521// // type SpecInstrComInner = Mapped<
1522// // OrdChoice<Refined<U8, TagPred<u8>>, LazyAuxBlockCom>,
1523// // InstrIso,
1524// // >;
1525// //
1526// // type SpecAuxBlockComInner = Mapped<
1527// // (Refined<U8, TagPred<u8>>, (Star<LazyInstrCom>, Refined<U8, TagPred<u8>>)),
1528// // AuxBlockIso,
1529// // >;
1530// //
1531// // impl View for InstrCom {
1532// // type V = SpecInstrCom;
1533// //
1534// // closed spec fn view(&self) -> Self::V {
1535// // SpecInstrCom(self.0@)
1536// // }
1537// // }
1538// //
1539// // impl View for AuxBlockCom {
1540// // type V = SpecAuxBlockCom;
1541// //
1542// // closed spec fn view(&self) -> Self::V {
1543// // SpecAuxBlockCom(self.0@)
1544// // }
1545// // }
1546// //
1547// // impl SpecCombinator for SpecInstrCom {
1548// // type Type = SpecInstrFmt;
1549// //
1550// // closed spec fn spec_parse(&self, s: Seq<u8>) -> Result<(usize, Self::Type), ()> {
1551// // self.0.spec_parse(s)
1552// // }
1553// //
1554// // closed spec fn spec_serialize(&self, v: Self::Type) -> Result<Seq<u8>, ()> {
1555// // self.0.spec_serialize(v)
1556// // }
1557// // }
1558// //
1559// // impl SecureSpecCombinator for SpecInstrCom {
1560// // open spec fn is_prefix_secure() -> bool {
1561// // SpecInstrComInner::is_prefix_secure()
1562// // }
1563// //
1564// // open spec fn is_productive(&self) -> bool {
1565// // self.0.is_productive()
1566// // }
1567// //
1568// // proof fn theorem_serialize_parse_roundtrip(&self, v: Self::Type) {
1569// // // self.0.theorem_serialize_parse_roundtrip(v.0)
1570// // self.0.theorem_serialize_parse_roundtrip(v)
1571// // }
1572// //
1573// // proof fn theorem_parse_serialize_roundtrip(&self, buf: Seq<u8>) {
1574// // self.0.theorem_parse_serialize_roundtrip(buf)
1575// // }
1576// //
1577// // proof fn lemma_prefix_secure(&self, s1: Seq<u8>, s2: Seq<u8>) {
1578// // self.0.lemma_prefix_secure(s1, s2)
1579// // }
1580// //
1581// // proof fn lemma_parse_length(&self, s: Seq<u8>) {
1582// // self.0.lemma_parse_length(s)
1583// // }
1584// //
1585// // proof fn lemma_parse_productive(&self, s: Seq<u8>) {
1586// // self.0.lemma_parse_productive(s)
1587// // }
1588// // }
1589// //
1590// // impl SpecCombinator for SpecAuxBlockCom {
1591// // type Type = SpecAuxBlockFmt;
1592// //
1593// // closed spec fn spec_parse(&self, s: Seq<u8>) -> Result<(usize, Self::Type), ()> {
1594// // self.0.spec_parse(s)
1595// // }
1596// //
1597// // closed spec fn spec_serialize(&self, v: Self::Type) -> Result<Seq<u8>, ()> {
1598// // self.0.spec_serialize(v)
1599// // }
1600// // }
1601// //
1602// // impl SecureSpecCombinator for SpecAuxBlockCom {
1603// // open spec fn is_prefix_secure() -> bool {
1604// // SpecAuxBlockComInner::is_prefix_secure()
1605// // }
1606// //
1607// // open spec fn is_productive(&self) -> bool {
1608// // self.0.is_productive()
1609// // }
1610// //
1611// // proof fn theorem_serialize_parse_roundtrip(&self, v: Self::Type) {
1612// // self.0.theorem_serialize_parse_roundtrip(v)
1613// //
1614// // }
1615// //
1616// // proof fn theorem_parse_serialize_roundtrip(&self, buf: Seq<u8>) {
1617// // self.0.theorem_parse_serialize_roundtrip(buf)
1618// // }
1619// //
1620// // proof fn lemma_prefix_secure(&self, s1: Seq<u8>, s2: Seq<u8>) {
1621// // self.0.lemma_prefix_secure(s1, s2)
1622// // }
1623// //
1624// // proof fn lemma_parse_length(&self, s: Seq<u8>) {
1625// // self.0.lemma_parse_length(s)
1626// // }
1627// //
1628// // proof fn lemma_parse_productive(&self, s: Seq<u8>) {
1629// // self.0.lemma_parse_productive(s)
1630// // }
1631// // }
1632// //
1633// // // impl DisjointFrom<Refined<U8, TagPred<u8>>> for SpecAuxBlockCont {
1634// // // closed spec fn disjoint_from(&self, other: &Refined<U8, TagPred<u8>>) -> bool {
1635// // // (self.0)().0.inner.0.disjoint_from(other)
1636// // // }
1637// // //
1638// // // proof fn parse_disjoint_on(&self, other: &Refined<U8, TagPred<u8>>, buf: Seq<u8>) {
1639// // // (self.0)().0.inner.0.parse_disjoint_on(other, buf)
1640// // // }
1641// // // }
1642// //
1643// // // impl DisjointFrom<Refined<U8, TagPred<u8>>> for SpecInstrCom {}
1644// // impl<'a> Combinator<&'a [u8], Vec<u8>> for InstrCom {
1645// // type Type = InstrFmt;
1646// //
1647// // open spec fn spec_length(&self) -> Option<usize> {
1648// // None
1649// // }
1650// //
1651// // fn length(&self) -> Option<usize> {
1652// // None
1653// // }
1654// //
1655// // fn parse(&self, s: &'a [u8]) -> Result<(usize, Self::Type), ParseError> {
1656// // <_ as Combinator<&[u8], Vec<u8>>>::parse(
1657// // &self.0,
1658// // s,
1659// // )
1660// // }
1661// //
1662// // fn serialize(&self, v: Self::Type, data: &mut Vec<u8>, pos: usize) -> Result<
1663// // usize,
1664// // SerializeError,
1665// // > {
1666// // <_ as Combinator<&[u8], Vec<u8>>>::serialize(&self.0, v, data, pos)
1667// // }
1668// // }
1669// //
1670// // impl<'a> Combinator<&'a [u8], Vec<u8>> for AuxBlockCom {
1671// // type Type = AuxBlockFmt;
1672// //
1673// // open spec fn spec_length(&self) -> Option<usize> {
1674// // None
1675// // }
1676// //
1677// // fn length(&self) -> Option<usize> {
1678// // None
1679// // }
1680// //
1681// // fn parse(&self, s: &'a [u8]) -> Result<(usize, Self::Type), ParseError> {
1682// // <_ as Combinator<&[u8], Vec<u8>>>::parse(
1683// // &self.0,
1684// // s,
1685// // )
1686// // }
1687// //
1688// // fn serialize(&self, v: Self::Type, data: &mut Vec<u8>, pos: usize) -> Result<
1689// // usize,
1690// // SerializeError,
1691// // > {
1692// // <_ as Combinator<&[u8], Vec<u8>>>::serialize(&self.0, v, data, pos)
1693// // }
1694// // }
1695// //
1696// // } // verus!