1use super::DerOrd;
6use crate::combinators::{star::spec::*, Star};
7use crate::core::exec::output::*;
8use crate::core::{
9 exec::{
10 input::InputBuf,
11 parser::{PResult, Parser},
12 serializer::{ByteLen, PreSerializeError, Prepare, Serializer},
13 ParseError,
14 },
15 proof::*,
16 spec::*,
17};
18#[cfg(feature = "alloc")]
19use alloc::vec::Vec;
20use vstd::{prelude::*, relations::*};
21use OutputBuf;
22
23verus! {
24
25#[derive(Copy)]
30pub struct SetOfFmt<C>(pub C);
31
32impl<C: Clone> Clone for SetOfFmt<C> {
33 fn clone(&self) -> (cloned: Self)
34 ensures
35 call_ensures(C::clone, (&self.0,), cloned.0),
36 {
37 SetOfFmt(self.0.clone())
38 }
39}
40
41pub open spec fn der_octet_at(bytes: Seq<u8>, i: nat) -> u8 {
44 if i < bytes.len() {
45 bytes[i as int]
46 } else {
47 0u8
48 }
49}
50
51pub open spec fn der_octets_drop_head(bytes: Seq<u8>) -> Seq<u8> {
52 if bytes.len() == 0 {
53 bytes
54 } else {
55 bytes.skip(1)
56 }
57}
58
59pub open spec fn der_octets_leq(a: Seq<u8>, b: Seq<u8>) -> bool
62 decreases a.len() + b.len(),
63{
64 if a.len() == 0 && b.len() == 0 {
65 true
66 } else {
67 let left = der_octet_at(a, 0);
68 let right = der_octet_at(b, 0);
69 ||| left < right
70 ||| (left == right && der_octets_leq(der_octets_drop_head(a), der_octets_drop_head(b)))
71 }
72}
73
74pub open spec fn der_encodings_sorted(encodings: Seq<Seq<u8>>) -> bool {
75 sorted_by(encodings, |a: Seq<u8>, b: Seq<u8>| der_octets_leq(a, b))
76}
77
78pub open spec fn set_of_values_sorted<C: SpecSerializer>(inner: C, values: Seq<C::SVal>) -> bool {
80 der_encodings_sorted(values.map_values(|v: C::SVal| inner.spec_serialize(v)))
81}
82
83pub proof fn lemma_der_octets_leq_step(a: Seq<u8>, b: Seq<u8>)
85 requires
86 a.len() > 0 || b.len() > 0,
87 ensures
88 der_octet_at(a, 0) < der_octet_at(b, 0) ==> der_octets_leq(a, b),
89 der_octet_at(a, 0) > der_octet_at(b, 0) ==> !der_octets_leq(a, b),
90 der_octet_at(a, 0) == der_octet_at(b, 0) ==> {
91 der_octets_leq(a, b) == der_octets_leq(der_octets_drop_head(a), der_octets_drop_head(b))
92 },
93{
94}
95
96pub proof fn lemma_der_octets_leq_transitive(a: Seq<u8>, b: Seq<u8>, c: Seq<u8>)
98 requires
99 der_octets_leq(a, b),
100 der_octets_leq(b, c),
101 ensures
102 der_octets_leq(a, c),
103 decreases a.len() + b.len() + c.len(),
104{
105 if a.len() > 0 || b.len() > 0 || c.len() > 0 {
106 if a.len() > 0 || b.len() > 0 {
107 lemma_der_octets_leq_step(a, b);
108 }
109 if b.len() > 0 || c.len() > 0 {
110 lemma_der_octets_leq_step(b, c);
111 }
112 if a.len() > 0 || c.len() > 0 {
113 lemma_der_octets_leq_step(a, c);
114 }
115 let ai = der_octet_at(a, 0);
116 let bi = der_octet_at(b, 0);
117 let ci = der_octet_at(c, 0);
118 if ai == bi && bi == ci {
119 lemma_der_octets_leq_transitive(
120 der_octets_drop_head(a),
121 der_octets_drop_head(b),
122 der_octets_drop_head(c),
123 );
124 }
125 }
126}
127
128proof fn lemma_sorted_by_index<T>(values: Seq<T>, leq: spec_fn(T, T) -> bool, i: int, j: int)
129 requires
130 sorted_by(values, leq),
131 0 <= i < j < values.len(),
132 ensures
133 leq(values[i], values[j]),
134{
135}
136
137pub proof fn lemma_der_encodings_sorted_index(encodings: Seq<Seq<u8>>, i: int, j: int)
138 requires
139 der_encodings_sorted(encodings),
140 0 <= i < j < encodings.len(),
141 ensures
142 der_octets_leq(encodings[i], encodings[j]),
143{
144 lemma_sorted_by_index(encodings, |a: Seq<u8>, b: Seq<u8>| der_octets_leq(a, b), i, j);
145}
146
147pub proof fn lemma_der_encodings_sorted_take(encodings: Seq<Seq<u8>>, n: int)
148 requires
149 der_encodings_sorted(encodings),
150 0 <= n <= encodings.len(),
151 ensures
152 der_encodings_sorted(encodings.take(n)),
153{
154 assert forall|i: int, j: int|
155 0 <= i < j < encodings.take(n).len() implies #[trigger] der_octets_leq(
156 encodings.take(n)[i],
157 encodings.take(n)[j],
158 ) by {
159 lemma_der_encodings_sorted_index(encodings, i, j);
160 }
161}
162
163pub proof fn lemma_der_encodings_sorted_push(encodings: Seq<Seq<u8>>, current: Seq<u8>)
167 requires
168 der_encodings_sorted(encodings),
169 ensures
170 der_encodings_sorted(encodings.push(current)) <==> (encodings.len() == 0 || der_octets_leq(
171 encodings.last(),
172 current,
173 )),
174{
175 let extended = encodings.push(current);
176 if encodings.len() > 0 {
177 if der_octets_leq(encodings.last(), current) {
178 assert forall|i: int, j: int|
179 0 <= i < j < extended.len() implies #[trigger] der_octets_leq(
180 extended[i],
181 extended[j],
182 ) by {
183 if j < encodings.len() {
184 lemma_der_encodings_sorted_index(encodings, i, j);
185 } else if i < encodings.len() - 1 {
186 lemma_der_encodings_sorted_index(encodings, i, encodings.len() as int - 1);
187 lemma_der_octets_leq_transitive(encodings[i], encodings.last(), current);
188 }
189 }
190 } else {
191 assert(!der_encodings_sorted(extended)) by {
192 if der_encodings_sorted(extended) {
193 lemma_der_encodings_sorted_index(
194 extended,
195 encodings.len() as int - 1,
196 encodings.len() as int,
197 );
198 }
199 }
200 }
201 }
202}
203
204impl<C: SpecParser> SetOfFmt<C> {
205 pub open spec fn parse_ordered(&self, ibuf: Seq<u8>, previous: Seq<Seq<u8>>) -> Option<
207 Seq<C::PVal>,
208 >
209 decreases ibuf.len(),
210 {
211 if !der_encodings_sorted(previous) {
212 None
213 } else if ibuf.len() == 0 {
214 Some(Seq::empty())
215 } else {
216 match self.0.spec_parse(ibuf) {
217 Some((n, v)) if 0 < n <= ibuf.len() && der_encodings_sorted(
218 previous.push(ibuf.take(n)),
219 ) => {
220 match self.parse_ordered(ibuf.skip(n), previous.push(ibuf.take(n))) {
221 Some(values) => Some(seq![v] + values),
222 None => None,
223 }
224 },
225 _ => None,
226 }
227 }
228 }
229}
230
231impl<C: SoundParser> SetOfFmt<C> {
232 proof fn lemma_parse_ordered_byte_len(&self, ibuf: Seq<u8>, previous: Seq<Seq<u8>>)
233 requires
234 self.0.sound_inv(),
235 der_encodings_sorted(previous),
236 ensures
237 self.parse_ordered(ibuf, previous) matches Some(values) ==> {
238 ibuf.len() == Star(self.0).byte_len(values)
239 },
240 decreases ibuf.len(),
241 {
242 reveal(<Star<_> as SpecByteLen>::byte_len);
243
244 if ibuf.len() > 0 {
245 match self.0.spec_parse(ibuf) {
246 Some((n, value)) if 0 < n <= ibuf.len() && der_encodings_sorted(
247 previous.push(ibuf.take(n)),
248 ) => {
249 self.0.lemma_parse_sound_consumption(ibuf);
250 self.lemma_parse_ordered_byte_len(ibuf.skip(n), previous.push(ibuf.take(n)));
251
252 if let Some(rest_values) = self.parse_ordered(
253 ibuf.skip(n),
254 previous.push(ibuf.take(n)),
255 ) {
256 Star(self.0).lemma_byte_len_cons(value, rest_values);
257 }
258 },
259 _ => {},
260 }
261 }
262 }
263}
264
265impl<C: SoundParser + PSRoundTrip> SetOfFmt<C> {
266 proof fn lemma_parse_ordered_consistent(&self, ibuf: Seq<u8>, previous: Seq<Seq<u8>>)
267 requires
268 self.0.sound_inv(),
269 self.0.ps_roundtrip_inv(),
270 der_encodings_sorted(previous),
271 ensures
272 self.parse_ordered(ibuf, previous) matches Some(values) ==> {
273 &&& Star(self.0).consistent(values)
274 &&& der_encodings_sorted(
275 previous + values.map_values(|v: C::PVal| self.0.spec_serialize(v)),
276 )
277 },
278 decreases ibuf.len(),
279 {
280 reveal(<Star<_> as Consistency>::consistent);
281 broadcast use vstd::seq::group_seq_axioms;
282
283 if ibuf.len() > 0 {
284 match self.0.spec_parse(ibuf) {
285 Some((n, value)) if 0 < n <= ibuf.len() && der_encodings_sorted(
286 previous.push(ibuf.take(n)),
287 ) => {
288 self.0.lemma_parse_sound_value(ibuf);
289 self.0.theorem_parse_serialize_roundtrip(ibuf);
290 self.lemma_parse_ordered_consistent(ibuf.skip(n), previous.push(ibuf.take(n)));
291
292 if let Some(rest_values) = self.parse_ordered(
293 ibuf.skip(n),
294 previous.push(ibuf.take(n)),
295 ) {
296 let values = seq![value] + rest_values;
297 let serialize = |v: C::PVal| self.0.spec_serialize(v);
298 assert(values.map_values(serialize) == seq![ibuf.take(n)]
299 + rest_values.map_values(serialize));
300 assert(previous + values.map_values(serialize) == previous.push(
301 ibuf.take(n),
302 ) + rest_values.map_values(serialize));
303 }
304 },
305 _ => {},
306 }
307 }
308 }
309}
310
311impl<C: NonMalleable> SetOfFmt<C> {
312 proof fn lemma_parse_ordered_non_malleable(
313 &self,
314 buf1: Seq<u8>,
315 previous1: Seq<Seq<u8>>,
316 buf2: Seq<u8>,
317 previous2: Seq<Seq<u8>>,
318 )
319 requires
320 self.0.nonmal_inv(),
321 self.0.safe_inv(),
322 der_encodings_sorted(previous1),
323 der_encodings_sorted(previous2),
324 ensures
325 self.parse_ordered(buf1, previous1) matches Some(values1) ==> self.parse_ordered(
326 buf2,
327 previous2,
328 ) matches Some(values2) ==> values1 == values2 ==> buf1 == buf2,
329 decreases buf1.len(),
330 {
331 broadcast use vstd::seq_lib::group_seq_properties;
332
333 if let Some(values1) = self.parse_ordered(buf1, previous1) {
334 if let Some(values2) = self.parse_ordered(buf2, previous2) {
335 if values1 == values2 && values1.len() > 0 {
336 let (n1, value1) = self.0.spec_parse(buf1)->0;
337 let (n2, value2) = self.0.spec_parse(buf2)->0;
338 let rest1 = self.parse_ordered(buf1.skip(n1), previous1.push(buf1.take(n1)))->0;
339 let rest2 = self.parse_ordered(buf2.skip(n2), previous2.push(buf2.take(n2)))->0;
340
341 assert(value1 == value2) by {
342 assert(value1 == values1[0]);
343 assert(value2 == values2[0]);
344 }
345 assert(rest1 == rest2) by {
346 assert(rest1 == values1.skip(1));
347 assert(rest2 == values2.skip(1));
348 }
349
350 self.0.lemma_parse_non_malleable(buf1, buf2);
351 self.lemma_parse_ordered_non_malleable(
352 buf1.skip(n1),
353 previous1.push(buf1.take(n1)),
354 buf2.skip(n2),
355 previous2.push(buf2.take(n2)),
356 );
357 assert(buf1 == buf1.take(n1) + buf1.skip(n1));
358 assert(buf2 == buf2.take(n2) + buf2.skip(n2));
359 }
360 }
361 }
362 }
363}
364
365impl<C> SetOfFmt<C> where
366 C: SPRoundTripDps + NonTailFmt + EquivSerializersGeneral + Productive,
367 C: SpecSerializer<SVal = C::T>,
368 {
369 proof fn lemma_serialize_parse_ordered(&self, values: Seq<C::T>, previous: Seq<Seq<u8>>)
370 requires
371 self.0.unambiguous(),
372 self.0.serialize_dps_inv(),
373 self.0.equiv_general_inv(),
374 self.0.safe_inv(),
375 self.0.productive_inv(),
376 Star(self.0).consistent(values),
377 der_encodings_sorted(previous + values.map_values(|v: C::T| self.0.spec_serialize(v))),
378 ensures
379 self.parse_ordered(Star(self.0).spec_serialize_dps(values, Seq::empty()), previous)
380 == Some(values),
381 decreases values.len(),
382 {
383 reveal(<Star<_> as Consistency>::consistent);
384 reveal(<Star<_> as SpecSerializerDps>::spec_serialize_dps);
385 broadcast use vstd::seq::group_seq_axioms;
386
387 let encodings = values.map_values(|v: C::T| self.0.spec_serialize(v));
388 lemma_der_encodings_sorted_take(previous + encodings, previous.len() as int);
389 assert((previous + encodings).take(previous.len() as int) == previous);
390 assert(der_encodings_sorted(previous));
391 if values.len() > 0 {
392 let value = values[0];
393 let rest = values.skip(1);
394 let rest_buf = Star(self.0).spec_serialize_dps(rest, Seq::empty());
395 let serialized = Star(self.0).spec_serialize_dps(values, Seq::empty());
396 let n = self.0.byte_len(value) as int;
397
398 assert(values == seq![value] + rest);
399 assert(encodings == seq![self.0.spec_serialize(value)] + rest.map_values(
400 |v: C::T| self.0.spec_serialize(v),
401 ));
402 assert(serialized == self.0.spec_serialize_dps(value, rest_buf));
403 self.0.theorem_serialize_dps_parse_roundtrip(value, rest_buf);
404 self.0.lemma_serialize_dps_prepend(value, rest_buf);
405 self.0.lemma_serialize_dps_len(value, rest_buf);
406 self.0.lemma_serialize_equiv(value, rest_buf);
407 self.0.lemma_productive(serialized);
408 assert(serialized.take(n) == self.0.spec_serialize(value));
409 assert(serialized.skip(n) == rest_buf);
410
411 lemma_der_encodings_sorted_take(previous + encodings, previous.len() as int + 1);
412 assert((previous + encodings).take(previous.len() as int + 1) == previous.push(
413 self.0.spec_serialize(value),
414 ));
415 assert(previous.push(self.0.spec_serialize(value)) + rest.map_values(
416 |v: C::T| self.0.spec_serialize(v),
417 ) == previous + encodings);
418
419 self.lemma_serialize_parse_ordered(rest, previous.push(self.0.spec_serialize(value)));
420 }
421 }
422}
423
424mod derived_specs {
425 use super::*;
426
427 impl<C: SpecParser> SpecParser for SetOfFmt<C> {
428 type PVal = Seq<C::PVal>;
429
430 open spec fn spec_parse(&self, ibuf: Seq<u8>) -> Option<(int, Self::PVal)> {
431 match self.parse_ordered(ibuf, Seq::empty()) {
432 Some(values) => Some((ibuf.len() as int, values)),
433 _ => None,
434 }
435 }
436 }
437
438 impl<C> Consistency for SetOfFmt<C> where C: Consistency + SpecSerializer<SVal = C::Val> {
439 type Val = Seq<C::Val>;
440
441 open spec fn consistent(&self, values: Self::Val) -> bool {
442 &&& Star(self.0).consistent(values)
443 &&& set_of_values_sorted(self.0, values)
444 }
445 }
446
447 impl<C: SpecSerializerDps> SpecSerializerDps for SetOfFmt<C> {
448 type SValue = Seq<C::SValue>;
449
450 open spec fn spec_serialize_dps(&self, v: Self::SValue, _obuf: Seq<u8>) -> Seq<u8> {
451 Star(self.0).spec_serialize_dps(v, Seq::empty())
452 }
453 }
454
455 impl<C: SpecSerializer> SpecSerializer for SetOfFmt<C> {
456 type SVal = Seq<C::SVal>;
457
458 open spec fn spec_serialize(&self, v: Self::SVal) -> Seq<u8> {
459 Star(self.0).spec_serialize(v)
460 }
461 }
462
463 impl<C: SpecByteLen> SpecByteLen for SetOfFmt<C> {
464 type T = Seq<C::T>;
465
466 open spec fn byte_len(&self, v: Self::T) -> nat {
467 Star(self.0).byte_len(v)
468 }
469 }
470
471}
472
473mod derived_proofs {
474 use super::*;
475
476 impl<C: SafeParser> SafeParser for SetOfFmt<C> {
477 open spec fn safe_inv(&self) -> bool {
478 self.0.safe_inv()
479 }
480
481 proof fn lemma_parse_safe(&self, ibuf: Seq<u8>) {
482 reveal(<SetOfFmt<_> as SpecParser>::spec_parse);
483 }
484 }
485
486 impl<C: SoundParser + PSRoundTrip> SoundParser for SetOfFmt<C> {
487 open spec fn sound_inv(&self) -> bool {
488 self.0.sound_inv() && self.0.ps_roundtrip_inv()
489 }
490
491 proof fn lemma_parse_sound_consumption(&self, ibuf: Seq<u8>) {
492 reveal(<SetOfFmt<_> as SpecParser>::spec_parse);
493 reveal(<SetOfFmt<_> as SpecByteLen>::byte_len);
494 self.lemma_parse_ordered_byte_len(ibuf, Seq::empty());
495 }
496
497 proof fn lemma_parse_sound_value(&self, ibuf: Seq<u8>) {
498 reveal(<SetOfFmt<_> as SpecParser>::spec_parse);
499 reveal(<SetOfFmt<_> as Consistency>::consistent);
500 self.lemma_parse_ordered_consistent(ibuf, Seq::empty());
501 }
502 }
503
504 impl<C: NonMalleable> NonMalleable for SetOfFmt<C> {
505 open spec fn nonmal_inv(&self) -> bool {
506 self.0.nonmal_inv() && self.0.safe_inv()
507 }
508
509 proof fn lemma_parse_non_malleable(&self, buf1: Seq<u8>, buf2: Seq<u8>) {
510 reveal(<SetOfFmt<_> as SpecParser>::spec_parse);
511 self.lemma_parse_ordered_non_malleable(buf1, Seq::empty(), buf2, Seq::empty());
512 }
513 }
514
515 impl<C: SafeParser> Productive for SetOfFmt<C> {
516 open spec fn productive_inv(&self) -> bool {
517 false
518 }
519
520 proof fn lemma_productive(&self, _ibuf: Seq<u8>) {
521 }
522 }
523
524 impl<C: GoodSerializer> GoodSerializer for SetOfFmt<C> {
525 open spec fn serialize_inv(&self) -> bool {
526 self.0.serialize_inv()
527 }
528
529 proof fn lemma_serialize_len(&self, values: Self::SVal) {
530 reveal(<SetOfFmt<_> as SpecSerializer>::spec_serialize);
531 reveal(<SetOfFmt<_> as SpecByteLen>::byte_len);
532 reveal(<Star<_> as SpecSerializer>::spec_serialize);
533 reveal(<Star<_> as SpecByteLen>::byte_len);
534 Star(self.0).lemma_serialize_len(values);
535 }
536 }
537
538 impl<C: EquivSerializersGeneral> EquivSerializers for SetOfFmt<C> {
539 open spec fn equiv_inv(&self) -> bool {
540 self.0.equiv_general_inv()
541 }
542
543 proof fn lemma_serialize_equiv_on_empty(&self, values: Self::SVal) {
544 reveal(<SetOfFmt<_> as SpecSerializerDps>::spec_serialize_dps);
545 reveal(<SetOfFmt<_> as SpecSerializer>::spec_serialize);
546 reveal(<Star<_> as SpecSerializer>::spec_serialize);
547 Star(self.0).lemma_serialize_equiv_on_empty(values);
548 }
549 }
550
551 impl<C> SPRoundTripDps for SetOfFmt<C> where
552 C: SPRoundTripDps + NonTailFmt + EquivSerializersGeneral + Productive,
553 C: SpecSerializer<SVal = C::T>,
554 {
555 open spec fn unambiguous(&self) -> bool {
556 &&& self.0.unambiguous()
557 &&& self.0.serialize_dps_inv()
558 &&& self.0.equiv_general_inv()
559 &&& self.0.safe_inv()
560 &&& self.0.productive_inv()
561 }
562
563 proof fn theorem_serialize_dps_parse_roundtrip(&self, values: Self::T, _obuf: Seq<u8>) {
564 reveal(<SetOfFmt<_> as Consistency>::consistent);
565 reveal(<SetOfFmt<_> as SpecSerializerDps>::spec_serialize_dps);
566 reveal(<SetOfFmt<_> as SpecParser>::spec_parse);
567 reveal(<SetOfFmt<_> as SpecByteLen>::byte_len);
568
569 let star = Star(self.0);
570 self.lemma_serialize_parse_ordered(values, Seq::empty());
571 star.lemma_serialize_dps_len(values, Seq::empty());
572 assert(star.spec_serialize_dps(values, Seq::empty()).len() == star.byte_len(values));
573 }
574 }
575
576}
577
578pub fn der_leq(a: &[u8], b: &[u8]) -> (leq: bool)
580 ensures
581 leq == der_octets_leq(a.deep_view(), b.deep_view()),
582{
583 let mut left = 0usize;
584 let mut right = 0usize;
585 assert(a.deep_view().skip(0) == a.deep_view());
586 assert(b.deep_view().skip(0) == b.deep_view());
587 while left < a.len() || right < b.len()
588 invariant
589 left <= a.len(),
590 right <= b.len(),
591 der_octets_leq(a.deep_view(), b.deep_view()) == der_octets_leq(
592 a.deep_view().skip(left as int),
593 b.deep_view().skip(right as int),
594 ),
595 decreases a.len() - left + b.len() - right,
596 {
597 let ghost old_left = a.deep_view().skip(left as int);
598 let ghost old_right = b.deep_view().skip(right as int);
599 proof {
600 lemma_der_octets_leq_step(old_left, old_right);
601 }
602 let ai = if left < a.len() {
603 a[left]
604 } else {
605 0u8
606 };
607 let bi = if right < b.len() {
608 b[right]
609 } else {
610 0u8
611 };
612 if ai < bi {
613 return true;
614 }
615 if ai > bi {
616 return false;
617 }
618 if left < a.len() {
619 left += 1;
620 }
621 if right < b.len() {
622 right += 1;
623 }
624 assert(der_octets_drop_head(old_left) == a.deep_view().skip(left as int));
625 assert(der_octets_drop_head(old_right) == b.deep_view().skip(right as int));
626 }
627 true
628}
629
630#[cfg(feature = "alloc")]
631impl<'i, C> Parser<&'i [u8]> for SetOfFmt<C> where
632 C: Parser<&'i [u8]> + SafeParser + Productive + Copy,
633 {
634 type PT = Vec<C::PT>;
635
636 open spec fn exec_inv(&self) -> bool {
637 &&& self.0.exec_inv()
638 &&& self.0.safe_inv()
639 &&& self.0.productive_inv()
640 }
641
642 fn parse(&self, ibuf: &&'i [u8]) -> (r: PResult<Self::PT>) {
643 reveal(<SetOfFmt<_> as SpecParser>::spec_parse);
644 broadcast use vstd::seq::group_seq_axioms;
645
646 let _len = ibuf.len();
647 let mut consumed = 0usize;
648 let mut rest = *ibuf;
649 let mut values = Vec::new();
650 let mut encodings = Vec::new();
651
652 assert(values.deep_view() == Seq::empty());
653 assert(encodings.deep_view() == Seq::empty());
654
655 while rest.len() > 0
656 invariant
657 self.exec_inv(),
658 consumed + rest@.len() == _len,
659 values.len() == encodings.len(),
660 der_encodings_sorted(encodings.deep_view()),
661 self.parse_ordered(rest@, encodings.deep_view()) matches Some(suffix)
662 ==> self.spec_parse(ibuf@) == Some((_len as int, values.deep_view() + suffix)),
663 self.parse_ordered(rest@, encodings.deep_view()) is None ==> self.spec_parse(
664 ibuf@,
665 ) is None,
666 decreases rest.len(),
667 {
668 broadcast use crate::core::spec::SafeParser::lemma_parse_safe;
669
670 let (n, value): (usize, C::PT) = self.0.parse(&rest)?;
671 proof {
672 self.0.lemma_productive(rest@);
673 }
674 let encoding = &rest[0..n];
675
676 proof {
677 assert(encoding.deep_view() == rest@.take(n as int));
678 lemma_der_encodings_sorted_push(encodings.deep_view(), encoding.deep_view());
679 }
680 if encodings.len() > 0 {
681 let previous = encodings[encodings.len() - 1];
682 if !der_leq(previous, encoding) {
683 return Err(ParseError::non_canonical());
684 }
685 }
686 let ghost old_rest = rest@;
687 let ghost old_encodings = encodings.deep_view();
688 values.push(value);
689 encodings.push(encoding);
690 rest = &rest[n..rest.len()];
691 consumed += n;
692
693 assert(encodings.deep_view() == old_encodings.push(old_rest.take(n as int)));
694 }
695
696 Ok((consumed, values))
697 }
698}
699
700impl<Output: OutputBuf, C, Elem> Serializer<Output, [Elem]> for SetOfFmt<C> where
701 Elem: DeepView,
702 C: SpecCombinator<T = <Elem as DeepView>::V> + Serializer<Output, Elem> + Copy,
703 {
704 #[verifier::prophetic]
705 open spec fn exec_inv(&self) -> bool {
706 self.0.exec_inv()
707 }
708
709 fn serialize_into(&self, v: &[Elem], obuf: &mut Output) {
710 Star(self.0).serialize_into(v, obuf)
711 }
712}
713
714impl<C, Elem> ByteLen<[Elem]> for SetOfFmt<C> where
715 C: SpecByteLen<T = <Elem as DeepView>::V> + ByteLen<Elem> + Copy,
716 Elem: DeepView,
717 {
718 open spec fn exec_inv(&self) -> bool {
719 self.0.exec_inv()
720 }
721
722 fn length(&self, v: &[Elem]) -> (len: usize) {
723 Star(self.0).length(v)
724 }
725}
726
727impl<C, Elem> Prepare<[Elem]> for SetOfFmt<C> where
728 Elem: DeepView,
729 C: SpecCombinator<T = <Elem as DeepView>::V> + Prepare<Elem> + DerOrd<Elem> + Copy,
730 {
731 open spec fn exec_inv(&self) -> bool {
732 self.0.exec_inv()
733 }
734
735 fn prepare(&self, values: &[Elem]) -> (checked: Result<usize, PreSerializeError>) {
736 reveal(<Star<_> as Consistency>::consistent);
737 let total = Star(self.0).prepare(values)?;
738
739 for i in 0..values.len()
740 invariant
741 <Self as Prepare<[Elem]>>::exec_inv(self),
742 forall|k: int|
743 0 <= k < values.deep_view().len() ==> self.0.consistent(
744 #[trigger] values.deep_view()[k],
745 ),
746 total == Star(self.0).byte_len(values.deep_view()),
747 set_of_values_sorted(self.0, values.deep_view().take(i as int)),
748 {
749 if i > 0 {
750 assert(self.0.consistent(values.deep_view()[i as int - 1]));
751 assert(self.0.consistent(values.deep_view()[i as int]));
752 if !self.0.der_leq(&values[i - 1], &values[i]) {
753 return Err(
754 PreSerializeError::custom("SET OF elements are not in canonical DER order"),
755 );
756 }
757 }
758 proof {
759 let vs = values.deep_view();
760 let serialize = |v: C::T| self.0.spec_serialize(v);
761 let prefix_encodings = vs.take(i as int).map_values(serialize);
762 let current_encoding = serialize(vs[i as int]);
763 lemma_der_encodings_sorted_push(prefix_encodings, current_encoding);
764 vs.lemma_map_take_succ(serialize, i as int);
765 }
766 }
767 assert(values.deep_view().take(values.deep_view().len() as int) == values.deep_view());
768
769 Ok(total)
770 }
771}
772
773#[cfg(feature = "alloc")]
774impl<Output: OutputBuf, C, Elem> Serializer<Output, Vec<Elem>> for SetOfFmt<C> where
775 Elem: DeepView,
776 C: SpecCombinator<T = <Elem as DeepView>::V> + Serializer<Output, Elem> + Copy,
777 {
778 #[verifier::prophetic]
779 open spec fn exec_inv(&self) -> bool {
780 self.0.exec_inv()
781 }
782
783 fn serialize_into(&self, values: &Vec<Elem>, obuf: &mut Output) {
784 <Self as Serializer<Output, [Elem]>>::serialize_into(self, values.as_slice(), obuf)
785 }
786}
787
788#[cfg(feature = "alloc")]
789impl<C, Elem> ByteLen<Vec<Elem>> for SetOfFmt<C> where
790 C: SpecByteLen<T = <Elem as DeepView>::V> + ByteLen<Elem> + Copy,
791 Elem: DeepView,
792 {
793 open spec fn exec_inv(&self) -> bool {
794 self.0.exec_inv()
795 }
796
797 fn length(&self, values: &Vec<Elem>) -> (len: usize) {
798 <Self as ByteLen<[Elem]>>::length(self, values.as_slice())
799 }
800}
801
802#[cfg(feature = "alloc")]
803impl<C, Elem> Prepare<Vec<Elem>> for SetOfFmt<C> where
804 Elem: DeepView,
805 C: SpecCombinator<T = <Elem as DeepView>::V> + Prepare<Elem> + DerOrd<Elem> + Copy,
806 {
807 open spec fn exec_inv(&self) -> bool {
808 self.0.exec_inv()
809 }
810
811 fn prepare(&self, values: &Vec<Elem>) -> (checked: Result<usize, PreSerializeError>) {
812 <Self as Prepare<[Elem]>>::prepare(self, values.as_slice())
813 }
814}
815
816} #[cfg(all(test, feature = "alloc"))]
818mod tests {
819 use crate::asn1::der::{INTEGER8, SET_OF};
820 use crate::core::exec::{Parser, Prepare, SerializerExt};
821
822 #[test]
823 fn der_set_of_integer8_roundtrip_and_ordering() {
824 let format = SET_OF(INTEGER8);
825 let canonical = [0x31, 0x06, 0x02, 0x01, 0x01, 0x02, 0x01, 0x02];
826 let (consumed, values) = format.parse(&&canonical[..]).unwrap();
827 assert_eq!(consumed, canonical.len());
828 assert_eq!(values, vec![1, 2]);
829
830 assert_eq!(format.prepare(&values), Ok(canonical.len()));
831 let mut encoded = vec![0; format.prepare(&values).unwrap()];
832 format.serialize(&values, &mut encoded);
833 assert_eq!(encoded, canonical);
834
835 let unordered = [0x31, 0x06, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01];
836 assert!(format.parse(&&unordered[..]).is_err());
837 assert!(format.prepare(&vec![2, 1]).is_err());
838 }
839
840 #[test]
841 fn der_set_of_allows_duplicate_encodings() {
842 let format = SET_OF(INTEGER8);
843 let duplicate = [0x31, 0x06, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01];
844 let (_, values) = format.parse(&&duplicate[..]).unwrap();
845 assert_eq!(values, vec![1, 1]);
846 assert_eq!(format.prepare(&values), Ok(duplicate.len()));
847 }
848}