1use crate::core::exec::output::*;
3use crate::core::exec::{parser::*, serializer::*, ParseError, ParseErrorKind};
4use crate::{
5 combinators::{
6 bytes::ExactLen, length::AsLen, mapped::spec::FnSpecMapper, Bind, Mapped, Pair, Refined,
7 Tail, U8,
8 },
9 core::{proof::*, spec::*},
10};
11#[cfg(feature = "alloc")]
12use alloc::vec::Vec;
13use vstd::prelude::*;
14use OutputBuf;
15
16verus! {
17
18pub struct BitString<'a, const DER: bool = true> {
23 unused: u8,
25 bits: &'a [u8],
27}
28
29#[cfg(feature = "alloc")]
31pub struct BitStringOwned {
32 unused: u8,
33 bits: Vec<u8>,
34}
35
36#[verifier::ext_equal]
37pub struct BitStringSpec {
38 pub unused: u8,
39 pub bits: Seq<u8>,
40}
41
42impl<'a, const DER: bool> DeepView for BitString<'a, DER> {
43 type V = BitStringSpec;
44
45 closed spec fn deep_view(&self) -> Self::V {
46 BitStringSpec { unused: self.unused, bits: self.bits.deep_view() }
47 }
48}
49
50#[cfg(feature = "alloc")]
51impl DeepView for BitStringOwned {
52 type V = BitStringSpec;
53
54 closed spec fn deep_view(&self) -> Self::V {
55 BitStringSpec { unused: self.unused, bits: self.bits.deep_view() }
56 }
57}
58
59impl<'a, const DER: bool> BitString<'a, DER> {
60 #[verifier::type_invariant]
61 spec fn wf(&self) -> bool {
62 self.deep_view().wf::<DER>()
63 }
64
65 pub fn new(unused: u8, bits: &'a [u8]) -> (bs: Self)
66 requires
67 unused <= 7,
68 bits.len() == 0 ==> unused == 0,
69 DER ==> bits.len() > 0 ==> bits@.last().trailing_zeros() >= unused,
70 ensures
71 (bs.deep_view() == BitStringSpec { unused, bits: bits.deep_view() }),
72 {
73 BitString { unused, bits }
74 }
75
76 pub fn unused(&self) -> (unused: u8)
77 ensures
78 unused == self.deep_view().unused,
79 self.deep_view().wf::<DER>(),
80 {
81 proof {
82 use_type_invariant(self);
83 }
84 self.unused
85 }
86
87 pub fn bits(&self) -> (bits: &'a [u8])
88 ensures
89 bits.deep_view() == self.deep_view().bits,
90 {
91 self.bits
92 }
93}
94
95#[cfg(feature = "alloc")]
96impl BitStringOwned {
97 #[verifier::type_invariant]
98 spec fn wf(&self) -> bool {
99 self.deep_view().wf::<false>()
100 }
101
102 pub fn new(unused: u8, bits: Vec<u8>) -> (value: Self)
103 requires
104 unused <= 7,
105 bits.len() == 0 ==> unused == 0,
106 ensures
107 value.deep_view() == (BitStringSpec { unused, bits: bits.deep_view() }),
108 {
109 Self { unused, bits }
110 }
111
112 pub fn unused(&self) -> (unused: u8)
113 ensures
114 unused == self.deep_view().unused,
115 self.deep_view().wf::<false>(),
116 {
117 proof {
118 use_type_invariant(self);
119 }
120 self.unused
121 }
122
123 pub fn bits(&self) -> (bits: &[u8])
124 ensures
125 bits.deep_view() == self.deep_view().bits,
126 {
127 self.bits.as_slice()
128 }
129}
130
131impl BitStringSpec {
132 #[verusfmt::skip]
133 pub open spec fn wf<const DER: bool>(&self) -> bool {
134 &&& self.unused <= 7
135 &&& (self.bits.len() == 0 ==> self.unused == 0)
137 &&& (DER ==> self.bits.len() > 0 ==> self.bits.last().trailing_zeros() >= self.unused)
139 }
140}
141
142type BitStringFmt<const DER: bool> = Mapped<
143 Refined<Pair<U8, Tail>, PredFnSpec<(u8, Seq<u8>)>>,
144 FnSpecMapper<(u8, Seq<u8>), BitStringSpec>,
145>;
146
147pub(super) open(super) spec fn bitstring_fmt<const DER: bool>() -> BitStringFmt<DER> {
148 Mapped {
149 inner: Refined(
150 Pair(U8, Tail),
151 |r: (u8, Seq<u8>)|
152 {
153 let (unused, bits) = r;
154 BitStringSpec { unused, bits }.wf::<DER>()
155 },
156 ),
157 mapper: (
158 |r: (u8, Seq<u8>)|
159 {
160 let (unused, bits) = r;
161 BitStringSpec { unused, bits }
162 },
163 |spec: BitStringSpec| (spec.unused, spec.bits),
164 ),
165 }
166}
167
168pub(crate) proof fn lemma_bit_string_fmt_serialization<const DER: bool>(value: BitStringSpec)
170 ensures
171 super::BitStringFmt::<DER>.spec_serialize(value) == Pair(U8, Tail).spec_serialize(
172 (value.unused, value.bits),
173 ),
174 super::BitStringFmt::<DER>.byte_len(value) == Pair(U8, Tail).byte_len(
175 (value.unused, value.bits),
176 ),
177{
178}
179
180mod derived_specs {
181 use super::*;
182 use super::super::BitStringFmt;
183
184 impl<const DER: bool> SpecParser for BitStringFmt<DER> {
185 type PVal = BitStringSpec;
186
187 open(super) spec fn spec_parse(&self, ibuf: Seq<u8>) -> Option<(int, Self::PVal)> {
188 bitstring_fmt::<DER>().spec_parse(ibuf)
189 }
190 }
191
192 impl<const DER: bool> Consistency for BitStringFmt<DER> {
193 type Val = BitStringSpec;
194
195 open(super) spec fn consistent(&self, v: Self::Val) -> bool {
196 bitstring_fmt::<DER>().consistent(v)
197 }
198 }
199
200 impl<const DER: bool> SpecSerializerDps for BitStringFmt<DER> {
201 type SValue = BitStringSpec;
202
203 open(super) spec fn spec_serialize_dps(&self, v: Self::SValue, obuf: Seq<u8>) -> Seq<u8> {
204 bitstring_fmt::<DER>().spec_serialize_dps(v, obuf)
205 }
206 }
207
208 impl<const DER: bool> SpecSerializer for BitStringFmt<DER> {
209 type SVal = BitStringSpec;
210
211 open(super) spec fn spec_serialize(&self, v: Self::SVal) -> Seq<u8> {
212 bitstring_fmt::<DER>().spec_serialize(v)
213 }
214 }
215
216 impl<const DER: bool> SpecByteLen for BitStringFmt<DER> {
217 type T = BitStringSpec;
218
219 open(super) spec fn byte_len(&self, v: Self::T) -> nat {
220 bitstring_fmt::<DER>().byte_len(v)
221 }
222 }
223
224}
225
226mod derived_proofs {
227 use super::*;
228 use super::super::BitStringFmt;
229
230 impl<const DER: bool> SafeParser for BitStringFmt<DER> {
231 proof fn lemma_parse_safe(&self, ibuf: Seq<u8>) {
232 bitstring_fmt::<DER>().lemma_parse_safe(ibuf);
233 }
234 }
235
236 impl<const DER: bool> Productive for BitStringFmt<DER> {
237 proof fn lemma_productive(&self, s: Seq<u8>) {
238 bitstring_fmt::<DER>().lemma_productive(s);
239 }
240 }
241
242 impl<const DER: bool> SoundParser for BitStringFmt<DER> {
243 proof fn lemma_parse_sound_consumption(&self, ibuf: Seq<u8>) {
244 bitstring_fmt::<DER>().lemma_parse_sound_consumption(ibuf);
245 }
246
247 proof fn lemma_parse_sound_value(&self, ibuf: Seq<u8>) {
248 bitstring_fmt::<DER>().lemma_parse_sound_value(ibuf);
249 }
250 }
251
252 impl<const DER: bool> GoodSerializer for BitStringFmt<DER> {
253 proof fn lemma_serialize_len(&self, v: Self::SVal) {
254 bitstring_fmt::<DER>().lemma_serialize_len(v);
255 }
256 }
257
258 impl<const DER: bool> SPRoundTripDps for BitStringFmt<DER> {
259 proof fn theorem_serialize_dps_parse_roundtrip(&self, v: Self::T, obuf: Seq<u8>) {
260 bitstring_fmt::<DER>().theorem_serialize_dps_parse_roundtrip(v, obuf);
261 }
262 }
263
264 impl<const DER: bool> NonMalleable for BitStringFmt<DER> {
265 proof fn lemma_parse_non_malleable(&self, buf1: Seq<u8>, buf2: Seq<u8>) {
266 bitstring_fmt::<DER>().lemma_parse_non_malleable(buf1, buf2);
267 }
268 }
269
270 impl<const DER: bool> EquivSerializers for BitStringFmt<DER> {
271 proof fn lemma_serialize_equiv_on_empty(&self, v: Self::SVal) {
272 bitstring_fmt::<DER>().lemma_serialize_equiv_on_empty(v);
273 }
274 }
275
276}
277
278impl<'i, const DER: bool> Parser<&'i [u8]> for super::BitStringFmt<DER> {
279 type PT = BitString<'i, DER>;
280
281 fn parse(&self, ibuf: &&'i [u8]) -> PResult<Self::PT> {
282 let (n, (unused, bits)): (usize, (u8, &[u8])) = Pair(U8, Tail).parse(ibuf)?;
283 if unused > 7 {
284 return Err(ParseError::custom("Invalid number of unused bits in BIT STRING"));
285 }
286 if bits.len() == 0 && unused != 0 {
287 return Err(ParseError::custom("Invalid number of unused bits in BIT STRING"));
288 }
289 if DER && bits.len() > 0 && bits[bits.len() - 1].trailing_zeros() < unused as u32 {
290 return Err(ParseError::custom("Non-canonical encoding of BIT STRING."));
291 }
292 Ok((n, BitString::new(unused, bits)))
293 }
294}
295
296impl<Output: OutputBuf, 'i, const DER: bool> Serializer<
297 Output,
298 BitString<'i, DER>,
299> for super::BitStringFmt<DER> {
300 fn serialize_into(&self, v: &BitString<'i, DER>, obuf: &mut Output) {
301 broadcast use crate::core::exec::output::outbuf_lemmas;
302
303 U8.serialize_into(&v.unused, obuf);
304 Tail.serialize_into(&v.bits, obuf);
305 }
306}
307
308impl<'i, const DER: bool> Prepare<BitString<'i, DER>> for super::BitStringFmt<DER> {
309 fn prepare(&self, v: &BitString<'i, DER>) -> Result<usize, PreSerializeError> {
310 proof {
311 use_type_invariant(v);
312 }
313 let n1 = U8.prepare(&v.unused)?;
314 let n2 = Tail.prepare(&v.bits)?;
315 let total_len = n1.checked_add(n2).ok_or(PreSerializeError::length_too_large())?;
316 Ok(total_len)
317 }
318}
319
320impl<'i, const DER: bool> ByteLen<BitString<'i, DER>> for super::BitStringFmt<DER> {
321 fn length(&self, v: &BitString<'i, DER>) -> usize {
322 let n1 = U8.length(&v.unused);
323 let n2 = Tail.length(&v.bits);
324 n1 + n2
325 }
326}
327
328#[cfg(feature = "alloc")]
329impl<Output: OutputBuf> Serializer<Output, BitStringOwned> for super::BitStringFmt<false> {
330 fn serialize_into(&self, v: &BitStringOwned, obuf: &mut Output) {
331 broadcast use crate::core::exec::output::outbuf_lemmas;
332
333 proof {
334 use_type_invariant(v);
335 }
336 U8.serialize_into(&v.unused, obuf);
337 Tail.serialize_into(&v.bits.as_slice(), obuf);
338 }
339}
340
341#[cfg(feature = "alloc")]
342impl Prepare<BitStringOwned> for super::BitStringFmt<false> {
343 fn prepare(&self, v: &BitStringOwned) -> Result<usize, PreSerializeError> {
344 proof {
345 use_type_invariant(v);
346 }
347 let n1 = U8.prepare(&v.unused)?;
348 let n2 = Tail.prepare(&v.bits.as_slice())?;
349 n1.checked_add(n2).ok_or(PreSerializeError::length_too_large())
350 }
351}
352
353#[cfg(feature = "alloc")]
354impl ByteLen<BitStringOwned> for super::BitStringFmt<false> {
355 fn length(&self, v: &BitStringOwned) -> usize {
356 U8.length(&v.unused) + Tail.length(&v.bits.as_slice())
357 }
358}
359
360}