crypto_permutation/io.rs
1//! Reader and writer traits to generalise over writing to and reading from
2//! buffers in memory and cryptographic constructions which take variable length
3//! input or generate variable length output.
4
5mod util;
6pub use util::check_write_size;
7
8// `Reader` and `Writer` implementations:
9#[cfg(feature = "io_le_uint_slice")]
10pub mod le_uint_slice_reader;
11#[cfg(feature = "io_le_uint_slice")]
12pub mod le_uint_slice_writer;
13
14use crate::buffer::BufMut;
15
16/// Requested a write larger than `self.capacity()`.
17#[derive(Debug, Clone)]
18pub struct WriteTooLargeError {
19 /// Length of write request in bytes.
20 pub requested: usize,
21 /// Capacity in bytes that is left.
22 pub capacity: usize,
23}
24
25impl core::fmt::Display for WriteTooLargeError {
26 fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
27 write!(
28 fmt,
29 "Requested a write of size {} but writer has only {} bytes capacity left",
30 self.requested, self.capacity
31 )
32 }
33}
34
35#[cfg(feature = "std")]
36impl std::error::Error for WriteTooLargeError {}
37
38/// An object to which bytes can be written.
39///
40/// Writes may be buffered, so it is required to call [`Self::finish`] to flush
41/// pending writes. Using a [`Writer`] and dropping it afterwards instead of
42/// calling [`Self::finish`] on it is a logic error.
43pub trait Writer {
44 /// Optional return type for the [`Self::finish`] method.
45 type Return;
46
47 /// Return the number of bytes that can still be written to `self`.
48 ///
49 /// When the writer has infinite capacity then `usize::MAX` is returned.
50 fn capacity(&self) -> usize;
51
52 /// Skip over `len` bytes. If skipping over bytes is not meaningful for the
53 /// buffer then this is a no-op.
54 ///
55 /// # Errors
56 /// Errors when `len > self.capacity()`.
57 fn skip(&mut self, len: usize) -> Result<(), WriteTooLargeError>;
58
59 /// Write `data.len()` bytes to the buffer.
60 ///
61 /// # Errors
62 /// Errors when `data.len() > self.capacity()`.
63 fn write_bytes(&mut self, data: &[u8]) -> Result<(), WriteTooLargeError>;
64
65 /// Flush any pending/buffered writes and optionally return something.
66 ///
67 /// If the buffer must initialise leftover bytes it will set them to zero.
68 fn finish(self) -> Self::Return;
69}
70
71/// An object from which bytes can be read.
72pub trait Reader {
73 /// Return the number of bytes that can still be read from `self`.
74 ///
75 /// When the reader can generate arbitrary long output streams, `usize::MAX`
76 /// is returned.
77 fn capacity(&self) -> usize;
78
79 /// Skip over `len` bytes.
80 ///
81 /// # Errors
82 /// Errors when `len > self.capacity()`.
83 fn skip(&mut self, len: usize) -> Result<(), WriteTooLargeError>;
84
85 /// Write `n` bytes to `writer`.
86 ///
87 /// # Errors
88 /// Errors when `n` exceeds reader or writer capacity.
89 fn write_to<W: Writer>(&mut self, writer: &mut W, n: usize) -> Result<(), WriteTooLargeError>;
90
91 /// Write `buf.len()` bytes of data into `buf`.
92 ///
93 /// # Errors
94 /// Errors when `buf.len()` exceeds reader capacity.
95 fn write_to_buf(&mut self, mut buf: BufMut<'_>) -> Result<(), WriteTooLargeError> {
96 let len = buf.len();
97 self.write_to(&mut buf, len)
98 }
99
100 /// Write `buf.len()` bytes of data into `buf`.
101 ///
102 /// # Errors
103 /// Errors when `buf.len()` exceeds reader capacity.
104 fn write_to_slice(&mut self, buf: &mut [u8]) -> Result<(), WriteTooLargeError> {
105 self.write_to_buf(buf.into())
106 }
107}
108
109/// Marker trait to indicate that the output of a [`Reader`] can be considered
110/// to be pseudo random.
111pub trait CryptoReader: Reader {}