use crate::fragment::{
Fragment, LINKED_FRAGMENTED_HEADER_LEN, UNLINKED_FRAGMENTED_HEADER_LEN,
linked_fragment_payload_max_len, unlinked_fragment_payload_max_len,
};
use rand::Rng;
pub const fn max_unlinked_set_payload_length(max_plaintext_size: usize) -> usize {
u8::MAX as usize * unlinked_fragment_payload_max_len(max_plaintext_size)
}
pub const fn max_one_way_linked_set_payload_length(max_plaintext_size: usize) -> usize {
max_unlinked_set_payload_length(max_plaintext_size)
- (LINKED_FRAGMENTED_HEADER_LEN - UNLINKED_FRAGMENTED_HEADER_LEN)
}
pub const fn two_way_linked_set_payload_length(max_plaintext_size: usize) -> usize {
max_unlinked_set_payload_length(max_plaintext_size)
- 2 * (LINKED_FRAGMENTED_HEADER_LEN - UNLINKED_FRAGMENTED_HEADER_LEN)
}
pub(crate) type FragmentSet = Vec<Fragment>;
pub(crate) fn generate_set_id<R: Rng>(rng: &mut R) -> i32 {
let potential_id = rng.r#gen::<i32>();
if potential_id == 0 || potential_id == i32::MIN {
generate_set_id(rng)
} else {
potential_id.abs()
}
}
fn prepare_unlinked_fragmented_set(
message: &[u8],
id: i32,
max_plaintext_size: usize,
) -> FragmentSet {
let pre_casted_frags = (message.len() as f64
/ unlinked_fragment_payload_max_len(max_plaintext_size) as f64)
.ceil() as usize;
debug_assert!(pre_casted_frags <= u8::MAX as usize);
let num_fragments = pre_casted_frags as u8;
let mut fragments = Vec::with_capacity(num_fragments as usize);
for i in 1..(pre_casted_frags + 1) {
let lb = (i - 1) * unlinked_fragment_payload_max_len(max_plaintext_size);
let ub = usize::min(
message.len(),
i * unlinked_fragment_payload_max_len(max_plaintext_size),
);
fragments.push(
Fragment::try_new(
&message[lb..ub],
id,
num_fragments,
i as u8,
None,
None,
max_plaintext_size,
)
.unwrap(),
)
}
fragments
}
fn prepare_linked_fragment_set(
message: &[u8],
id: i32,
previous_link_id: Option<i32>,
next_link_id: Option<i32>,
max_plaintext_size: usize,
) -> FragmentSet {
let num_frags_usize = if next_link_id.is_some() {
u8::MAX as usize
} else {
let tail_len = if message.len() >= linked_fragment_payload_max_len(max_plaintext_size) {
message.len() - linked_fragment_payload_max_len(max_plaintext_size)
} else {
0
};
let pre_casted_frags = 1
+ (tail_len as f64 / unlinked_fragment_payload_max_len(max_plaintext_size) as f64)
.ceil() as usize;
if pre_casted_frags > u8::MAX as usize {
panic!("message would produce too many fragments!")
};
pre_casted_frags
};
let mut lb = 0;
let mut ub = if previous_link_id.is_some() {
usize::min(
message.len(),
linked_fragment_payload_max_len(max_plaintext_size),
)
} else {
unlinked_fragment_payload_max_len(max_plaintext_size)
};
let mut fragments = Vec::with_capacity(num_frags_usize);
for i in 1..(num_frags_usize + 1) {
let fragment = Fragment::try_new(
&message[lb..ub],
id,
num_frags_usize as u8,
i as u8,
if i == 1 { previous_link_id } else { None },
if i == num_frags_usize {
next_link_id
} else {
None
},
max_plaintext_size,
)
.unwrap();
fragments.push(fragment);
lb = ub;
ub = usize::min(
message.len(),
ub + unlinked_fragment_payload_max_len(max_plaintext_size),
);
}
fragments
}
pub(crate) fn total_number_of_sets(message_len: usize, max_plaintext_size: usize) -> usize {
if message_len <= max_unlinked_set_payload_length(max_plaintext_size) {
1
} else if message_len > max_unlinked_set_payload_length(max_plaintext_size)
&& message_len <= 2 * max_one_way_linked_set_payload_length(max_plaintext_size)
{
2
} else {
let len_without_edges =
message_len - 2 * max_one_way_linked_set_payload_length(max_plaintext_size);
(len_without_edges as f64 / two_way_linked_set_payload_length(max_plaintext_size) as f64)
.ceil() as usize
+ 2
}
}
fn prepare_fragment_set(
message: &[u8],
id: i32,
previous_link_id: Option<i32>,
next_link_id: Option<i32>,
max_plaintext_size: usize,
) -> FragmentSet {
if previous_link_id.is_some() || next_link_id.is_some() {
prepare_linked_fragment_set(
message,
id,
previous_link_id,
next_link_id,
max_plaintext_size,
)
} else {
prepare_unlinked_fragmented_set(message, id, max_plaintext_size)
}
}
pub fn split_into_sets<R: Rng>(
rng: &mut R,
message: &[u8],
max_plaintext_size: usize,
) -> Vec<FragmentSet> {
let num_of_sets = total_number_of_sets(message.len(), max_plaintext_size);
if num_of_sets == 1 {
let set_id = generate_set_id(rng);
vec![prepare_fragment_set(
message,
set_id,
None,
None,
max_plaintext_size,
)]
} else {
let mut sets = Vec::with_capacity(num_of_sets);
let set_ids: Vec<_> = std::iter::repeat(())
.map(|_| generate_set_id(rng))
.take(num_of_sets)
.collect();
let mut lb = 0;
let mut ub = max_one_way_linked_set_payload_length(max_plaintext_size);
for i in 0..num_of_sets {
let fragment_set = prepare_fragment_set(
&message[lb..ub],
set_ids[i],
if i == 0 { None } else { Some(set_ids[i - 1]) },
if i == (num_of_sets - 1) {
None
} else {
Some(set_ids[i + 1])
},
max_plaintext_size,
);
sets.push(fragment_set);
lb = ub;
ub = if i == num_of_sets - 2 {
usize::min(
message.len(),
ub + max_one_way_linked_set_payload_length(max_plaintext_size),
)
} else {
usize::min(
message.len(),
ub + two_way_linked_set_payload_length(max_plaintext_size),
)
}
}
sets
}
}
#[cfg(test)]
mod tests {
use super::*;
use nym_sphinx_params::packet_sizes::PacketSize;
fn max_plaintext_size() -> usize {
PacketSize::default().plaintext_size() - PacketSize::AckPacket.size()
}
fn verify_unlinked_set_payload(mut set: FragmentSet, payload: &[u8]) {
for i in (0..set.len()).rev() {
assert_eq!(
set.pop().unwrap().extract_payload(),
payload[i * unlinked_fragment_payload_max_len(max_plaintext_size())
..usize::min(
payload.len(),
(i + 1) * unlinked_fragment_payload_max_len(max_plaintext_size())
)]
.to_vec()
)
}
}
fn verify_pre_linked_set_payload(mut set: FragmentSet, payload: &[u8]) {
for i in (0..set.len()).rev() {
let lb = if i == 0 {
0
} else {
(i - 1) * unlinked_fragment_payload_max_len(max_plaintext_size())
+ linked_fragment_payload_max_len(max_plaintext_size())
};
let ub = usize::min(
payload.len(),
i * unlinked_fragment_payload_max_len(max_plaintext_size())
+ linked_fragment_payload_max_len(max_plaintext_size()),
);
assert_eq!(
set.pop().unwrap().extract_payload(),
payload[lb..ub].to_vec()
)
}
}
fn verify_post_linked_set_payload(mut set: FragmentSet, payload: &[u8]) {
for i in (0..set.len()).rev() {
let lb = i * unlinked_fragment_payload_max_len(max_plaintext_size());
let ub = if i == (u8::MAX as usize - 1) {
i * unlinked_fragment_payload_max_len(max_plaintext_size())
+ linked_fragment_payload_max_len(max_plaintext_size())
} else {
(i + 1) * unlinked_fragment_payload_max_len(max_plaintext_size())
};
assert_eq!(
set.pop().unwrap().extract_payload(),
payload[lb..ub].to_vec(),
)
}
}
fn verify_two_way_linked_set_payload(mut set: FragmentSet, payload: &[u8]) {
for i in (0..set.len()).rev() {
let lb = if i == 0 {
0
} else {
(i - 1) * unlinked_fragment_payload_max_len(max_plaintext_size())
+ linked_fragment_payload_max_len(max_plaintext_size())
};
let ub = if i == (u8::MAX as usize - 1) {
(i - 1) * unlinked_fragment_payload_max_len(max_plaintext_size())
+ 2 * linked_fragment_payload_max_len(max_plaintext_size())
} else {
i * unlinked_fragment_payload_max_len(max_plaintext_size())
+ linked_fragment_payload_max_len(max_plaintext_size())
};
assert_eq!(
set.pop().unwrap().extract_payload(),
payload[lb..ub].to_vec(),
)
}
}
fn verify_correct_link(left: &[Fragment], right: &[Fragment]) {
let first_id = left[0].id();
let post_id = left[254].next_fragments_set_id().unwrap();
let second_id = right[0].id();
let pre_id = right[0].previous_fragments_set_id().unwrap();
assert_eq!(first_id, pre_id);
assert_eq!(second_id, post_id);
}
#[cfg(test)]
mod preparing_unlinked_set {
use super::*;
use rand::{RngCore, thread_rng};
#[test]
fn makes_set_with_correctly_split_payload() {
let id = 12345;
let mut rng = thread_rng();
let mut two_element_set_payload =
vec![0u8; unlinked_fragment_payload_max_len(max_plaintext_size()) + 1];
rng.fill_bytes(&mut two_element_set_payload);
let two_element_set =
prepare_unlinked_fragmented_set(&two_element_set_payload, id, max_plaintext_size());
assert_eq!(2, two_element_set.len());
verify_unlinked_set_payload(two_element_set, &two_element_set_payload);
let mut forty_two_element_set_payload =
vec![0u8; 41 * unlinked_fragment_payload_max_len(max_plaintext_size()) + 42];
rng.fill_bytes(&mut forty_two_element_set_payload);
let forty_two_element_set = prepare_unlinked_fragmented_set(
&forty_two_element_set_payload,
id,
max_plaintext_size(),
);
assert_eq!(42, forty_two_element_set.len());
verify_unlinked_set_payload(forty_two_element_set, &forty_two_element_set_payload);
let mut max_fragments_set_payload =
vec![
0u8;
max_unlinked_set_payload_length(max_plaintext_size())
- unlinked_fragment_payload_max_len(max_plaintext_size())
+ 1
]; rng.fill_bytes(&mut max_fragments_set_payload);
let max_fragment_set = prepare_unlinked_fragmented_set(
&max_fragments_set_payload,
id,
max_plaintext_size(),
);
assert_eq!(u8::MAX as usize, max_fragment_set.len());
verify_unlinked_set_payload(max_fragment_set, &max_fragments_set_payload);
let mut full_set_payload =
vec![0u8; max_unlinked_set_payload_length(max_plaintext_size())];
rng.fill_bytes(&mut full_set_payload);
let full_fragment_set =
prepare_unlinked_fragmented_set(&full_set_payload, id, max_plaintext_size());
assert_eq!(u8::MAX as usize, full_fragment_set.len());
verify_unlinked_set_payload(full_fragment_set, &full_set_payload);
}
#[test]
#[should_panic]
fn panics_for_too_long_payload() {
prepare_unlinked_fragmented_set(
&vec![0u8; max_unlinked_set_payload_length(max_plaintext_size()) + 1],
12345,
max_plaintext_size(),
);
}
}
#[cfg(test)]
mod preparing_linked_set {
use super::*;
use rand::{RngCore, thread_rng};
#[test]
fn makes_set_with_correctly_split_payload_for_pre_linked_set() {
let id = 12345;
let link_id = 1234;
let mut rng = thread_rng();
let mut two_element_set_payload =
vec![0u8; linked_fragment_payload_max_len(max_plaintext_size()) + 1];
rng.fill_bytes(&mut two_element_set_payload);
let two_element_set = prepare_linked_fragment_set(
&two_element_set_payload,
id,
Some(link_id),
None,
max_plaintext_size(),
);
assert_eq!(2, two_element_set.len());
verify_pre_linked_set_payload(two_element_set, &two_element_set_payload);
let mut forty_two_element_set_payload =
vec![
0u8;
linked_fragment_payload_max_len(max_plaintext_size())
+ 40 * unlinked_fragment_payload_max_len(max_plaintext_size())
+ 42
];
rng.fill_bytes(&mut forty_two_element_set_payload);
let forty_two_element_set = prepare_linked_fragment_set(
&forty_two_element_set_payload,
id,
Some(link_id),
None,
max_plaintext_size(),
);
assert_eq!(42, forty_two_element_set.len());
verify_pre_linked_set_payload(forty_two_element_set, &forty_two_element_set_payload);
let mut max_fragments_set_payload =
vec![
0u8;
max_unlinked_set_payload_length(max_plaintext_size())
- linked_fragment_payload_max_len(max_plaintext_size())
+ 1
]; rng.fill_bytes(&mut max_fragments_set_payload);
let max_fragment_set = prepare_linked_fragment_set(
&max_fragments_set_payload,
id,
Some(link_id),
None,
max_plaintext_size(),
);
assert_eq!(u8::MAX as usize, max_fragment_set.len());
verify_pre_linked_set_payload(max_fragment_set, &max_fragments_set_payload);
let mut full_set_payload =
vec![0u8; max_one_way_linked_set_payload_length(max_plaintext_size())];
rng.fill_bytes(&mut full_set_payload);
let full_fragment_set = prepare_linked_fragment_set(
&full_set_payload,
id,
Some(link_id),
None,
max_plaintext_size(),
);
assert_eq!(u8::MAX as usize, full_fragment_set.len());
verify_pre_linked_set_payload(full_fragment_set, &full_set_payload);
}
#[test]
#[should_panic]
fn panics_for_too_long_payload_for_pre_linked_set() {
prepare_linked_fragment_set(
&vec![0u8; max_one_way_linked_set_payload_length(max_plaintext_size()) + 1],
12345,
Some(1234),
None,
max_plaintext_size(),
);
}
#[test]
fn makes_set_with_correctly_split_payload_for_post_linked_set() {
let id = 12345;
let link_id = 1234;
let mut rng = thread_rng();
let mut full_set_payload =
vec![0u8; max_one_way_linked_set_payload_length(max_plaintext_size())];
rng.fill_bytes(&mut full_set_payload);
let full_fragment_set = prepare_linked_fragment_set(
&full_set_payload,
id,
None,
Some(link_id),
max_plaintext_size(),
);
assert_eq!(u8::MAX as usize, full_fragment_set.len());
verify_post_linked_set_payload(full_fragment_set, &full_set_payload);
}
#[test]
#[should_panic]
fn panics_for_too_long_payload_for_post_linked_set() {
prepare_linked_fragment_set(
&vec![0u8; max_one_way_linked_set_payload_length(max_plaintext_size()) + 1],
12345,
None,
Some(1234),
max_plaintext_size(),
);
}
#[test]
#[should_panic]
fn panics_for_too_short_payload_for_post_linked_set() {
prepare_linked_fragment_set(
&vec![0u8; max_one_way_linked_set_payload_length(max_plaintext_size()) - 1],
12345,
None,
Some(1234),
max_plaintext_size(),
);
}
#[test]
fn makes_set_with_correctly_split_payload_for_two_way_linked_set() {
let id = 12345;
let pre_link_id = 1234;
let post_link_id = 123456;
let mut rng = thread_rng();
let mut full_set_payload =
vec![0u8; two_way_linked_set_payload_length(max_plaintext_size())];
rng.fill_bytes(&mut full_set_payload);
let full_fragment_set = prepare_linked_fragment_set(
&full_set_payload,
id,
Some(pre_link_id),
Some(post_link_id),
max_plaintext_size(),
);
assert_eq!(u8::MAX as usize, full_fragment_set.len());
verify_two_way_linked_set_payload(full_fragment_set, &full_set_payload);
}
#[test]
#[should_panic]
fn panics_for_too_long_payload_for_two_way_linked_set() {
prepare_linked_fragment_set(
&vec![0u8; two_way_linked_set_payload_length(max_plaintext_size()) + 1],
12345,
Some(123456),
Some(1234),
max_plaintext_size(),
);
}
#[test]
#[should_panic]
fn panics_for_too_short_payload_for_two_way_linked_set() {
prepare_linked_fragment_set(
&vec![0u8; two_way_linked_set_payload_length(max_plaintext_size()) - 1],
12345,
Some(123456),
Some(1234),
max_plaintext_size(),
);
}
}
#[cfg(test)]
mod splitting_into_sets {
use super::*;
use rand::{RngCore, thread_rng};
#[test]
fn correctly_creates_single_fragmented_set_when_expected() {
let mut rng = thread_rng();
let mut message =
vec![0u8; max_unlinked_set_payload_length(max_plaintext_size()) - 2345];
rng.fill_bytes(&mut message);
let mut sets = split_into_sets(&mut rng, &message, max_plaintext_size());
assert_eq!(1, sets.len());
verify_unlinked_set_payload(sets.pop().unwrap(), &message);
}
#[test]
fn correctly_creates_two_singly_linked_sets_with_second_set_containing_data_fitting_in_unfragmented_payload()
{
let mut rng = thread_rng();
let mut message =
vec![0u8; max_one_way_linked_set_payload_length(max_plaintext_size()) + 123];
rng.fill_bytes(&mut message);
let mut sets = split_into_sets(&mut rng, &message, max_plaintext_size());
assert_eq!(2, sets.len());
verify_correct_link(&sets[0], &sets[1]);
verify_pre_linked_set_payload(
sets.pop().unwrap(),
&message[max_one_way_linked_set_payload_length(max_plaintext_size())..],
);
verify_post_linked_set_payload(
sets.pop().unwrap(),
&message[..max_one_way_linked_set_payload_length(max_plaintext_size())],
);
}
#[test]
fn correctly_creates_two_singly_linked_sets_when_expected() {
let mut rng = thread_rng();
let mut message =
vec![0u8; max_one_way_linked_set_payload_length(max_plaintext_size()) + 2345];
rng.fill_bytes(&mut message);
let mut sets = split_into_sets(&mut rng, &message, max_plaintext_size());
assert_eq!(2, sets.len());
verify_correct_link(&sets[0], &sets[1]);
verify_pre_linked_set_payload(
sets.pop().unwrap(),
&message[max_one_way_linked_set_payload_length(max_plaintext_size())..],
);
verify_post_linked_set_payload(
sets.pop().unwrap(),
&message[..max_one_way_linked_set_payload_length(max_plaintext_size())],
);
let mut message =
vec![0u8; 2 * max_one_way_linked_set_payload_length(max_plaintext_size())];
rng.fill_bytes(&mut message);
let mut sets = split_into_sets(&mut rng, &message, max_plaintext_size());
assert_eq!(2, sets.len());
assert_eq!(sets[0].len(), u8::MAX as usize);
assert_eq!(sets[1].len(), u8::MAX as usize);
verify_correct_link(&sets[0], &sets[1]);
verify_pre_linked_set_payload(
sets.pop().unwrap(),
&message[max_one_way_linked_set_payload_length(max_plaintext_size())..],
);
verify_post_linked_set_payload(
sets.pop().unwrap(),
&message[..max_one_way_linked_set_payload_length(max_plaintext_size())],
);
}
#[test]
fn correctly_creates_four_correctly_formed_sets_when_expected() {
let mut rng = thread_rng();
let mut message = vec![
0u8;
2 * two_way_linked_set_payload_length(max_plaintext_size())
+ max_one_way_linked_set_payload_length(max_plaintext_size())
+ 2345
];
rng.fill_bytes(&mut message);
let mut sets = split_into_sets(&mut rng, &message, max_plaintext_size());
assert_eq!(4, sets.len());
assert_eq!(sets[0].len(), u8::MAX as usize);
assert_eq!(sets[1].len(), u8::MAX as usize);
assert_eq!(sets[2].len(), u8::MAX as usize);
verify_correct_link(&sets[0], &sets[1]);
verify_correct_link(&sets[1], &sets[2]);
verify_correct_link(&sets[2], &sets[3]);
verify_pre_linked_set_payload(
sets.pop().unwrap(),
&message[2 * two_way_linked_set_payload_length(max_plaintext_size())
+ max_one_way_linked_set_payload_length(max_plaintext_size())..],
);
verify_two_way_linked_set_payload(
sets.pop().unwrap(),
&message[two_way_linked_set_payload_length(max_plaintext_size())
+ max_one_way_linked_set_payload_length(max_plaintext_size())
..2 * two_way_linked_set_payload_length(max_plaintext_size())
+ max_one_way_linked_set_payload_length(max_plaintext_size())],
);
verify_two_way_linked_set_payload(
sets.pop().unwrap(),
&message[max_one_way_linked_set_payload_length(max_plaintext_size())
..two_way_linked_set_payload_length(max_plaintext_size())
+ max_one_way_linked_set_payload_length(max_plaintext_size())],
);
verify_post_linked_set_payload(
sets.pop().unwrap(),
&message[..max_one_way_linked_set_payload_length(max_plaintext_size())],
);
let mut message =
vec![
0u8;
2 * two_way_linked_set_payload_length(max_plaintext_size())
+ 2 * max_one_way_linked_set_payload_length(max_plaintext_size())
];
rng.fill_bytes(&mut message);
let mut sets = split_into_sets(&mut rng, &message, max_plaintext_size());
assert_eq!(4, sets.len());
assert_eq!(sets[0].len(), u8::MAX as usize);
assert_eq!(sets[1].len(), u8::MAX as usize);
assert_eq!(sets[2].len(), u8::MAX as usize);
assert_eq!(sets[3].len(), u8::MAX as usize);
verify_correct_link(&sets[0], &sets[1]);
verify_correct_link(&sets[1], &sets[2]);
verify_correct_link(&sets[2], &sets[3]);
verify_pre_linked_set_payload(
sets.pop().unwrap(),
&message[2 * two_way_linked_set_payload_length(max_plaintext_size())
+ max_one_way_linked_set_payload_length(max_plaintext_size())..],
);
verify_two_way_linked_set_payload(
sets.pop().unwrap(),
&message[two_way_linked_set_payload_length(max_plaintext_size())
+ max_one_way_linked_set_payload_length(max_plaintext_size())
..2 * two_way_linked_set_payload_length(max_plaintext_size())
+ max_one_way_linked_set_payload_length(max_plaintext_size())],
);
verify_two_way_linked_set_payload(
sets.pop().unwrap(),
&message[max_one_way_linked_set_payload_length(max_plaintext_size())
..two_way_linked_set_payload_length(max_plaintext_size())
+ max_one_way_linked_set_payload_length(max_plaintext_size())],
);
verify_post_linked_set_payload(
sets.pop().unwrap(),
&message[..max_one_way_linked_set_payload_length(max_plaintext_size())],
);
}
}
#[cfg(test)]
mod helpers {
use super::*;
#[test]
fn total_number_of_sets() {
assert_eq!(
1,
super::total_number_of_sets(
max_unlinked_set_payload_length(max_plaintext_size()) - 1,
max_plaintext_size()
)
);
assert_eq!(
1,
super::total_number_of_sets(
max_unlinked_set_payload_length(max_plaintext_size()),
max_plaintext_size()
)
);
assert_eq!(
2,
super::total_number_of_sets(
max_unlinked_set_payload_length(max_plaintext_size()) + 1,
max_plaintext_size()
)
);
assert_eq!(
2,
super::total_number_of_sets(
2 * max_one_way_linked_set_payload_length(max_plaintext_size()),
max_plaintext_size()
)
);
assert_eq!(
3,
super::total_number_of_sets(
2 * max_one_way_linked_set_payload_length(max_plaintext_size()) + 1,
max_plaintext_size()
)
);
assert_eq!(
3,
super::total_number_of_sets(
2 * max_one_way_linked_set_payload_length(max_plaintext_size())
+ two_way_linked_set_payload_length(max_plaintext_size())
- 1,
max_plaintext_size()
)
);
assert_eq!(
3,
super::total_number_of_sets(
2 * max_one_way_linked_set_payload_length(max_plaintext_size())
+ two_way_linked_set_payload_length(max_plaintext_size()),
max_plaintext_size()
)
);
assert_eq!(
4,
super::total_number_of_sets(
2 * max_one_way_linked_set_payload_length(max_plaintext_size())
+ two_way_linked_set_payload_length(max_plaintext_size())
+ 1,
max_plaintext_size()
)
);
assert_eq!(
4,
super::total_number_of_sets(
2 * max_one_way_linked_set_payload_length(max_plaintext_size())
+ 2 * two_way_linked_set_payload_length(max_plaintext_size())
- 1,
max_plaintext_size()
)
);
assert_eq!(
4,
super::total_number_of_sets(
2 * max_one_way_linked_set_payload_length(max_plaintext_size())
+ 2 * two_way_linked_set_payload_length(max_plaintext_size()),
max_plaintext_size()
)
);
assert_eq!(
5,
super::total_number_of_sets(
2 * max_one_way_linked_set_payload_length(max_plaintext_size())
+ 2 * two_way_linked_set_payload_length(max_plaintext_size())
+ 1,
max_plaintext_size()
)
);
}
}
}