ore_rs/
ciphertext.rs

1use thiserror::Error;
2
3use crate::primitives::NONCE_SIZE;
4pub use crate::OreCipher;
5
6/// The trait of any encryption output (either Left, Right or combined).
7pub trait OreOutput: Sized {
8    /// The size (in bytes) of this encrypted value
9    fn size() -> usize;
10
11    /// Convert to bytes
12    fn to_bytes(&self) -> Vec<u8>;
13
14    /// Try to deserialize from a slice
15    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    /* Array of Left blocks of size N */
26    pub f: [S::LeftBlockType; N],
27
28    /* Transformed input array of size N (x̃ = π(F (k_2 , x|i−1 ), x_i )) */
29    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    /// Serialize the ciphertext into a vector of bytes
137    fn to_bytes(&self) -> Vec<u8> {
138        [self.left.to_bytes(), self.right.to_bytes()].concat()
139    }
140
141    /// Deserialize from a slice of bytes
142    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}