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")]
18 fn from_bytes(data: &[u8]) -> Result<Self, ParseError> {
19 Self::from_slice(data)
20 }
21}
22
23#[derive(Debug, Copy, Clone)]
24pub struct Left<S: OreCipher, const N: usize> {
25 pub f: [S::LeftBlockType; N],
27
28 pub xt: [u8; N],
30}
31
32#[derive(Debug, Copy, Clone)]
33pub struct Right<S: OreCipher, const N: usize> {
34 pub nonce: [u8; NONCE_SIZE],
35 pub data: [S::RightBlockType; N],
36}
37
38#[derive(Debug, Copy, Clone)]
39pub struct CipherText<S: OreCipher, const N: usize> {
40 pub left: Left<S, N>,
41 pub right: Right<S, N>,
42}
43
44pub trait CipherTextBlock: Default + Copy + std::fmt::Debug {
45 const BLOCK_SIZE: usize;
46
47 fn to_bytes(self) -> Vec<u8>;
48
49 fn from_bytes(data: &[u8]) -> Result<Self, ParseError>;
50
51 fn default_in_place(&mut self);
52}
53
54#[derive(Debug, Error)]
55#[error("Unable to parse ORE Ciphertext")]
56pub struct ParseError;
57
58impl<S: OreCipher, const N: usize> Left<S, N> {
59 pub(crate) fn init() -> Self {
60 Self {
61 xt: [0; N],
62 f: [S::LeftBlockType::default(); N],
63 }
64 }
65}
66
67impl<S: OreCipher, const N: usize> OreOutput for Left<S, N> {
68 fn size() -> usize {
69 N * (S::LeftBlockType::BLOCK_SIZE + 1)
70 }
71
72 fn to_bytes(&self) -> Vec<u8> {
73 let mut vec = Vec::with_capacity(N * S::LeftBlockType::BLOCK_SIZE);
74 self.f
75 .iter()
76 .for_each(|&block| vec.append(&mut block.to_bytes()));
77
78 [self.xt.to_vec(), vec].concat()
79 }
80
81 fn from_slice(data: &[u8]) -> Result<Self, ParseError> {
82 let mut out = Self::init();
83 out.xt.copy_from_slice(&data[0..N]);
84 for i in 0..N {
85 let block_start_index = N + (i * S::LeftBlockType::BLOCK_SIZE);
86 out.f[i] = S::LeftBlockType::from_bytes(
87 &data[block_start_index..(block_start_index + S::LeftBlockType::BLOCK_SIZE)],
88 )?;
89 }
90
91 Ok(out)
92 }
93}
94
95impl<S: OreCipher, const N: usize> Right<S, N> {
96 pub(crate) fn init() -> Self {
97 Self {
98 nonce: Default::default(),
99 data: [Default::default(); N],
100 }
101 }
102}
103
104impl<S: OreCipher, const N: usize> OreOutput for Right<S, N> {
105 fn size() -> usize {
106 (N * S::RightBlockType::BLOCK_SIZE) + NONCE_SIZE
107 }
108
109 fn to_bytes(&self) -> Vec<u8> {
110 let mut vec = Vec::with_capacity(N * S::RightBlockType::BLOCK_SIZE);
111 self.data
112 .iter()
113 .for_each(|&block| vec.append(&mut block.to_bytes()));
114
115 [self.nonce.to_vec(), vec].concat()
116 }
117
118 fn from_slice(data: &[u8]) -> Result<Self, ParseError> {
119 let mut out = Self::init();
120 out.nonce.copy_from_slice(&data[0..NONCE_SIZE]);
121 for i in 0..N {
122 let block_start_index = NONCE_SIZE + (i * S::RightBlockType::BLOCK_SIZE);
123 out.data[i] = S::RightBlockType::from_bytes(
124 &data[block_start_index..(block_start_index + S::RightBlockType::BLOCK_SIZE)],
125 )?;
126 }
127 Ok(out)
128 }
129}
130
131impl<S: OreCipher, const N: usize> OreOutput for CipherText<S, N> {
132 fn size() -> usize {
133 Left::<S, N>::size() + Right::<S, N>::size()
134 }
135
136 fn to_bytes(&self) -> Vec<u8> {
138 [self.left.to_bytes(), self.right.to_bytes()].concat()
139 }
140
141 fn from_slice(data: &[u8]) -> Result<Self, ParseError> {
143 if data.len() != (Left::<S, N>::size() + Right::<S, N>::size()) {
144 return Err(ParseError);
145 }
146 let (left, right) = data.split_at(Left::<S, N>::size());
147 let left = Left::<S, N>::from_slice(left)?;
148 let right = Right::<S, N>::from_slice(right)?;
149
150 Ok(Self { left, right })
151 }
152}