define size of layered encryption data as const
This commit is contained in:
parent
6fa207167c
commit
30eefbbe57
@ -53,8 +53,8 @@ pub struct ConsistentLengthLayeredCipher<D> {
|
|||||||
pub trait ConsistentLengthLayeredCipherData {
|
pub trait ConsistentLengthLayeredCipherData {
|
||||||
// Returns the serialized bytes for an instance of the implementing type
|
// Returns the serialized bytes for an instance of the implementing type
|
||||||
fn to_bytes(&self) -> Vec<u8>;
|
fn to_bytes(&self) -> Vec<u8>;
|
||||||
// Returns the size of the serialized data. This is a static method.
|
// The size of the serialized data.
|
||||||
fn size() -> usize;
|
const SIZE: usize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A parameter for one layer of encryption
|
/// A parameter for one layer of encryption
|
||||||
@ -84,14 +84,12 @@ impl<D: ConsistentLengthLayeredCipherData> ConsistentLengthLayeredCipher<D> {
|
|||||||
/// The total size of fully encrypted output that includes all layers.
|
/// The total size of fully encrypted output that includes all layers.
|
||||||
/// This size is determined by [`D::size`] and [`Self::max_layers`].
|
/// This size is determined by [`D::size`] and [`Self::max_layers`].
|
||||||
pub fn total_size(&self) -> usize {
|
pub fn total_size(&self) -> usize {
|
||||||
Self::single_layer_size() * self.max_layers
|
Self::SINGLE_LAYER_SIZE * self.max_layers
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The size of a single layer that contains a data and a MAC.
|
/// The size of a single layer that contains a data and a MAC.
|
||||||
/// The MAC is used to verify integrity of the encrypted next layer.
|
/// The MAC is used to verify integrity of the encrypted next layer.
|
||||||
fn single_layer_size() -> usize {
|
const SINGLE_LAYER_SIZE: usize = D::SIZE + HEADER_INTEGRITY_MAC_SIZE;
|
||||||
D::size() + HEADER_INTEGRITY_MAC_SIZE
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Perform the layered encryption.
|
/// Perform the layered encryption.
|
||||||
pub fn encrypt(&self, params: &[EncryptionParam<D>]) -> Result<(Vec<u8>, HeaderIntegrityMac)> {
|
pub fn encrypt(&self, params: &[EncryptionParam<D>]) -> Result<(Vec<u8>, HeaderIntegrityMac)> {
|
||||||
@ -124,7 +122,7 @@ impl<D: ConsistentLengthLayeredCipherData> ConsistentLengthLayeredCipher<D> {
|
|||||||
next_mac.as_bytes(),
|
next_mac.as_bytes(),
|
||||||
// Truncate last bytes for the length-preserved decryption later.
|
// Truncate last bytes for the length-preserved decryption later.
|
||||||
// They will be restored by a filler during the decryption process.
|
// They will be restored by a filler during the decryption process.
|
||||||
&next_encrypted_data[..next_encrypted_data.len() - Self::single_layer_size()],
|
&next_encrypted_data[..next_encrypted_data.len() - Self::SINGLE_LAYER_SIZE],
|
||||||
)
|
)
|
||||||
.copied()
|
.copied()
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
@ -160,7 +158,7 @@ impl<D: ConsistentLengthLayeredCipherData> ConsistentLengthLayeredCipher<D> {
|
|||||||
// because there is no next encrypted layer.
|
// because there is no next encrypted layer.
|
||||||
// Instead, random bytes are used to fill the space between data and fillers.
|
// Instead, random bytes are used to fill the space between data and fillers.
|
||||||
// The size of random bytes depends on the [`self.max_layers`].
|
// The size of random bytes depends on the [`self.max_layers`].
|
||||||
let random_bytes = random_bytes(self.total_size() - D::size() - fillers.len());
|
let random_bytes = random_bytes(self.total_size() - D::SIZE - fillers.len());
|
||||||
|
|
||||||
// First, concat the data and the random bytes, and encrypt it.
|
// First, concat the data and the random bytes, and encrypt it.
|
||||||
let last_data = last_param.data.to_bytes();
|
let last_data = last_param.data.to_bytes();
|
||||||
@ -185,15 +183,14 @@ impl<D: ConsistentLengthLayeredCipherData> ConsistentLengthLayeredCipher<D> {
|
|||||||
/// Build as many fillers as the number of keys provided.
|
/// Build as many fillers as the number of keys provided.
|
||||||
/// Fillers are encrypted in accumulated manner by keys.
|
/// Fillers are encrypted in accumulated manner by keys.
|
||||||
fn build_fillers(&self, params: &[EncryptionParam<D>]) -> Vec<u8> {
|
fn build_fillers(&self, params: &[EncryptionParam<D>]) -> Vec<u8> {
|
||||||
let single_layer_size = Self::single_layer_size();
|
let mut fillers = vec![0u8; Self::SINGLE_LAYER_SIZE * params.len()];
|
||||||
let mut fillers = vec![0u8; single_layer_size * params.len()];
|
|
||||||
params
|
params
|
||||||
.iter()
|
.iter()
|
||||||
.map(|param| ¶m.key.stream_cipher_key)
|
.map(|param| ¶m.key.stream_cipher_key)
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.for_each(|(i, key)| {
|
.for_each(|(i, key)| {
|
||||||
self.apply_streamcipher(
|
self.apply_streamcipher(
|
||||||
&mut fillers[0..(i + 1) * single_layer_size],
|
&mut fillers[0..(i + 1) * Self::SINGLE_LAYER_SIZE],
|
||||||
key,
|
key,
|
||||||
StreamCipherOption::FromBack,
|
StreamCipherOption::FromBack,
|
||||||
)
|
)
|
||||||
@ -222,7 +219,7 @@ impl<D: ConsistentLengthLayeredCipherData> ConsistentLengthLayeredCipher<D> {
|
|||||||
let total_data_with_zero_filler = encrypted_total_data
|
let total_data_with_zero_filler = encrypted_total_data
|
||||||
.iter()
|
.iter()
|
||||||
.copied()
|
.copied()
|
||||||
.chain(std::iter::repeat(0u8).take(Self::single_layer_size()))
|
.chain(std::iter::repeat(0u8).take(Self::SINGLE_LAYER_SIZE))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
// Decrypt the extended data.
|
// Decrypt the extended data.
|
||||||
@ -236,7 +233,7 @@ impl<D: ConsistentLengthLayeredCipherData> ConsistentLengthLayeredCipher<D> {
|
|||||||
// Parse the decrypted data into 3 parts: data, MAC, and the next encrypted data.
|
// Parse the decrypted data into 3 parts: data, MAC, and the next encrypted data.
|
||||||
let parsed = parse_bytes(
|
let parsed = parse_bytes(
|
||||||
&decrypted,
|
&decrypted,
|
||||||
&[D::size(), HEADER_INTEGRITY_MAC_SIZE, self.total_size()],
|
&[D::SIZE, HEADER_INTEGRITY_MAC_SIZE, self.total_size()],
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let data = parsed[0].to_vec();
|
let data = parsed[0].to_vec();
|
||||||
@ -249,7 +246,7 @@ impl<D: ConsistentLengthLayeredCipherData> ConsistentLengthLayeredCipher<D> {
|
|||||||
let pseudorandom_bytes = sphinx_packet::crypto::generate_pseudorandom_bytes(
|
let pseudorandom_bytes = sphinx_packet::crypto::generate_pseudorandom_bytes(
|
||||||
key,
|
key,
|
||||||
&STREAM_CIPHER_INIT_VECTOR,
|
&STREAM_CIPHER_INIT_VECTOR,
|
||||||
self.total_size() + Self::single_layer_size(),
|
self.total_size() + Self::SINGLE_LAYER_SIZE,
|
||||||
);
|
);
|
||||||
let pseudorandom_bytes = match opt {
|
let pseudorandom_bytes = match opt {
|
||||||
StreamCipherOption::FromFront => &pseudorandom_bytes[..data.len()],
|
StreamCipherOption::FromFront => &pseudorandom_bytes[..data.len()],
|
||||||
@ -338,8 +335,6 @@ mod tests {
|
|||||||
self.to_vec()
|
self.to_vec()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn size() -> usize {
|
const SIZE: usize = 10;
|
||||||
10
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ impl RoutingInformation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_bytes(data: &[u8]) -> Result<Self, Error> {
|
pub fn from_bytes(data: &[u8]) -> Result<Self, Error> {
|
||||||
if data.len() != Self::size() {
|
if data.len() != Self::SIZE {
|
||||||
return Err(Error::InvalidEncryptedRoutingInfoLength(data.len()));
|
return Err(Error::InvalidEncryptedRoutingInfoLength(data.len()));
|
||||||
}
|
}
|
||||||
Ok(Self { flag: data[0] })
|
Ok(Self { flag: data[0] })
|
||||||
@ -40,9 +40,7 @@ impl ConsistentLengthLayeredCipherData for RoutingInformation {
|
|||||||
vec![self.flag]
|
vec![self.flag]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn size() -> usize {
|
const SIZE: usize = std::mem::size_of::<RoutingFlag>();
|
||||||
std::mem::size_of::<RoutingFlag>()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Encrypted routing information that will be contained in a packet header.
|
/// Encrypted routing information that will be contained in a packet header.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user