1use crate::asn1::{ASN1Fmt, BerLength, BerLengthFmt, Class, Tag, TagFmt, BER};
3use crate::combinators::{
4 bytes::ExactLen, mapped::spec::FnSpecMapper, tail::RepeatTillEnd, Bind, Const, Mapped,
5 PrefixTagged, Repeat, Sum,
6};
7use crate::core::exec::input::InputBuf;
8use crate::core::exec::parser::*;
9use crate::core::exec::{
10 ByteLen, OutputBuf, PResult, ParseError, ParseErrorKind, Parser, PreSerializeError, Prepare,
11 Serializer,
12};
13use crate::core::{proof::*, spec::*};
14#[cfg(feature = "alloc")]
15use alloc::vec::Vec;
16use vstd::prelude::*;
17
18use super::any::{parse_discard_eoc, EocFmt, EocValue, EOC};
19use Sum::Inl as L;
20use Sum::Inr as R;
21
22verus! {
23
24type BerSequenceOfWireType<T> = (BerLength, Sum<Seq<T>, (Seq<T>, EocValue)>);
25
26type BerSequenceOfInnerFmt<C> = Mapped<
27 PrefixTagged<
28 TagFmt,
29 Tag,
30 Bind<
31 BerLengthFmt,
32 spec_fn(BerLength) -> Sum<ExactLen<RepeatTillEnd<C>, usize>, Repeat<C, EocFmt>>,
33 >,
34 >,
35 FnSpecMapper<BerSequenceOfWireType<<C as SpecByteLen>::T>, Seq<<C as SpecByteLen>::T>>,
36>;
37
38pub open spec fn ber_sequence_of_fmt<C: SpecCombinator>(
44 tag: Tag,
45 content: C,
46) -> BerSequenceOfInnerFmt<C> {
47 #[verusfmt::skip]
48 Mapped {
49 inner: PrefixTagged(TagFmt, tag, Bind(BerLengthFmt, |len: BerLength|
50 match len {
51 BerLength::Definite(len) => L(ExactLen(len, RepeatTillEnd(content))),
52 BerLength::Indefinite => R(Repeat(content, EOC)),
53 },
54 ),
55 ),
56 mapper: (
57 |parsed: BerSequenceOfWireType<C::T>|
58 match parsed.1 {
59 L(values) => values,
60 R((values, _eoc)) => values,
61 },
62 |values: Seq<C::T>|
63 {
64 let len = RepeatTillEnd(content).byte_len(values) as usize;
65 (BerLength::Definite(len), L(values))
66 },
67 ),
68 }
69}
70
71pub open spec fn ber_sequence_of_normalized_fmt<C>(tag: Tag, content: C) -> ASN1Fmt<
73 RepeatTillEnd<C>,
74 BER,
75> {
76 ASN1Fmt(tag, RepeatTillEnd(content))
77}
78
79#[derive(Copy)]
85pub struct BerSequenceOfFmt<C>(pub Tag, pub C);
86
87impl<C: Clone> Clone for BerSequenceOfFmt<C> {
88 fn clone(&self) -> (cloned: Self)
89 ensures
90 cloned.0 == self.0,
91 call_ensures(C::clone, (&self.1,), cloned.1),
92 {
93 BerSequenceOfFmt(self.0, self.1.clone())
94 }
95}
96
97impl<C: Copy> BerSequenceOfFmt<C> {
98 #[verifier::allow_in_spec]
100 pub const fn universal(content: C) -> Self
101 returns
102 Self(TagFmt::SEQUENCE, content),
103 {
104 Self(TagFmt::SEQUENCE, content)
105 }
106
107 #[verifier::allow_in_spec]
109 pub const fn implicit(class: Class, number: u64, content: C) -> Self
110 returns
111 Self(
112 Tag {
113 class,
114 constructed: true,
115 number: crate::asn1::tag::tag_num_from_uint(number),
116 },
117 content,
118 ),
119 {
120 Self(
121 Tag { class, constructed: true, number: crate::asn1::tag::tag_num_from_uint(number) },
122 content,
123 )
124 }
125}
126
127mod derived_specs {
128 use super::*;
129
130 impl<C: SpecCombinator> SpecParser for BerSequenceOfFmt<C> {
131 type PVal = Seq<C::T>;
132
133 open spec fn spec_parse(&self, ibuf: Seq<u8>) -> Option<(int, Self::PVal)> {
134 ber_sequence_of_fmt(self.0, self.1).spec_parse(ibuf)
135 }
136 }
137
138 impl<C: SpecCombinator> Consistency for BerSequenceOfFmt<C> {
139 type Val = Seq<C::T>;
140
141 open spec fn consistent(&self, value: Self::Val) -> bool {
142 ber_sequence_of_fmt(self.0, self.1).consistent(value)
143 }
144 }
145
146 impl<C: SpecCombinator> SpecSerializerDps for BerSequenceOfFmt<C> {
147 type SValue = Seq<C::T>;
148
149 open spec fn spec_serialize_dps(&self, value: Self::SValue, obuf: Seq<u8>) -> Seq<u8> {
150 ber_sequence_of_fmt(self.0, self.1).spec_serialize_dps(value, obuf)
151 }
152 }
153
154 impl<C: SpecCombinator> SpecSerializer for BerSequenceOfFmt<C> {
155 type SVal = Seq<C::T>;
156
157 open spec fn spec_serialize(&self, value: Self::SVal) -> Seq<u8> {
158 ber_sequence_of_fmt(self.0, self.1).spec_serialize(value)
159 }
160 }
161
162 impl<C: SpecCombinator> SpecByteLen for BerSequenceOfFmt<C> {
163 type T = Seq<C::T>;
164
165 open spec fn byte_len(&self, value: Self::T) -> nat {
166 ber_sequence_of_fmt(self.0, self.1).byte_len(value)
167 }
168 }
169
170}
171
172mod derived_proofs {
173 use super::*;
174
175 impl<C: SpecCombinator + SafeParser> SafeParser for BerSequenceOfFmt<C> {
176 open spec fn safe_inv(&self) -> bool {
177 self.1.safe_inv()
178 }
179
180 proof fn lemma_parse_safe(&self, ibuf: Seq<u8>) {
181 ber_sequence_of_fmt(self.0, self.1).lemma_parse_safe(ibuf);
182 }
183 }
184
185 impl<C: SpecCombinator + SafeParser> Productive for BerSequenceOfFmt<C> {
186 open spec fn productive_inv(&self) -> bool {
187 self.1.safe_inv()
188 }
189
190 proof fn lemma_productive(&self, ibuf: Seq<u8>) {
191 ber_sequence_of_fmt(self.0, self.1).lemma_productive(ibuf);
192 }
193 }
194
195 impl<C: SpecCombinator + GoodSerializer> GoodSerializer for BerSequenceOfFmt<C> {
196 open spec fn serialize_inv(&self) -> bool {
197 self.1.serialize_inv()
198 }
199
200 proof fn lemma_serialize_len(&self, value: Self::SVal) {
201 ber_sequence_of_fmt(self.0, self.1).lemma_serialize_len(value);
202 }
203 }
204
205 impl<
206 C: SpecCombinator + GoodSerializer + EquivSerializersGeneral,
207 > NonTailFmt for BerSequenceOfFmt<C> {
208 open spec fn serialize_dps_inv(&self) -> bool {
209 &&& self.1.serialize_inv()
210 &&& self.1.equiv_general_inv()
211 }
212
213 proof fn lemma_serialize_dps_prepend(&self, value: Self::SValue, obuf: Seq<u8>) {
214 ber_sequence_of_normalized_fmt(self.0, self.1).lemma_serialize_dps_prepend(value, obuf);
215 }
216
217 proof fn lemma_serialize_dps_len(&self, value: Self::SValue, obuf: Seq<u8>) {
218 ber_sequence_of_normalized_fmt(self.0, self.1).lemma_serialize_dps_len(value, obuf);
219 }
220 }
221
222 impl<C: SpecCombinator + EquivSerializersGeneral> EquivSerializersGeneral for BerSequenceOfFmt<
223 C,
224 > {
225 open spec fn equiv_general_inv(&self) -> bool {
226 self.1.equiv_general_inv()
227 }
228
229 proof fn lemma_serialize_equiv(&self, value: Self::SVal, obuf: Seq<u8>) {
230 ber_sequence_of_normalized_fmt(self.0, self.1).lemma_serialize_equiv(value, obuf);
231 }
232 }
233
234 impl<C: SpecCombinator + EquivSerializersGeneral> EquivSerializers for BerSequenceOfFmt<C> {
235 open spec fn equiv_inv(&self) -> bool {
236 self.1.equiv_general_inv()
237 }
238
239 proof fn lemma_serialize_equiv_on_empty(&self, value: Self::SVal) {
240 self.lemma_serialize_equiv(value, Seq::empty());
241 }
242 }
243
244 impl<C> SPRoundTripDps for BerSequenceOfFmt<C> where
245 C:
246 SpecCombinator + Productive + GoodSerializer + NonTailFmt + SPRoundTripDps + EquivSerializersGeneral,
247 {
248 open spec fn unambiguous(&self) -> bool {
249 &&& RepeatTillEnd(self.1).sp_roundtrip_inv()
250 &&& disjoint_domains(self.1, EOC)
251 }
252
253 proof fn theorem_serialize_dps_parse_roundtrip(&self, value: Self::T, obuf: Seq<u8>) {
254 ber_sequence_of_fmt(self.0, self.1).theorem_serialize_dps_parse_roundtrip(value, obuf);
255 }
256 }
257
258}
259
260#[cfg(feature = "alloc")]
261impl<'i, C> Parser<&'i [u8]> for BerSequenceOfFmt<C> where
262 C: SpecCombinator + Parser<&'i [u8]> + Productive + Copy,
263 {
264 type PT = Vec<C::PT>;
265
266 open spec fn exec_inv(&self) -> bool {
267 &&& self.1.exec_inv()
268 &&& self.1.safe_inv()
269 &&& self.1.productive_inv()
270 }
271
272 fn parse(&self, ibuf: &&'i [u8]) -> PResult<Self::PT> {
273 broadcast use crate::core::spec::SafeParser::lemma_parse_safe;
274 broadcast use crate::asn1::tag::lemma_const_tag_fmt_exec_inv;
275
276 let _ = ibuf.len();
277 let (tag_len, _tag) = Const(TagFmt, self.0).parse(ibuf)?;
278 let after_tag = ibuf.skip(tag_len);
279 let (length_len, length) = BerLengthFmt.parse(&after_tag)?;
280 let content = after_tag.skip(length_len);
281
282 let (content_len, values) = match length {
283 BerLength::Definite(len) => {
284 let exact = ExactLen(len, RepeatTillEnd(self.1));
285 exact.parse(&content)?
286 },
287 BerLength::Indefinite => {
288 let repeated = Repeat(self.1, EOC);
289 proof {
290 crate::core::exec::bridge_lemmas::lemma_pair_parser_exec_inv::<&'i [u8], _, _>(
291 &EOC,
292 );
293 crate::core::exec::bridge_lemmas::lemma_repeat_parser_exec_inv::<
294 &'i [u8],
295 _,
296 _,
297 >(&repeated);
298 }
299 parse_discard_eoc(&repeated, &content)?
300 },
301 };
302 let total = tag_len + length_len + content_len;
303 assert(self.spec_parse(ibuf@) == Some((total as int, values.deep_view())));
304 Ok((total, values))
305 }
306}
307
308impl<Output: OutputBuf, C, T> Serializer<Output, &[T]> for BerSequenceOfFmt<C> where
309 C: SpecCombinator + Serializer<Output, T> + ByteLen<T> + Copy,
310 T: DeepView,
311 {
312 #[verifier::prophetic]
313 open spec fn exec_inv(&self) -> bool {
314 &&& <C as Serializer<Output, T>>::exec_inv(&self.1)
315 &&& <C as ByteLen<T>>::exec_inv(&self.1)
316 }
317
318 fn serialize_into(&self, value: &&[T], obuf: &mut Output) {
319 let normalized = ASN1Fmt::<_, BER>(self.0, RepeatTillEnd(self.1));
320 normalized.serialize_into(value, obuf);
321 }
322}
323
324impl<C, T> Prepare<&[T]> for BerSequenceOfFmt<C> where
325 C: SpecCombinator + Prepare<T> + Copy,
326 T: DeepView,
327 {
328 open spec fn exec_inv(&self) -> bool {
329 <C as Prepare<T>>::exec_inv(&self.1)
330 }
331
332 fn prepare(&self, value: &&[T]) -> Result<usize, PreSerializeError> {
333 let normalized = ASN1Fmt::<_, BER>(self.0, RepeatTillEnd(self.1));
334 normalized.prepare(value)
335 }
336}
337
338impl<C, T> ByteLen<&[T]> for BerSequenceOfFmt<C> where
339 C: SpecCombinator + ByteLen<T> + Copy,
340 T: DeepView,
341 {
342 open spec fn exec_inv(&self) -> bool {
343 <C as ByteLen<T>>::exec_inv(&self.1)
344 }
345
346 fn length(&self, value: &&[T]) -> usize {
347 let normalized = ASN1Fmt::<_, BER>(self.0, RepeatTillEnd(self.1));
348 normalized.length(value)
349 }
350}
351
352#[cfg(feature = "alloc")]
353impl<Output: OutputBuf, C, T> Serializer<Output, Vec<T>> for BerSequenceOfFmt<C> where
354 C: SpecCombinator + Serializer<Output, T> + ByteLen<T> + Copy,
355 T: DeepView,
356 {
357 #[verifier::prophetic]
358 open spec fn exec_inv(&self) -> bool {
359 &&& <C as Serializer<Output, T>>::exec_inv(&self.1)
360 &&& <C as ByteLen<T>>::exec_inv(&self.1)
361 }
362
363 fn serialize_into(&self, value: &Vec<T>, obuf: &mut Output) {
364 let normalized = ASN1Fmt::<_, BER>(self.0, RepeatTillEnd(self.1));
365 normalized.serialize_into(value, obuf);
366 }
367}
368
369#[cfg(feature = "alloc")]
370impl<C, T> Prepare<Vec<T>> for BerSequenceOfFmt<C> where
371 C: SpecCombinator + Prepare<T> + Copy,
372 T: DeepView,
373 {
374 open spec fn exec_inv(&self) -> bool {
375 <C as Prepare<T>>::exec_inv(&self.1)
376 }
377
378 fn prepare(&self, value: &Vec<T>) -> Result<usize, PreSerializeError> {
379 let normalized = ASN1Fmt::<_, BER>(self.0, RepeatTillEnd(self.1));
380 normalized.prepare(value)
381 }
382}
383
384#[cfg(feature = "alloc")]
385impl<C, T> ByteLen<Vec<T>> for BerSequenceOfFmt<C> where
386 C: SpecCombinator + ByteLen<T> + Copy,
387 T: DeepView,
388 {
389 open spec fn exec_inv(&self) -> bool {
390 <C as ByteLen<T>>::exec_inv(&self.1)
391 }
392
393 fn length(&self, value: &Vec<T>) -> usize {
394 let normalized = ASN1Fmt::<_, BER>(self.0, RepeatTillEnd(self.1));
395 normalized.length(value)
396 }
397}
398
399}