1use alloc::vec::Vec;
2
3use crate::properties::*;
4use core::mem::size_of;
5use vstd::prelude::*;
6use vstd::seq_lib::*;
7use vstd::slice::*;
8
9use super::bytes::Fixed;
10
11verus! {
12
13global size_of u8 == 1;
14
15global size_of u16 == 2;
16
17global size_of u32 == 4;
18
19global size_of u64 == 8;
20
21global size_of usize == 8;
22
23pub broadcast proof fn size_of_facts()
25 ensures
26 #[trigger] size_of::<u8>() == 1,
27 #[trigger] size_of::<u16>() == 2,
28 #[trigger] size_of::<u32>() == 4,
29 #[trigger] size_of::<u64>() == 8,
30 #[trigger] size_of::<usize>() == 8,
31{
32}
33
34pub struct U8;
36
37impl View for U8 {
38 type V = Self;
39
40 open spec fn view(&self) -> Self::V {
41 *self
42 }
43}
44
45pub struct U16Le;
47
48impl View for U16Le {
49 type V = Self;
50
51 open spec fn view(&self) -> Self::V {
52 *self
53 }
54}
55
56pub struct U32Le;
58
59impl View for U32Le {
60 type V = Self;
61
62 open spec fn view(&self) -> Self::V {
63 *self
64 }
65}
66
67pub struct U64Le;
69
70impl View for U64Le {
71 type V = Self;
72
73 open spec fn view(&self) -> Self::V {
74 *self
75 }
76}
77
78pub struct U16Be;
80
81impl View for U16Be {
82 type V = Self;
83
84 open spec fn view(&self) -> Self::V {
85 *self
86 }
87}
88
89pub struct U32Be;
91
92impl View for U32Be {
93 type V = Self;
94
95 open spec fn view(&self) -> Self::V {
96 *self
97 }
98}
99
100pub struct U64Be;
102
103impl View for U64Be {
104 type V = Self;
105
106 open spec fn view(&self) -> Self::V {
107 *self
108 }
109}
110
111macro_rules! impl_combinator_for_le_uint_type {
112 ($combinator:ty, $int_type:ty) => {
113 ::vstd::prelude::verus! {
114 impl SpecCombinator for $combinator {
115 type Type = $int_type;
116
117 open spec fn spec_parse(&self, s: Seq<u8>) -> Option<(int, $int_type)> {
118 if s.len() >= size_of::<$int_type>() {
119 Some((size_of::<$int_type>() as int, <$int_type>::spec_from_le_bytes(s)))
120 } else {
121 None
122 }
123 }
124
125 open spec fn spec_serialize(&self, v: $int_type) -> Seq<u8> {
126 <$int_type>::spec_to_le_bytes(&v)
127 }
128 }
129
130 impl SecureSpecCombinator for $combinator {
131 open spec fn is_prefix_secure() -> bool {
132 true
133 }
134
135 open spec fn is_productive(&self) -> bool {
136 true
137 }
138
139 proof fn theorem_serialize_parse_roundtrip(&self, v: $int_type) {
140 $int_type::lemma_spec_to_from_le_bytes(&v);
141 }
142
143 proof fn theorem_parse_serialize_roundtrip(&self, buf: Seq<u8>) {
144 let n = size_of::<$int_type>();
145 if buf.len() >= n {
146 let fst = buf.subrange(0, n as int);
147 let snd = buf.subrange(n as int, buf.len() as int);
148 $int_type::lemma_spec_from_to_le_bytes(fst);
149 self.lemma_prefix_secure(fst, snd);
150 assert(fst.add(snd) == buf);
151 }
152 }
153
154 proof fn lemma_prefix_secure(&self, s1: Seq<u8>, s2: Seq<u8>) {
155 $int_type::lemma_spec_from_le_bytes_no_lookahead(s1, s2);
156 }
157
158 proof fn lemma_parse_length(&self, s: Seq<u8>) {
159 }
160
161 proof fn lemma_parse_productive(&self, s: Seq<u8>) {
162 }
163 }
164
165 impl<'x, I: VestPublicInput, O: VestPublicOutput<I>> Combinator<'x, I, O> for $combinator {
166 type Type = $int_type;
167
168 type SType = &'x $int_type;
169
170 fn length(&self, _v: Self::SType) -> usize {
171 size_of::<$int_type>()
172 }
173
174 fn parse(&self, s: I) -> (res: Result<(usize, $int_type), ParseError>) {
175 if s.len() >= size_of::<$int_type>() {
176 let s_ = s.subrange(0, size_of::<$int_type>());
177 let v = $int_type::ex_from_le_bytes(s_.as_byte_slice());
178 proof {
179 let s_ = s_@;
180 let s__ = s@.subrange(size_of::<$int_type>() as int, s@.len() as int);
181 $int_type::lemma_spec_from_le_bytes_no_lookahead(s_, s__);
182 assert(s_.add(s__) == s@);
183 assert($int_type::spec_from_le_bytes(s@) == v);
184 v.reflex();
185 }
186 Ok((size_of::<$int_type>(), v))
187 } else {
188 Err(ParseError::UnexpectedEndOfInput)
189 }
190 }
191
192 fn serialize(&self, v: Self::SType, data: &mut O, pos: usize) -> (res: Result<usize, SerializeError>) {
193 if size_of::<$int_type>() <= data.len() - pos {
194 $int_type::ex_to_le_bytes(&v, data, pos);
195 proof {
196 v.reflex();
197 assert(data@.subrange(pos as int, pos + size_of::<$int_type>() as int)
198 == self.spec_serialize(v@));
199 }
200 Ok(size_of::<$int_type>())
201 } else {
202 Err(SerializeError::InsufficientBuffer)
203 }
204 }
205 }
206 } };
208}
209
210macro_rules! impl_combinator_for_be_uint_type {
211 ($combinator:ty, $int_type:ty) => {
212 ::vstd::prelude::verus! {
213 impl SpecCombinator for $combinator {
214 type Type = $int_type;
215
216 open spec fn spec_parse(&self, s: Seq<u8>) -> Option<(int, $int_type)> {
217 if s.len() >= size_of::<$int_type>() {
218 Some((size_of::<$int_type>() as int, <$int_type>::spec_from_be_bytes(s)))
219 } else {
220 None
221 }
222 }
223
224 open spec fn spec_serialize(&self, v: $int_type) -> Seq<u8> {
225 <$int_type>::spec_to_be_bytes(&v)
226 }
227 }
228
229 impl SecureSpecCombinator for $combinator {
230 open spec fn is_prefix_secure() -> bool {
231 true
232 }
233
234 open spec fn is_productive(&self) -> bool {
235 true
236 }
237
238 proof fn theorem_serialize_parse_roundtrip(&self, v: $int_type) {
239 $int_type::lemma_spec_to_from_be_bytes(&v);
240 }
241
242 proof fn theorem_parse_serialize_roundtrip(&self, buf: Seq<u8>) {
243 let n = size_of::<$int_type>();
244 if buf.len() >= n {
245 let fst = buf.subrange(0, n as int);
246 let snd = buf.subrange(n as int, buf.len() as int);
247 $int_type::lemma_spec_from_to_be_bytes(fst);
248 self.lemma_prefix_secure(fst, snd);
249 assert(fst.add(snd) == buf);
250 }
251 }
252
253 proof fn lemma_prefix_secure(&self, s1: Seq<u8>, s2: Seq<u8>) {
254 $int_type::lemma_spec_from_be_bytes_no_lookahead(s1, s2);
255 }
256
257 proof fn lemma_parse_length(&self, s: Seq<u8>) {
258 }
259
260 proof fn lemma_parse_productive(&self, s: Seq<u8>) {
261 }
262 }
263
264 impl<'x, I: VestPublicInput, O: VestPublicOutput<I>> Combinator<'x, I, O> for $combinator {
265 type Type = $int_type;
266
267 type SType = &'x $int_type;
268
269 fn length(&self, _v: Self::SType) -> usize {
270 size_of::<$int_type>()
271 }
272
273 fn parse(&self, s: I) -> (res: Result<(usize, $int_type), ParseError>) {
274 if s.len() >= size_of::<$int_type>() {
275 let s_ = s.subrange(0, size_of::<$int_type>());
276 let v = $int_type::ex_from_be_bytes(s_.as_byte_slice());
277 proof {
278 let s_ = s_@;
279 let s__ = s@.subrange(size_of::<$int_type>() as int, s@.len() as int);
280 $int_type::lemma_spec_from_be_bytes_no_lookahead(s_, s__);
281 assert(s_.add(s__) == s@);
282 assert($int_type::spec_from_be_bytes(s@) == v);
283 v.reflex();
284 }
285 Ok((size_of::<$int_type>(), v))
286 } else {
287 Err(ParseError::UnexpectedEndOfInput)
288 }
289 }
290
291 fn serialize(&self, v: Self::SType, data: &mut O, pos: usize) -> (res: Result<usize, SerializeError>) {
292 if size_of::<$int_type>() <= data.len() - pos {
293 $int_type::ex_to_be_bytes(&v, data, pos);
294 proof {
295 v.reflex();
296 assert(data@.subrange(pos as int, pos + size_of::<$int_type>() as int)
297 == self.spec_serialize(v@));
298 }
299 Ok(size_of::<$int_type>())
300 } else {
301 Err(SerializeError::InsufficientBuffer)
302 }
303 }
304 }
305 } };
307}
308
309impl_combinator_for_le_uint_type!(U8, u8);
310
311impl_combinator_for_le_uint_type!(U16Le, u16);
312
313impl_combinator_for_le_uint_type!(U32Le, u32);
314
315impl_combinator_for_le_uint_type!(U64Le, u64);
316
317impl_combinator_for_be_uint_type!(U16Be, u16);
318
319impl_combinator_for_be_uint_type!(U32Be, u32);
320
321impl_combinator_for_be_uint_type!(U64Be, u64);
322
323pub trait FromToBytes where Self: ViewReflex + core::marker::Sized + Copy {
326 spec fn spec_from_le_bytes(s: Seq<u8>) -> Self;
328
329 spec fn spec_to_le_bytes(&self) -> Seq<u8>;
331
332 spec fn spec_from_be_bytes(s: Seq<u8>) -> Self;
334
335 spec fn spec_to_be_bytes(&self) -> Seq<u8>;
337
338 proof fn lemma_spec_to_from_le_bytes(&self)
341 ensures
345 self.spec_to_le_bytes().len() == size_of::<Self>(),
346 Self::spec_from_le_bytes(self.spec_to_le_bytes()) == *self,
347 ;
348
349 proof fn lemma_spec_from_to_le_bytes(s: Seq<u8>)
352 ensures
356 s.len() == size_of::<Self>() ==> Self::spec_to_le_bytes(&Self::spec_from_le_bytes(s))
357 == s,
358 ;
359
360 proof fn lemma_spec_from_le_bytes_no_lookahead(s1: Seq<u8>, s2: Seq<u8>)
362 ensures
363 s1.len() >= size_of::<Self>() ==> Self::spec_from_le_bytes(s1)
364 == Self::spec_from_le_bytes(s1.add(s2)),
365 ;
366
367 proof fn lemma_spec_to_from_be_bytes(&self)
370 ensures
371 self.spec_to_be_bytes().len() == size_of::<Self>(),
372 Self::spec_from_be_bytes(self.spec_to_be_bytes()) == *self,
373 ;
374
375 proof fn lemma_spec_from_to_be_bytes(s: Seq<u8>)
378 ensures
379 s.len() == size_of::<Self>() ==> Self::spec_to_be_bytes(&Self::spec_from_be_bytes(s))
380 == s,
381 ;
382
383 proof fn lemma_spec_from_be_bytes_no_lookahead(s1: Seq<u8>, s2: Seq<u8>)
385 ensures
386 s1.len() >= size_of::<Self>() ==> Self::spec_from_be_bytes(s1)
387 == Self::spec_from_be_bytes(s1.add(s2)),
388 ;
389
390 fn ex_from_le_bytes(s: &[u8]) -> (x: Self)
392 requires
393 s@.len() == size_of::<Self>(),
394 ensures
395 x == Self::spec_from_le_bytes(s@),
396 ;
397
398 fn ex_to_le_bytes<I, O>(&self, s: &mut O, pos: usize) where
400 I: VestPublicInput,
401 O: VestPublicOutput<I>,
402
403 requires
404 old(s)@.len() - pos >= size_of::<Self>(),
405 ensures
406 old(s)@.len() == s@.len(),
407 self.spec_to_le_bytes().len() == size_of::<Self>(),
408 s@ == seq_splice(old(s)@, pos, self.spec_to_le_bytes()),
409 ;
410
411 fn ex_from_be_bytes(s: &[u8]) -> (x: Self)
413 requires
414 s@.len() == size_of::<Self>(),
415 ensures
416 x == Self::spec_from_be_bytes(s@),
417 ;
418
419 fn ex_to_be_bytes<I, O>(&self, s: &mut O, pos: usize) where
421 I: VestPublicInput,
422 O: VestPublicOutput<I>,
423
424 requires
425 old(s)@.len() - pos >= size_of::<Self>(),
426 ensures
427 old(s)@.len() == s@.len(),
428 self.spec_to_be_bytes().len() == size_of::<Self>(),
429 s@ == seq_splice(old(s)@, pos, self.spec_to_be_bytes()),
430 ;
431
432 fn eq(&self, other: &Self) -> (res: bool)
434 ensures
435 res == (self@ == other@),
436 ;
437}
438
439impl FromToBytes for u8 {
440 open spec fn spec_from_le_bytes(s: Seq<u8>) -> Self {
441 s[0]
442 }
443
444 open spec fn spec_to_le_bytes(&self) -> Seq<u8> {
445 seq![*self]
446 }
447
448 open spec fn spec_from_be_bytes(s: Seq<u8>) -> Self {
449 s[0]
450 }
451
452 open spec fn spec_to_be_bytes(&self) -> Seq<u8> {
453 seq![*self]
454 }
455
456 proof fn lemma_spec_to_from_le_bytes(&self) {
457 }
458
459 proof fn lemma_spec_from_to_le_bytes(s: Seq<u8>) {
460 if s.len() == size_of::<u8>() {
461 assert(Self::spec_to_le_bytes(&Self::spec_from_le_bytes(s)) == s);
462 }
463 }
464
465 proof fn lemma_spec_from_le_bytes_no_lookahead(s1: Seq<u8>, s2: Seq<u8>) {
466 }
467
468 proof fn lemma_spec_to_from_be_bytes(&self) {
469 }
470
471 proof fn lemma_spec_from_to_be_bytes(s: Seq<u8>) {
472 if s.len() == size_of::<u8>() {
473 assert(Self::spec_to_be_bytes(&Self::spec_from_be_bytes(s)) == s);
474 }
475 }
476
477 proof fn lemma_spec_from_be_bytes_no_lookahead(s1: Seq<u8>, s2: Seq<u8>) {
478 }
479
480 fn ex_from_le_bytes(s: &[u8]) -> (x: u8) {
481 *slice_index_get(s, 0)
482 }
483
484 fn ex_to_le_bytes<I, O>(&self, s: &mut O, pos: usize) where
485 I: VestPublicInput,
486 O: VestPublicOutput<I>,
487 {
488 let ghost old = s@;
489 s.set_byte(pos, *self);
490 proof {
491 assert(s@ == seq_splice(old, pos, self.spec_to_le_bytes()));
492 }
493 }
494
495 fn ex_from_be_bytes(s: &[u8]) -> (x: u8) {
496 *slice_index_get(s, 0)
497 }
498
499 fn ex_to_be_bytes<I, O>(&self, s: &mut O, pos: usize) where
500 I: VestPublicInput,
501 O: VestPublicOutput<I>,
502 {
503 let ghost old = s@;
504 s.set_byte(pos, *self);
505 proof {
506 assert(s@ == seq_splice(old, pos, self.spec_to_be_bytes()));
507 }
508 }
509
510 fn eq(&self, other: &u8) -> (res: bool) {
511 *self == *other
512 }
513}
514
515impl FromToBytes for u16 {
516 open spec fn spec_from_le_bytes(s: Seq<u8>) -> Self {
517 (s[0] as u16) | (s[1] as u16) << 8
518 }
519
520 open spec fn spec_to_le_bytes(&self) -> Seq<u8> {
521 seq![(self & 0xff) as u8, ((self >> 8) & 0xff) as u8]
522 }
523
524 open spec fn spec_from_be_bytes(s: Seq<u8>) -> Self {
525 (s[0] as u16) << 8 | (s[1] as u16)
526 }
527
528 open spec fn spec_to_be_bytes(&self) -> Seq<u8> {
529 seq![((self >> 8) & 0xff) as u8, (self & 0xff) as u8]
530 }
531
532 proof fn lemma_spec_to_from_le_bytes(&self) {
533 assert({
534 &&& self & 0xff < 256
535 &&& (self >> 8) & 0xff < 256
536 }) by (bit_vector);
537 assert(self == ((self & 0xff) | ((self >> 8) & 0xff) << 8)) by (bit_vector);
538 }
539
540 proof fn lemma_spec_from_to_le_bytes(s: Seq<u8>) {
541 if s.len() == size_of::<u16>() {
542 let x = Self::spec_from_le_bytes(s);
543 let s0 = s[0] as u16;
544 let s1 = s[1] as u16;
545 assert(((x == s0 | s1 << 8) && (s0 < 256) && (s1 < 256)) ==> s0 == (x & 0xff) && s1 == (
546 (x >> 8) & 0xff)) by (bit_vector);
547 assert_seqs_equal!(Self::spec_to_le_bytes(&Self::spec_from_le_bytes(s)) == s);
548 }
549 }
550
551 proof fn lemma_spec_from_le_bytes_no_lookahead(s1: Seq<u8>, s2: Seq<u8>) {
552 }
553
554 proof fn lemma_spec_to_from_be_bytes(&self) {
555 assert({
556 &&& self & 0xff < 256
557 &&& (self >> 8) & 0xff < 256
558 }) by (bit_vector);
559 assert(self == (((self >> 8) & 0xff) << 8 | (self & 0xff))) by (bit_vector);
560 }
561
562 proof fn lemma_spec_from_to_be_bytes(s: Seq<u8>) {
563 if s.len() == size_of::<u16>() {
564 let x = Self::spec_from_be_bytes(s);
565 let s0 = s[0] as u16;
566 let s1 = s[1] as u16;
567 assert(((x == s0 << 8 | s1) && (s0 < 256) && (s1 < 256)) ==> s0 == ((x >> 8) & 0xff)
568 && s1 == (x & 0xff)) by (bit_vector);
569 assert_seqs_equal!(Self::spec_to_be_bytes(&Self::spec_from_be_bytes(s)) == s);
570 }
571 }
572
573 proof fn lemma_spec_from_be_bytes_no_lookahead(s1: Seq<u8>, s2: Seq<u8>) {
574 }
575
576 #[verifier::external_body]
577 fn ex_from_le_bytes(s: &[u8]) -> (x: u16) {
578 use core::convert::TryInto;
579 u16::from_le_bytes(s.try_into().unwrap())
580 }
581
582 #[verifier::external_body]
583 fn ex_to_le_bytes<I, O>(&self, s: &mut O, pos: usize) where
584 I: VestPublicInput,
585 O: VestPublicOutput<I>,
586 {
587 let bytes = self.to_le_bytes();
588 s.set_byte_range(pos, &bytes.as_slice());
592 }
593
594 #[verifier::external_body]
595 fn ex_from_be_bytes(s: &[u8]) -> (x: u16) {
596 use core::convert::TryInto;
597 u16::from_be_bytes(s.try_into().unwrap())
598 }
599
600 #[verifier::external_body]
601 fn ex_to_be_bytes<I, O>(&self, s: &mut O, pos: usize) where
602 I: VestPublicInput,
603 O: VestPublicOutput<I>,
604 {
605 let bytes = self.to_be_bytes();
606 s.set_byte_range(pos, &bytes.as_slice());
610 }
611
612 fn eq(&self, other: &u16) -> (res: bool) {
613 *self == *other
614 }
615}
616
617impl FromToBytes for u32 {
618 open spec fn spec_from_le_bytes(s: Seq<u8>) -> Self {
619 (s[0] as u32) | (s[1] as u32) << 8 | (s[2] as u32) << 16 | (s[3] as u32) << 24
620 }
621
622 open spec fn spec_to_le_bytes(&self) -> Seq<u8> {
623 seq![
624 (self & 0xff) as u8,
625 ((self >> 8) & 0xff) as u8,
626 ((self >> 16) & 0xff) as u8,
627 ((self >> 24) & 0xff) as u8,
628 ]
629 }
630
631 open spec fn spec_from_be_bytes(s: Seq<u8>) -> Self {
632 (s[0] as u32) << 24 | (s[1] as u32) << 16 | (s[2] as u32) << 8 | (s[3] as u32)
633 }
634
635 open spec fn spec_to_be_bytes(&self) -> Seq<u8> {
636 seq![
637 ((self >> 24) & 0xff) as u8,
638 ((self >> 16) & 0xff) as u8,
639 ((self >> 8) & 0xff) as u8,
640 (self & 0xff) as u8,
641 ]
642 }
643
644 proof fn lemma_spec_to_from_le_bytes(&self) {
645 let s = self.spec_to_le_bytes();
646 assert({
647 &&& self & 0xff < 256
648 &&& (self >> 8) & 0xff < 256
649 &&& (self >> 16) & 0xff < 256
650 &&& (self >> 24) & 0xff < 256
651 }) by (bit_vector);
652 assert(self == ((self & 0xff) | ((self >> 8) & 0xff) << 8 | ((self >> 16) & 0xff) << 16 | ((
653 self >> 24) & 0xff) << 24)) by (bit_vector);
654 }
655
656 proof fn lemma_spec_from_to_le_bytes(s: Seq<u8>) {
657 if s.len() == size_of::<u32>() {
658 let x = Self::spec_from_le_bytes(s);
659 let s0 = s[0] as u32;
660 let s1 = s[1] as u32;
661 let s2 = s[2] as u32;
662 let s3 = s[3] as u32;
663 assert(((x == s0 | s1 << 8 | s2 << 16 | s3 << 24) && (s0 < 256) && (s1 < 256) && (s2
664 < 256) && (s3 < 256)) ==> s0 == (x & 0xff) && s1 == ((x >> 8) & 0xff) && s2 == ((x
665 >> 16) & 0xff) && s3 == ((x >> 24) & 0xff)) by (bit_vector);
666 assert_seqs_equal!(Self::spec_to_le_bytes(&Self::spec_from_le_bytes(s)) == s);
667 }
668 }
669
670 proof fn lemma_spec_from_le_bytes_no_lookahead(s1: Seq<u8>, s2: Seq<u8>) {
671 }
672
673 proof fn lemma_spec_to_from_be_bytes(&self) {
674 let s = self.spec_to_be_bytes();
675 assert({
676 &&& self & 0xff < 256
677 &&& (self >> 8) & 0xff < 256
678 &&& (self >> 16) & 0xff < 256
679 &&& (self >> 24) & 0xff < 256
680 }) by (bit_vector);
681 assert(self == (((self >> 24) & 0xff) << 24 | ((self >> 16) & 0xff) << 16 | ((self >> 8)
682 & 0xff) << 8 | (self & 0xff))) by (bit_vector);
683 }
684
685 proof fn lemma_spec_from_to_be_bytes(s: Seq<u8>) {
686 if s.len() == size_of::<u32>() {
687 let x = Self::spec_from_be_bytes(s);
688 let s0 = s[0] as u32;
689 let s1 = s[1] as u32;
690 let s2 = s[2] as u32;
691 let s3 = s[3] as u32;
692 assert(((x == s0 << 24 | s1 << 16 | s2 << 8 | s3) && (s0 < 256) && (s1 < 256) && (s2
693 < 256) && (s3 < 256)) ==> s0 == ((x >> 24) & 0xff) && s1 == ((x >> 16) & 0xff) && s2
694 == ((x >> 8) & 0xff) && s3 == (x & 0xff)) by (bit_vector);
695 assert_seqs_equal!(Self::spec_to_be_bytes(&Self::spec_from_be_bytes(s)) == s);
696 }
697 }
698
699 proof fn lemma_spec_from_be_bytes_no_lookahead(s1: Seq<u8>, s2: Seq<u8>) {
700 }
701
702 #[verifier::external_body]
703 fn ex_from_le_bytes(s: &[u8]) -> (x: u32) {
704 use core::convert::TryInto;
705 u32::from_le_bytes(s.try_into().unwrap())
706 }
707
708 #[verifier::external_body]
709 fn ex_to_le_bytes<I, O>(&self, s: &mut O, pos: usize) where
710 I: VestPublicInput,
711 O: VestPublicOutput<I>,
712 {
713 let bytes = self.to_le_bytes();
714 s.set_byte_range(pos, &bytes.as_slice());
720 }
721
722 #[verifier::external_body]
723 fn ex_from_be_bytes(s: &[u8]) -> (x: u32) {
724 use core::convert::TryInto;
725 u32::from_be_bytes(s.try_into().unwrap())
726 }
727
728 #[verifier::external_body]
729 fn ex_to_be_bytes<I, O>(&self, s: &mut O, pos: usize) where
730 I: VestPublicInput,
731 O: VestPublicOutput<I>,
732 {
733 let bytes = self.to_be_bytes();
734 s.set_byte_range(pos, &bytes.as_slice());
740 }
741
742 fn eq(&self, other: &u32) -> (res: bool) {
743 *self == *other
744 }
745}
746
747impl FromToBytes for u64 {
748 open spec fn spec_from_le_bytes(s: Seq<u8>) -> Self {
749 (s[0] as u64) | (s[1] as u64) << 8 | (s[2] as u64) << 16 | (s[3] as u64) << 24 | (
750 s[4] as u64) << 32 | (s[5] as u64) << 40 | (s[6] as u64) << 48 | (s[7] as u64) << 56
751 }
752
753 open spec fn spec_to_le_bytes(&self) -> Seq<u8> {
754 seq![
755 (self & 0xff) as u8,
756 ((self >> 8) & 0xff) as u8,
757 ((self >> 16) & 0xff) as u8,
758 ((self >> 24) & 0xff) as u8,
759 ((self >> 32) & 0xff) as u8,
760 ((self >> 40) & 0xff) as u8,
761 ((self >> 48) & 0xff) as u8,
762 ((self >> 56) & 0xff) as u8,
763 ]
764 }
765
766 open spec fn spec_from_be_bytes(s: Seq<u8>) -> Self {
767 (s[0] as u64) << 56 | (s[1] as u64) << 48 | (s[2] as u64) << 40 | (s[3] as u64) << 32 | (
768 s[4] as u64) << 24 | (s[5] as u64) << 16 | (s[6] as u64) << 8 | (s[7] as u64)
769 }
770
771 open spec fn spec_to_be_bytes(&self) -> Seq<u8> {
772 seq![
773 ((self >> 56) & 0xff) as u8,
774 ((self >> 48) & 0xff) as u8,
775 ((self >> 40) & 0xff) as u8,
776 ((self >> 32) & 0xff) as u8,
777 ((self >> 24) & 0xff) as u8,
778 ((self >> 16) & 0xff) as u8,
779 ((self >> 8) & 0xff) as u8,
780 (self & 0xff) as u8,
781 ]
782 }
783
784 proof fn lemma_spec_to_from_le_bytes(&self) {
785 let s = self.spec_to_le_bytes();
786 assert({
787 &&& self & 0xff < 256
788 &&& (self >> 8) & 0xff < 256
789 &&& (self >> 16) & 0xff < 256
790 &&& (self >> 24) & 0xff < 256
791 &&& (self >> 32) & 0xff < 256
792 &&& (self >> 40) & 0xff < 256
793 &&& (self >> 48) & 0xff < 256
794 &&& (self >> 56) & 0xff < 256
795 }) by (bit_vector);
796 assert(self == ((self & 0xff) | ((self >> 8) & 0xff) << 8 | ((self >> 16) & 0xff) << 16 | ((
797 self >> 24) & 0xff) << 24 | ((self >> 32) & 0xff) << 32 | ((self >> 40) & 0xff) << 40 | ((
798 self >> 48) & 0xff) << 48 | ((self >> 56) & 0xff) << 56)) by (bit_vector);
799 }
800
801 proof fn lemma_spec_from_to_le_bytes(s: Seq<u8>) {
802 if s.len() == size_of::<u64>() {
803 let x = Self::spec_from_le_bytes(s);
804 let s0 = s[0] as u64;
805 let s1 = s[1] as u64;
806 let s2 = s[2] as u64;
807 let s3 = s[3] as u64;
808 let s4 = s[4] as u64;
809 let s5 = s[5] as u64;
810 let s6 = s[6] as u64;
811 let s7 = s[7] as u64;
812 assert(((x == s0 | s1 << 8 | s2 << 16 | s3 << 24 | s4 << 32 | s5 << 40 | s6 << 48 | s7
813 << 56) && (s0 < 256) && (s1 < 256) && (s2 < 256) && (s3 < 256) && (s4 < 256) && (s5
814 < 256) && (s6 < 256) && (s7 < 256)) ==> s0 == (x & 0xff) && s1 == ((x >> 8) & 0xff)
815 && s2 == ((x >> 16) & 0xff) && s3 == ((x >> 24) & 0xff) && s4 == ((x >> 32) & 0xff)
816 && s5 == ((x >> 40) & 0xff) && s6 == ((x >> 48) & 0xff) && s7 == ((x >> 56) & 0xff))
817 by (bit_vector);
818 assert_seqs_equal!(Self::spec_to_le_bytes(&Self::spec_from_le_bytes(s)) == s);
819 }
820 }
821
822 proof fn lemma_spec_from_le_bytes_no_lookahead(s1: Seq<u8>, s2: Seq<u8>) {
823 }
824
825 proof fn lemma_spec_to_from_be_bytes(&self) {
826 let s = self.spec_to_be_bytes();
827 assert({
828 &&& self & 0xff < 256
829 &&& (self >> 8) & 0xff < 256
830 &&& (self >> 16) & 0xff < 256
831 &&& (self >> 24) & 0xff < 256
832 &&& (self >> 32) & 0xff < 256
833 &&& (self >> 40) & 0xff < 256
834 &&& (self >> 48) & 0xff < 256
835 &&& (self >> 56) & 0xff < 256
836 }) by (bit_vector);
837 assert(self == (((self >> 56) & 0xff) << 56 | ((self >> 48) & 0xff) << 48 | ((self >> 40)
838 & 0xff) << 40 | ((self >> 32) & 0xff) << 32 | ((self >> 24) & 0xff) << 24 | ((self
839 >> 16) & 0xff) << 16 | ((self >> 8) & 0xff) << 8 | (self & 0xff))) by (bit_vector);
840 }
841
842 proof fn lemma_spec_from_to_be_bytes(s: Seq<u8>) {
843 if s.len() == size_of::<u64>() {
844 let x = Self::spec_from_be_bytes(s);
845 let s0 = s[0] as u64;
846 let s1 = s[1] as u64;
847 let s2 = s[2] as u64;
848 let s3 = s[3] as u64;
849 let s4 = s[4] as u64;
850 let s5 = s[5] as u64;
851 let s6 = s[6] as u64;
852 let s7 = s[7] as u64;
853 assert(((x == s0 << 56 | s1 << 48 | s2 << 40 | s3 << 32 | s4 << 24 | s5 << 16 | s6 << 8
854 | s7) && (s0 < 256) && (s1 < 256) && (s2 < 256) && (s3 < 256) && (s4 < 256) && (s5
855 < 256) && (s6 < 256) && (s7 < 256)) ==> s0 == ((x >> 56) & 0xff) && s1 == ((x >> 48)
856 & 0xff) && s2 == ((x >> 40) & 0xff) && s3 == ((x >> 32) & 0xff) && s4 == ((x >> 24)
857 & 0xff) && s5 == ((x >> 16) & 0xff) && s6 == ((x >> 8) & 0xff) && s7 == (x & 0xff))
858 by (bit_vector);
859 assert_seqs_equal!(Self::spec_to_be_bytes(&Self::spec_from_be_bytes(s)) == s);
860 }
861 }
862
863 proof fn lemma_spec_from_be_bytes_no_lookahead(s1: Seq<u8>, s2: Seq<u8>) {
864 }
865
866 #[verifier::external_body]
867 fn ex_from_le_bytes(s: &[u8]) -> (x: u64) {
868 use core::convert::TryInto;
869 u64::from_le_bytes(s.try_into().unwrap())
870 }
871
872 #[verifier::external_body]
873 fn ex_to_le_bytes<I, O>(&self, s: &mut O, pos: usize) where
874 I: VestPublicInput,
875 O: VestPublicOutput<I>,
876 {
877 let bytes = self.to_le_bytes();
878 s.set_byte_range(pos, &bytes.as_slice());
888 }
889
890 #[verifier::external_body]
891 fn ex_from_be_bytes(s: &[u8]) -> (x: u64) {
892 use core::convert::TryInto;
893 u64::from_be_bytes(s.try_into().unwrap())
894 }
895
896 #[verifier::external_body]
897 fn ex_to_be_bytes<I, O>(&self, s: &mut O, pos: usize) where
898 I: VestPublicInput,
899 O: VestPublicOutput<I>,
900 {
901 let bytes = self.to_be_bytes();
902 s.set_byte_range(pos, &bytes.as_slice());
912 }
913
914 fn eq(&self, other: &u64) -> (res: bool) {
915 *self == *other
916 }
917}
918
919impl SpecFrom<u8> for usize {
920 open spec fn spec_from(t: u8) -> usize {
921 t as usize
922 }
923}
924
925impl SpecFrom<u16> for usize {
926 open spec fn spec_from(t: u16) -> usize {
927 t as usize
928 }
929}
930
931impl SpecFrom<u32> for usize {
932 open spec fn spec_from(t: u32) -> usize {
933 t as usize
934 }
935}
936
937impl SpecFrom<u64> for usize {
938 open spec fn spec_from(t: u64) -> usize {
939 t as usize
940 }
941}
942
943impl SpecFrom<u24> for usize {
944 open spec fn spec_from(t: u24) -> usize {
945 t.spec_as_u32() as usize
946 }
947}
948
949impl From<u8> for usize {
950 fn ex_from(t: u8) -> usize {
951 t as usize
952 }
953}
954
955impl From<u16> for usize {
956 fn ex_from(t: u16) -> usize {
957 t as usize
958 }
959}
960
961impl From<u32> for usize {
962 fn ex_from(t: u32) -> usize {
963 t as usize
964 }
965}
966
967impl From<u64> for usize {
968 fn ex_from(t: u64) -> usize {
969 t as usize
970 }
971}
972
973impl From<u24> for usize {
974 fn ex_from(t: u24) -> usize {
975 t.as_u32() as usize
976 }
977}
978
979#[allow(non_camel_case_types)]
982#[derive(Debug, Clone, Copy, PartialEq, Eq)]
983pub struct u24(pub [u8; 3]);
984
985impl View for u24 {
986 type V = Self;
987
988 open spec fn view(&self) -> Self::V {
989 *self
990 }
991}
992
993impl u24 {
994 pub open spec fn spec_as_u32(&self) -> u32 {
996 let s = self.0;
997 let bytes = seq![0, s[0], s[1], s[2]];
998 u32::spec_from_be_bytes(bytes)
999 }
1000
1001 pub fn as_u32(&self) -> (o: u32)
1003 ensures
1004 o == self.spec_as_u32(),
1005 {
1006 let mut bytes = [0;4];
1007 bytes.set(1, self.0[0]);
1008 bytes.set(2, self.0[1]);
1009 bytes.set(3, self.0[2]);
1010 u32::ex_from_be_bytes(bytes.as_slice())
1011 }
1012}
1013
1014pub struct U24Le;
1016
1017impl View for U24Le {
1018 type V = U24Le;
1019
1020 open spec fn view(&self) -> Self::V {
1021 *self
1022 }
1023}
1024
1025impl SpecCombinator for U24Le {
1026 type Type = u24;
1027
1028 open spec fn spec_parse(&self, s: Seq<u8>) -> Option<(int, u24)> {
1032 match Fixed::<3>.spec_parse(s) {
1033 Some((n, bytes)) => Some((n, u24([bytes[2], bytes[1], bytes[0]]))),
1034 _ => None,
1035 }
1036 }
1037
1038 open spec fn spec_serialize(&self, v: u24) -> Seq<u8> {
1039 let bytes = v.0;
1040 Fixed::<3>.spec_serialize([bytes[2], bytes[1], bytes[0]]@)
1041 }
1042}
1043
1044impl SecureSpecCombinator for U24Le {
1045 open spec fn is_prefix_secure() -> bool {
1046 true
1047 }
1048
1049 open spec fn is_productive(&self) -> bool {
1050 true
1051 }
1052
1053 proof fn lemma_prefix_secure(&self, s1: Seq<u8>, s2: Seq<u8>) {
1054 Fixed::<3>.lemma_prefix_secure(s1, s2);
1055 }
1056
1057 proof fn theorem_serialize_parse_roundtrip(&self, v: u24) {
1058 let v_rev = u24([v.0[2], v.0[1], v.0[0]]);
1059 Fixed::<3>.theorem_serialize_parse_roundtrip(v_rev.0@);
1060 match Fixed::<3>.spec_parse(Fixed::<3>.spec_serialize(v_rev.0@)) {
1061 Some((n, bytes)) => {
1062 bytes_eq_view_implies_eq([bytes[2], bytes[1], bytes[0]], v.0);
1063 },
1064 _ => {},
1065 }
1066 }
1067
1068 proof fn theorem_parse_serialize_roundtrip(&self, s: Seq<u8>) {
1069 Fixed::<3>.theorem_parse_serialize_roundtrip(s);
1070 match Fixed::<3>.spec_parse(s) {
1071 Some((n, bytes)) => {
1072 assert([bytes[0], bytes[1], bytes[2]]@ == bytes);
1073 },
1074 _ => {},
1075 }
1076 }
1077
1078 proof fn lemma_parse_length(&self, s: Seq<u8>) {
1079 }
1080
1081 proof fn lemma_parse_productive(&self, s: Seq<u8>) {
1082 }
1083}
1084
1085impl<'x> Combinator<'x, &[u8], Vec<u8>> for U24Le {
1086 type Type = u24;
1087
1088 type SType = &'x u24;
1089
1090 fn length(&self, v: Self::SType) -> usize {
1091 3
1092 }
1093
1094 fn parse(&self, s: &[u8]) -> (res: Result<(usize, u24), ParseError>) {
1095 let (n, bytes) = <_ as Combinator<&[u8], Vec<u8>>>::parse(&Fixed::<3>, s)?;
1096 Ok((n, u24([bytes[2], bytes[1], bytes[0]])))
1097 }
1098
1099 fn serialize(&self, v: Self::SType, data: &mut Vec<u8>, pos: usize) -> (res: Result<
1100 usize,
1101 SerializeError,
1102 >) {
1103 <_ as Combinator<&[u8], Vec<u8>>>::serialize(
1104 &Fixed::<3>,
1105 &[v.0[2], v.0[1], v.0[0]].as_slice(),
1106 data,
1107 pos,
1108 )
1109 }
1110}
1111
1112pub struct U24Be;
1114
1115impl View for U24Be {
1116 type V = U24Be;
1117
1118 open spec fn view(&self) -> Self::V {
1119 *self
1120 }
1121}
1122
1123impl SpecCombinator for U24Be {
1124 type Type = u24;
1125
1126 open spec fn spec_parse(&self, s: Seq<u8>) -> Option<(int, u24)> {
1127 match Fixed::<3>.spec_parse(s) {
1128 Some((n, bytes)) => Some((n, u24([bytes[0], bytes[1], bytes[2]]))),
1129 _ => None,
1130 }
1131 }
1132
1133 open spec fn spec_serialize(&self, v: u24) -> Seq<u8> {
1134 let bytes = v.0;
1135 Fixed::<3>.spec_serialize(bytes@)
1136 }
1137}
1138
1139impl SecureSpecCombinator for U24Be {
1140 open spec fn is_prefix_secure() -> bool {
1141 true
1142 }
1143
1144 open spec fn is_productive(&self) -> bool {
1145 true
1146 }
1147
1148 proof fn lemma_prefix_secure(&self, s1: Seq<u8>, s2: Seq<u8>) {
1149 Fixed::<3>.lemma_prefix_secure(s1, s2);
1150 }
1151
1152 proof fn theorem_serialize_parse_roundtrip(&self, v: u24) {
1153 Fixed::<3>.theorem_serialize_parse_roundtrip(v.0@);
1154 match Fixed::<3>.spec_parse(Fixed::<3>.spec_serialize(v.0@)) {
1155 Some((n, bytes)) => {
1156 bytes_eq_view_implies_eq([bytes[0], bytes[1], bytes[2]], v.0);
1157 },
1158 _ => {},
1159 }
1160 }
1161
1162 proof fn theorem_parse_serialize_roundtrip(&self, s: Seq<u8>) {
1163 Fixed::<3>.theorem_parse_serialize_roundtrip(s);
1164 match Fixed::<3>.spec_parse(s) {
1165 Some((n, bytes)) => {
1166 assert([bytes[0], bytes[1], bytes[2]]@ == bytes);
1167 },
1168 _ => {},
1169 }
1170 }
1171
1172 proof fn lemma_parse_length(&self, s: Seq<u8>) {
1173 }
1174
1175 proof fn lemma_parse_productive(&self, s: Seq<u8>) {
1176 }
1177}
1178
1179proof fn bytes_eq_view_implies_eq<const N: usize>(a: [u8; N], b: [u8; N])
1180 ensures
1181 a@ =~= b@ <==> a == b,
1182{
1183 if a@ == b@ {
1184 assert(a == b);
1185 }
1186}
1187
1188impl<'x> Combinator<'x, &[u8], Vec<u8>> for U24Be {
1189 type Type = u24;
1190
1191 type SType = &'x u24;
1192
1193 fn length(&self, v: Self::SType) -> usize {
1194 3
1195 }
1196
1197 fn parse(&self, s: &[u8]) -> (res: Result<(usize, u24), ParseError>) {
1198 let (n, bytes) = <_ as Combinator<&[u8], Vec<u8>>>::parse(&Fixed::<3>, s)?;
1199 Ok((n, u24([bytes[0], bytes[1], bytes[2]])))
1200 }
1201
1202 fn serialize(&self, v: Self::SType, data: &mut Vec<u8>, pos: usize) -> (res: Result<
1203 usize,
1204 SerializeError,
1205 >) {
1206 <_ as Combinator<&[u8], Vec<u8>>>::serialize(&Fixed::<3>, &v.0.as_slice(), data, pos)
1207 }
1208}
1209
1210}