verdict_parser/asn1/
big_int.rs1use super::*;
2use std::fmt::{self, Debug, Formatter};
3use vstd::prelude::*;
4
5verus! {
6
7#[derive(Debug, View)]
11pub struct BigInt;
12
13asn1_tagged!(BigInt, tag_of!(INTEGER));
14
15pub type SpecBigIntValue = Seq<u8>;
18pub struct BigIntValue<'a>(&'a [u8]);
19
20#[allow(dead_code)]
21pub struct BigIntOwned(Vec<u8>);
22
23impl<'a> View for BigIntValue<'a> {
24 type V = Seq<u8>;
25
26 closed spec fn view(&self) -> Self::V {
27 self.0@
28 }
29}
30
31impl<'a> PolyfillEq for BigIntValue<'a> {
32 #[inline(always)]
33 fn polyfill_eq(&self, other: &Self) -> bool {
34 self.0.polyfill_eq(&other.0)
35 }
36}
37
38impl View for BigIntOwned {
39 type V = Seq<u8>;
40
41 closed spec fn view(&self) -> Self::V {
42 self.0@
43 }
44}
45
46impl<'a> PolyfillClone for BigIntValue<'a> {
47 #[inline(always)]
48 fn clone(&self) -> Self {
49 proof {
50 use_type_invariant(self);
51 }
52 BigIntValue(&self.0)
53 }
54}
55
56impl<'a> BigIntValue<'a> {
57 #[verifier::type_invariant]
58 closed spec fn inv(self) -> bool {
59 Self::spec_wf(self@)
60 }
61
62 pub open spec fn spec_wf(bytes: Seq<u8>) -> bool {
67 &&& bytes.len() != 0
68 &&& bytes[0] == 0 ==> {
69 ||| bytes.len() == 1
70 ||| bytes[1] >= 0x80
72 }
73 }
74
75 #[inline(always)]
76 pub fn wf(bytes: &'a [u8]) -> (res: bool)
77 ensures res == BigIntValue::spec_wf(bytes@)
78 {
79 bytes.len() != 0 &&
80 (bytes[0] != 0 || bytes.len() == 1 || bytes[1] >= 0x80)
81 }
82
83 pub open spec fn spec_byte_len(&self) -> usize {
84 (self@.len() - 1) as usize
85 }
86
87 #[inline(always)]
89 pub fn byte_len(&self) -> (res: usize)
90 ensures res == self.spec_byte_len()
91 {
92 proof {
93 use_type_invariant(self);
94 }
95 self.0.len() - 1
96 }
97
98 #[inline(always)]
99 pub fn bytes(&self) -> (res: &[u8])
100 ensures res@ == self@
101 {
102 self.0
103 }
104
105 }
107
108impl SpecCombinator for BigInt {
109 type SpecResult = Seq<u8>;
110
111 closed spec fn spec_parse(&self, s: Seq<u8>) -> Result<(usize, Self::SpecResult), ()> {
112 new_spec_big_int_inner().spec_parse(s)
113 }
114
115 proof fn spec_parse_wf(&self, s: Seq<u8>) {
116 new_spec_big_int_inner().spec_parse_wf(s)
117 }
118
119 closed spec fn spec_serialize(&self, v: Self::SpecResult) -> Result<Seq<u8>, ()> {
120 new_spec_big_int_inner().spec_serialize(v)
121 }
122}
123
124impl SecureSpecCombinator for BigInt {
125 open spec fn is_prefix_secure() -> bool {
126 true
127 }
128
129 proof fn theorem_serialize_parse_roundtrip(&self, v: Self::SpecResult) {
130 new_spec_big_int_inner().theorem_serialize_parse_roundtrip(v);
131 }
132
133 proof fn theorem_parse_serialize_roundtrip(&self, buf: Seq<u8>) {
134 new_spec_big_int_inner().theorem_parse_serialize_roundtrip(buf);
135 }
136
137 proof fn lemma_prefix_secure(&self, s1: Seq<u8>, s2: Seq<u8>) {
138 new_spec_big_int_inner().lemma_prefix_secure(s1, s2);
139 }
140}
141
142impl Combinator for BigInt {
143 type Result<'a> = BigIntValue<'a>;
144 type Owned = BigIntOwned;
145
146 open spec fn spec_length(&self) -> Option<usize> {
147 None
148 }
149
150 fn length(&self) -> Option<usize> {
151 None
152 }
153
154 #[inline(always)]
155 fn parse<'a>(&self, s: &'a [u8]) -> (res: Result<(usize, Self::Result<'a>), ParseError>) {
156 let (len, v) = new_big_int_inner().parse(s)?;
157 Ok((len, BigIntValue(v)))
158 }
159
160 #[inline(always)]
161 fn serialize(&self, v: Self::Result<'_>, data: &mut Vec<u8>, pos: usize) -> (res: Result<usize, SerializeError>) {
162 new_big_int_inner().serialize(v.0, data, pos)
163 }
164}
165
166#[derive(View)]
168pub struct MinimalBigIntPred;
169
170impl SpecPred for MinimalBigIntPred {
171 type Input = Seq<u8>;
172
173 closed spec fn spec_apply(&self, i: &Self::Input) -> bool {
174 BigIntValue::spec_wf(*i)
175 }
176}
177
178impl Pred for MinimalBigIntPred {
179 type Input<'a> = &'a [u8];
180 type InputOwned = Vec<u8>;
181
182 fn apply(&self, i: &Self::Input<'_>) -> (res: bool)
183 {
184 BigIntValue::wf(i)
185 }
186}
187
188type BigIntInner = Refined<OctetString, MinimalBigIntPred>;
189
190pub closed spec fn new_spec_big_int_inner() -> BigIntInner
191{
192 Refined {
193 inner: OctetString,
194 predicate: MinimalBigIntPred,
195 }
196}
197
198#[inline(always)]
199fn new_big_int_inner() -> (res: BigIntInner)
200 ensures res@ == new_spec_big_int_inner()
201{
202 Refined {
203 inner: OctetString,
204 predicate: MinimalBigIntPred,
205 }
206}
207
208}
209
210impl<'a> Debug for BigIntValue<'a> {
211 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
212 write!(f, "BigIntValue(0x")?;
214 for b in self.0 {
215 write!(f, "{:02x}", b)?;
216 }
217 write!(f, ")")
218 }
219}