verdict_parser/asn1/
integer.rs1use super::*;
2use vstd::prelude::*;
3
4verus! {
5
6#[derive(Debug, View)]
10pub struct Integer;
11
12asn1_tagged!(Integer, tag_of!(INTEGER));
13
14pub type IntegerValue = VarIntResult;
15
16impl SpecCombinator for Integer {
17 type SpecResult = IntegerValue;
18
19 closed spec fn spec_parse(&self, s: Seq<u8>) -> Result<(usize, Self::SpecResult), ()> {
22 match new_spec_integer_inner().spec_parse(s) {
23 Ok((len, (n, v))) => {
24 if is_min_num_bytes_signed(v, n as VarUIntResult) {
25 Ok((len, v))
26 } else {
27 Err(())
28 }
29 }
30 Err(..) => Err(()),
31 }
32 }
33
34 proof fn spec_parse_wf(&self, s: Seq<u8>) {
35 new_spec_integer_inner().spec_parse_wf(s);
36 }
37
38 closed spec fn spec_serialize(&self, v: Self::SpecResult) -> Result<Seq<u8>, ()> {
39 new_spec_integer_inner().spec_serialize((min_num_bytes_signed(v) as LengthValue, v))
40 }
41}
42
43impl SecureSpecCombinator for Integer {
44 open spec fn is_prefix_secure() -> bool {
45 true
46 }
47
48 proof fn theorem_serialize_parse_roundtrip(&self, v: Self::SpecResult) {
49 new_spec_integer_inner().theorem_serialize_parse_roundtrip((min_num_bytes_signed(v) as LengthValue, v));
50 lemma_min_num_bytes_signed(v);
51 }
52
53 proof fn theorem_parse_serialize_roundtrip(&self, buf: Seq<u8>) {
54 new_spec_integer_inner().theorem_parse_serialize_roundtrip(buf);
55
56 if let Ok((_, (n, v))) = new_spec_integer_inner().spec_parse(buf) {
57 lemma_min_num_bytes_signed(v);
58 }
59 }
60
61 proof fn lemma_prefix_secure(&self, s1: Seq<u8>, s2: Seq<u8>) {
62 new_spec_integer_inner().lemma_prefix_secure(s1, s2);
63 }
64}
65
66impl Combinator for Integer {
67 type Result<'a> = IntegerValue;
68 type Owned = IntegerValue;
69
70 closed spec fn spec_length(&self) -> Option<usize> {
71 None
72 }
73
74 fn length(&self) -> Option<usize> {
75 None
76 }
77
78 #[inline(always)]
79 fn parse<'a>(&self, s: &'a [u8]) -> (res: Result<(usize, Self::Result<'a>), ParseError>) {
80 let (len, (n, v)) = new_integer_inner().parse(s)?;
81
82 if is_min_num_bytes_signed_exec(v, n as VarUIntResult) {
83 Ok((len, v))
84 } else {
85 Err(ParseError::Other("Non-minimal integer encoding".to_string()))
86 }
87 }
88
89 #[inline(always)]
90 fn serialize(&self, v: Self::Result<'_>, data: &mut Vec<u8>, pos: usize) -> (res: Result<usize, SerializeError>) {
91 proof {
92 lemma_min_num_bytes_signed(v);
93 }
94 new_integer_inner().serialize((min_num_bytes_signed_exec(v) as LengthValue, v), data, pos)
95 }
96}
97
98struct IntegerCont;
101
102impl Continuation for IntegerCont {
103 type Input<'a> = LengthValue;
104 type Output = VarInt;
105
106 #[inline(always)]
107 fn apply<'a>(&self, i: Self::Input<'a>) -> (o: Self::Output) {
108 VarInt(i as usize)
109 }
110
111 closed spec fn requires<'a>(&self, i: Self::Input<'a>) -> bool {
112 true
113 }
114
115 closed spec fn ensures<'a>(&self, i: Self::Input<'a>, o: Self::Output) -> bool {
116 o == VarInt(i as usize)
117 }
118}
119
120#[allow(dead_code)]
123type SpecIntegerInner = SpecDepend<Length, VarInt>;
124type IntegerInner = Depend<Length, VarInt, IntegerCont>;
125
126closed spec fn new_spec_integer_inner() -> SpecIntegerInner {
127 let ghost spec_snd = |l| {
128 VarInt(l as usize)
129 };
130
131 SpecDepend {
132 fst: Length,
133 snd: spec_snd,
134 }
135}
136
137#[inline(always)]
138fn new_integer_inner() -> (res: IntegerInner)
139 ensures res.view() == new_spec_integer_inner()
140{
141 let ghost spec_snd = |l| {
142 VarInt(l as usize)
143 };
144
145 Depend {
146 fst: Length,
147 snd: IntegerCont,
148 spec_snd: Ghost(spec_snd),
149 }
150}
151
152}
153
154#[cfg(test)]
155mod test {
156 use super::*;
157 use der::Encode;
158
159 #[test]
160 fn parse() {
161 assert_eq!(Integer.parse(&[0x01, 0x00]).unwrap(), (2, 0));
162 assert_eq!(Integer.parse(&[0x01, 0xff]).unwrap(), (2, -1));
163 assert_eq!(Integer.parse(&[0x02, 0x00, 0xff]).unwrap(), (3, 0xff));
164
165 assert!(Integer.parse(&[0x00]).is_err());
166 assert!(Integer.parse(&[0x81, 0x01, 0xff]).is_err());
167 assert!(Integer.parse(&[0x02, 0x00, 0x7f]).is_err()); }
169
170 fn serialize_int(v: IntegerValue) -> Result<Vec<u8>, SerializeError> {
171 let mut data = vec![0; 16];
172 let len = ASN1(Integer).serialize(v, &mut data, 0)?;
173 data.truncate(len);
174 Ok(data)
175 }
176
177 #[test]
179 fn diff_with_der() {
180 let diff = |i| {
181 let res1 = serialize_int(i).map_err(|_| ());
182 let res2 = i.to_der().map_err(|_| ());
183 assert_eq!(res1, res2);
184 };
185
186 diff(0);
187 diff(i64::MAX);
188 diff(i64::MIN);
189
190 for i in 0..65535i64 {
191 diff(i);
192 }
193
194 for i in -65535i64..0 {
195 diff(i);
196 }
197 }
198}