vest_lib/buf_traits.rs
1pub use crate::utils::*;
2// use core::rc::Rc;
3use alloc::vec::Vec;
4
5use vstd::prelude::*;
6use vstd::slice::*;
7use vstd::*;
8
9verus! {
10
11//////////////////////////////////////////////////////////////////////////////
12/// Trait definitions
13/// Trait for types that can be used as input for Vest parsers, roughly corresponding to byte buffers.
14/// `VestInput` does not expose the contents of the buffer, so opaque buffer types for side-channel
15/// security can implement `VestInput`.
16pub trait VestInput: View<V = Seq<u8>> {
17 /// The length of the buffer.
18 fn len(&self) -> (res: usize)
19 ensures
20 res == self@.len(),
21 ;
22
23 /// Analogous to `vstd::slice_subrange`
24 fn subrange(&self, i: usize, j: usize) -> (res: Self) where Self: Sized
25 requires
26 0 <= i <= j <= self@.len(),
27 ensures
28 res@ == self@.subrange(i as int, j as int),
29 ;
30
31 /// Creates another buffer with the same contents.
32 /// For good performance, this function should be cheap, just creating a new reference rather than
33 /// actually copying the buffer.
34 fn clone(&self) -> (res: Self) where Self: Sized
35 ensures
36 res@ == self@,
37 ;
38}
39
40/// Trait for types that can be used as input for Vest parsers, roughly corresponding to byte buffers.
41/// `VestPublicInput` can be set using transparent bytes, so it cannot provide type abstraction for side-channel security.
42pub trait VestPublicInput: VestInput {
43 /// Returns a byte slice with the contents of the buffer
44 fn as_byte_slice(&self) -> (res: &[u8])
45 ensures
46 res@ == self@,
47 ;
48}
49
50/// Trait for types that can be used as output for Vest serializers.
51/// `VestOutput` does not expose the contents of the buffer, so opaque buffer types for side-channel
52/// security can implement `VestOutput`.
53pub trait VestOutput<I>: View<V = Seq<u8>> where I: View<V = Seq<u8>> {
54 /// The length of the buffer.
55 fn len(&self) -> (res: usize)
56 ensures
57 res == self@.len(),
58 ;
59
60 /// Copy `input` to `self` starting at index `i`.
61 fn set_range(&mut self, i: usize, input: &I) -> (res: ())
62 requires
63 0 <= i + input@.len() <= old(self)@.len() <= usize::MAX,
64 ensures
65 self@.len() == old(self)@.len() && self@ == old(self)@.subrange(0, i as int).add(
66 input@,
67 ).add(old(self)@.subrange(i + input@.len(), self@.len() as int)),
68 ;
69}
70
71/// Trait for types that can be used as output for Vest serializers.
72/// `VestPublicOutput` can be set using transparent bytes, so it cannot provide type abstraction for side-channel security.
73pub trait VestPublicOutput<I>: VestOutput<I> where I: View<V = Seq<u8>> {
74 /// Set the byte at index `i` to `value`.
75 fn set_byte(&mut self, i: usize, value: u8)
76 requires
77 i < old(self)@.len(),
78 ensures
79 self@ == old(self)@.update(i as int, value),
80 ;
81
82 /// Copy `input` to `self` starting at index `i`. (Same as `set_range` but with byte slice input.)
83 fn set_byte_range(&mut self, i: usize, input: &[u8]) -> (res: ())
84 requires
85 0 <= i + input@.len() <= old(self)@.len() <= usize::MAX,
86 ensures
87 self@.len() == old(self)@.len() && self@ == old(self)@.subrange(0, i as int).add(
88 input@,
89 ).add(old(self)@.subrange(i + input@.len(), self@.len() as int)),
90 ;
91}
92
93//////////////////////////////////////////////////////////////////////////////
94/// Implementations for common types
95impl<'a> VestInput for &'a [u8] {
96 fn len(&self) -> usize {
97 <[u8]>::len(self)
98 }
99
100 fn subrange(&self, i: usize, j: usize) -> &'a [u8] {
101 slice_subrange(*self, i, j)
102 }
103
104 fn clone(&self) -> &'a [u8] {
105 *self
106 }
107}
108
109impl<'a> VestPublicInput for &'a [u8] {
110 fn as_byte_slice(&self) -> &[u8] {
111 *self
112 }
113}
114
115// /// Provided to demonstrate flexibility of the trait, but likely should not be used,
116// /// since this impl copies the `Vec` every time you call `subrange` or `clone`.
117// impl VestSecretInput for Vec<u8> {
118// fn len(&self) -> usize {
119// Vec::len(self)
120// }
121// fn subrange(&self, i: usize, j: usize) -> Vec<u8> {
122// let mut res = Vec::new();
123// vec_u8_extend_from_slice(&mut res, slice_subrange(self.as_slice(), i, j));
124// proof {
125// assert_seqs_equal!(res@, self@.subrange(i as int, j as int));
126// }
127// res
128// }
129// fn clone(&self) -> Vec<u8> {
130// Clone::clone(self)
131// }
132// }
133// impl VestInput for Vec<u8> {
134// fn as_byte_slice(&self) -> &[u8] {
135// self.as_slice()
136// }
137// }
138// /// Provided to demonstrate flexibility of the trait, but likely should not be used,
139// /// since this impl copies the `Vec` every time you call `subrange` or `clone`.
140// impl VestSecretInput for Rc<Vec<u8>> {
141// fn len(&self) -> usize {
142// Vec::len(self)
143// }
144// fn subrange(&self, i: usize, j: usize) -> Rc<Vec<u8>> {
145// let mut res = Vec::new();
146// vec_u8_extend_from_slice(&mut res, slice_subrange(self.as_slice(), i, j));
147// proof {
148// assert_seqs_equal!(res@, self@.subrange(i as int, j as int));
149// }
150// Rc::new(res)
151// }
152// fn clone(&self) -> Rc<Vec<u8>> {
153// Clone::clone(self)
154// }
155// }
156// impl VestInput for Rc<Vec<u8>> {
157// fn as_byte_slice(&self) -> &[u8] {
158// self.as_slice()
159// }
160// }
161impl<I> VestOutput<I> for Vec<u8> where I: VestPublicInput {
162 fn len(&self) -> usize {
163 Vec::len(self)
164 }
165
166 fn set_range(&mut self, i: usize, input: &I) {
167 set_range(self, i, input.as_byte_slice());
168 }
169}
170
171impl<I> VestPublicOutput<I> for Vec<u8> where I: VestPublicInput {
172 fn set_byte(&mut self, i: usize, value: u8) {
173 self.set(i, value);
174 }
175
176 fn set_byte_range(&mut self, i: usize, input: &[u8]) {
177 set_range(self, i, input);
178 }
179}
180
181} // verus!