1use thiserror::Error;
2
3use crate::primitives::NONCE_SIZE;
4pub use crate::OreCipher;
5
6pub trait OreOutput: Sized {
8 fn size() -> usize;
10
11 fn to_bytes(&self) -> Vec<u8>;
13
14 fn from_slice(data: &[u8]) -> Result<Self, ParseError>;
16
17 #[deprecated(since = "0.8.0", note = "please use `from_slice` instead")]
19 fn from_bytes(data: &[u8]) -> Result<Self, ParseError> {
20 Self::from_slice(data)
21 }
22}
23
24#[derive(Debug, Copy, Clone)]
28pub struct Left<S: OreCipher, const N: usize> {
29 pub f: [S::LeftBlockType; N],
31
32 pub xt: [u8; N],
34}
35
36#[derive(Debug, Copy, Clone)]
40pub struct Right<S: OreCipher, const N: usize> {
41 pub nonce: [u8; NONCE_SIZE],
43 pub data: [S::RightBlockType; N],
45}
46
47#[derive(Debug, Copy, Clone)]
49pub struct CipherText<S: OreCipher, const N: usize> {
50 pub left: Left<S, N>,
52 pub right: Right<S, N>,
54}
55
56pub trait CipherTextBlock: Default + Copy + std::fmt::Debug {
60 const BLOCK_SIZE: usize;
62
63 fn to_bytes(self) -> Vec<u8>;
65
66 fn from_bytes(data: &[u8]) -> Result<Self, ParseError>;
69
70 fn default_in_place(&mut self);
72}
73
74#[derive(Debug, Error)]
77#[error("Unable to parse ORE Ciphertext")]
78pub struct ParseError;
79
80impl<S: OreCipher, const N: usize> Left<S, N> {
81 pub(crate) fn init() -> Self {
82 Self {
83 xt: [0; N],
84 f: [S::LeftBlockType::default(); N],
85 }
86 }
87}
88
89impl<S: OreCipher, const N: usize> OreOutput for Left<S, N> {
90 fn size() -> usize {
91 N * (S::LeftBlockType::BLOCK_SIZE + 1)
92 }
93
94 fn to_bytes(&self) -> Vec<u8> {
95 let mut vec = Vec::with_capacity(N * S::LeftBlockType::BLOCK_SIZE);
96 self.f
97 .iter()
98 .for_each(|&block| vec.append(&mut block.to_bytes()));
99
100 [self.xt.to_vec(), vec].concat()
101 }
102
103 fn from_slice(data: &[u8]) -> Result<Self, ParseError> {
104 let mut out = Self::init();
105 out.xt.copy_from_slice(&data[0..N]);
106 for i in 0..N {
107 let block_start_index = N + (i * S::LeftBlockType::BLOCK_SIZE);
108 out.f[i] = S::LeftBlockType::from_bytes(
109 &data[block_start_index..(block_start_index + S::LeftBlockType::BLOCK_SIZE)],
110 )?;
111 }
112
113 Ok(out)
114 }
115}
116
117impl<S: OreCipher, const N: usize> Right<S, N> {
118 pub(crate) fn init() -> Self {
119 Self {
120 nonce: Default::default(),
121 data: [Default::default(); N],
122 }
123 }
124}
125
126impl<S: OreCipher, const N: usize> OreOutput for Right<S, N> {
127 fn size() -> usize {
128 (N * S::RightBlockType::BLOCK_SIZE) + NONCE_SIZE
129 }
130
131 fn to_bytes(&self) -> Vec<u8> {
132 let mut vec = Vec::with_capacity(N * S::RightBlockType::BLOCK_SIZE);
133 self.data
134 .iter()
135 .for_each(|&block| vec.append(&mut block.to_bytes()));
136
137 [self.nonce.to_vec(), vec].concat()
138 }
139
140 fn from_slice(data: &[u8]) -> Result<Self, ParseError> {
141 let mut out = Self::init();
142 out.nonce.copy_from_slice(&data[0..NONCE_SIZE]);
143 for i in 0..N {
144 let block_start_index = NONCE_SIZE + (i * S::RightBlockType::BLOCK_SIZE);
145 out.data[i] = S::RightBlockType::from_bytes(
146 &data[block_start_index..(block_start_index + S::RightBlockType::BLOCK_SIZE)],
147 )?;
148 }
149 Ok(out)
150 }
151}
152
153impl<S: OreCipher, const N: usize> OreOutput for CipherText<S, N> {
154 fn size() -> usize {
155 Left::<S, N>::size() + Right::<S, N>::size()
156 }
157
158 fn to_bytes(&self) -> Vec<u8> {
160 [self.left.to_bytes(), self.right.to_bytes()].concat()
161 }
162
163 fn from_slice(data: &[u8]) -> Result<Self, ParseError> {
165 if data.len() != (Left::<S, N>::size() + Right::<S, N>::size()) {
166 return Err(ParseError);
167 }
168 let (left, right) = data.split_at(Left::<S, N>::size());
169 let left = Left::<S, N>::from_slice(left)?;
170 let right = Right::<S, N>::from_slice(right)?;
171
172 Ok(Self { left, right })
173 }
174}