1use crate::error::{Error, Result};
4
5pub fn fill_random(buf: &mut [u8]) {
12 use rand_core::{OsRng, RngCore};
13 OsRng.fill_bytes(buf);
14}
15
16#[must_use]
18pub fn random_16() -> [u8; 16] {
19 let mut b = [0u8; 16];
20 fill_random(&mut b);
21 b
22}
23
24#[must_use]
30pub fn blake2b_256(data: &[u8]) -> [u8; 32] {
31 use blake2::digest::{Digest, consts::U32};
32 let mut h = blake2::Blake2b::<U32>::new();
33 h.update(data);
34 let out = h.finalize();
35 let mut r = [0u8; 32];
36 r.copy_from_slice(&out);
37 r
38}
39
40pub fn blake2b_256_reader<R: std::io::Read>(mut r: R) -> std::io::Result<[u8; 32]> {
48 use blake2::digest::{Digest, consts::U32};
49 let mut h = blake2::Blake2b::<U32>::new();
50 let mut buf = vec![0u8; 1 << 20];
51 loop {
52 let n = r.read(&mut buf)?;
53 if n == 0 {
54 break;
55 }
56 h.update(buf.get(..n).unwrap_or(&[]));
57 }
58 Ok(h.finalize().into())
59}
60
61pub struct Cursor<'a> {
65 data: &'a [u8],
66 pos: usize,
67 context: &'static str,
69}
70
71impl<'a> Cursor<'a> {
72 #[must_use]
74 pub const fn new(data: &'a [u8], context: &'static str) -> Self {
75 Self { data, pos: 0, context }
76 }
77
78 #[must_use]
80 pub const fn position(&self) -> usize {
81 self.pos
82 }
83
84 #[must_use]
86 pub const fn remaining(&self) -> usize {
87 self.data.len().saturating_sub(self.pos)
88 }
89
90 pub fn skip(&mut self, n: usize) -> Result<()> {
96 self.take(n).map(|_| ())
97 }
98
99 pub fn take(&mut self, n: usize) -> Result<&'a [u8]> {
105 let end = self.pos.checked_add(n).ok_or(Error::Truncated {
106 context: self.context,
107 need: n,
108 got: self.remaining(),
109 })?;
110 let s = self.data.get(self.pos..end).ok_or(Error::Truncated {
111 context: self.context,
112 need: n,
113 got: self.remaining(),
114 })?;
115 self.pos = end;
116 Ok(s)
117 }
118
119 pub fn take_array<const N: usize>(&mut self) -> Result<[u8; N]> {
125 let s = self.take(N)?;
126 let mut a = [0u8; N];
127 a.copy_from_slice(s);
128 Ok(a)
129 }
130
131 pub fn u8(&mut self) -> Result<u8> {
137 Ok(self.take_array::<1>()?[0])
138 }
139
140 pub fn u16le(&mut self) -> Result<u16> {
146 Ok(u16::from_le_bytes(self.take_array::<2>()?))
147 }
148
149 pub fn u32le(&mut self) -> Result<u32> {
155 Ok(u32::from_le_bytes(self.take_array::<4>()?))
156 }
157
158 pub fn u64le(&mut self) -> Result<u64> {
164 Ok(u64::from_le_bytes(self.take_array::<8>()?))
165 }
166}
167
168#[derive(Debug, Default)]
170pub struct Writer {
171 buf: Vec<u8>,
172}
173
174impl Writer {
175 #[must_use]
177 pub const fn new() -> Self {
178 Self { buf: Vec::new() }
179 }
180
181 #[must_use]
183 pub fn with_capacity(n: usize) -> Self {
184 Self { buf: Vec::with_capacity(n) }
185 }
186
187 #[must_use]
189 pub fn len(&self) -> usize {
190 self.buf.len()
191 }
192
193 #[must_use]
195 pub fn is_empty(&self) -> bool {
196 self.buf.is_empty()
197 }
198
199 pub fn bytes(&mut self, b: &[u8]) -> &mut Self {
201 self.buf.extend_from_slice(b);
202 self
203 }
204
205 pub fn u8(&mut self, v: u8) -> &mut Self {
207 self.buf.push(v);
208 self
209 }
210
211 pub fn u16le(&mut self, v: u16) -> &mut Self {
213 self.buf.extend_from_slice(&v.to_le_bytes());
214 self
215 }
216
217 pub fn u32le(&mut self, v: u32) -> &mut Self {
219 self.buf.extend_from_slice(&v.to_le_bytes());
220 self
221 }
222
223 pub fn u64le(&mut self, v: u64) -> &mut Self {
225 self.buf.extend_from_slice(&v.to_le_bytes());
226 self
227 }
228
229 pub fn zeros(&mut self, n: usize) -> &mut Self {
231 self.buf.resize(self.buf.len().saturating_add(n), 0);
232 self
233 }
234
235 pub fn random(&mut self, n: usize) -> &mut Self {
240 let start = self.buf.len();
241 self.buf.resize(start.saturating_add(n), 0);
242 if let Some(tail) = self.buf.get_mut(start..) {
243 fill_random(tail);
244 }
245 self
246 }
247
248 pub fn pad_to(&mut self, total: usize) -> Result<&mut Self> {
254 if self.buf.len() > total {
255 return Err(Error::MalformedHeader { reason: "field overflow while padding" });
256 }
257 self.buf.resize(total, 0);
258 Ok(self)
259 }
260
261 #[must_use]
263 pub fn into_vec(self) -> Vec<u8> {
264 self.buf
265 }
266
267 #[must_use]
269 pub fn as_slice(&self) -> &[u8] {
270 &self.buf
271 }
272}