raptorq: rustfmt whole project

This commit is contained in:
Luca Bruno 2019-03-28 21:13:19 +00:00 committed by Christopher Berner
parent a55116e637
commit 38df97cce1
18 changed files with 546 additions and 459 deletions

@ -5,12 +5,11 @@ use criterion::Criterion;
use criterion::Throughput; use criterion::Throughput;
use rand::Rng; use rand::Rng;
use raptorq::SourceBlockEncoder;
use raptorq::SourceBlockDecoder;
use raptorq::Octet; use raptorq::Octet;
use raptorq::SourceBlockDecoder;
use raptorq::SourceBlockEncoder;
use raptorq::Symbol; use raptorq::Symbol;
fn criterion_benchmark(c: &mut Criterion) { fn criterion_benchmark(c: &mut Criterion) {
let octet1 = Octet::new(rand::thread_rng().gen_range(1, 255)); let octet1 = Octet::new(rand::thread_rng().gen_range(1, 255));
let symbol_size = 512; let symbol_size = 512;
@ -25,31 +24,48 @@ fn criterion_benchmark(c: &mut Criterion) {
let symbol1_mul_scalar = symbol1.clone(); let symbol1_mul_scalar = symbol1.clone();
let octet1_mul_scalar = octet1.clone(); let octet1_mul_scalar = octet1.clone();
c.bench("Symbol mulassign_scalar()", Benchmark::new("", move |b| b.iter(|| { c.bench(
let mut temp = symbol1_mul_scalar.clone(); "Symbol mulassign_scalar()",
temp.mulassign_scalar(&octet1_mul_scalar); Benchmark::new("", move |b| {
temp b.iter(|| {
})).throughput(Throughput::Bytes(symbol1.len() as u32))); let mut temp = symbol1_mul_scalar.clone();
temp.mulassign_scalar(&octet1_mul_scalar);
temp
})
})
.throughput(Throughput::Bytes(symbol1.len() as u32)),
);
let symbol1_addassign = symbol1.clone(); let symbol1_addassign = symbol1.clone();
let symbol2_addassign = symbol2.clone(); let symbol2_addassign = symbol2.clone();
c.bench("Symbol +=", Benchmark::new("", move |b| b.iter(|| { c.bench(
let mut temp = symbol1_addassign.clone(); "Symbol +=",
temp += &symbol2_addassign; Benchmark::new("", move |b| {
temp b.iter(|| {
})).throughput(Throughput::Bytes(symbol1.len() as u32))); let mut temp = symbol1_addassign.clone();
temp += &symbol2_addassign;
temp
})
})
.throughput(Throughput::Bytes(symbol1.len() as u32)),
);
let symbol1_fma = symbol1.clone(); let symbol1_fma = symbol1.clone();
let symbol2_fma = symbol2.clone(); let symbol2_fma = symbol2.clone();
let octet1_fma = octet1.clone(); let octet1_fma = octet1.clone();
c.bench("Symbol FMA", Benchmark::new("", move |b| b.iter(|| { c.bench(
let mut temp = symbol1_fma.clone(); "Symbol FMA",
temp.fused_addassign_mul_scalar(&symbol2_fma, &octet1_fma); Benchmark::new("", move |b| {
temp b.iter(|| {
})).throughput(Throughput::Bytes(symbol1.len() as u32))); let mut temp = symbol1_fma.clone();
temp.fused_addassign_mul_scalar(&symbol2_fma, &octet1_fma);
temp
})
})
.throughput(Throughput::Bytes(symbol1.len() as u32)),
);
let elements = 10 * 1024;
let elements = 10*1024;
let symbol_size = 512; let symbol_size = 512;
let mut data: Vec<u8> = vec![0; elements]; let mut data: Vec<u8> = vec![0; elements];
for i in 0..elements { for i in 0..elements {
@ -57,32 +73,50 @@ fn criterion_benchmark(c: &mut Criterion) {
} }
let encode_data = data.clone(); let encode_data = data.clone();
c.bench("encode 10KB", Benchmark::new("", move |b| b.iter(|| { c.bench(
let encoder = SourceBlockEncoder::new(1, symbol_size, &encode_data); "encode 10KB",
return encoder.source_packets(); Benchmark::new("", move |b| {
})).throughput(Throughput::Bytes(data.len() as u32))); b.iter(|| {
let encoder = SourceBlockEncoder::new(1, symbol_size, &encode_data);
return encoder.source_packets();
})
})
.throughput(Throughput::Bytes(data.len() as u32)),
);
let roundtrip_data = data.clone(); let roundtrip_data = data.clone();
c.bench("roundtrip 10KB", Benchmark::new("", move |b| b.iter(|| { c.bench(
let encoder = SourceBlockEncoder::new(1, symbol_size, &roundtrip_data); "roundtrip 10KB",
let mut decoder = SourceBlockDecoder::new(1, symbol_size, elements as u64); Benchmark::new("", move |b| {
let mut result = None; b.iter(|| {
for packet in encoder.source_packets() { let encoder = SourceBlockEncoder::new(1, symbol_size, &roundtrip_data);
result = decoder.decode(packet); let mut decoder = SourceBlockDecoder::new(1, symbol_size, elements as u64);
} let mut result = None;
return result for packet in encoder.source_packets() {
})).throughput(Throughput::Bytes(data.len() as u32))); result = decoder.decode(packet);
}
return result;
})
})
.throughput(Throughput::Bytes(data.len() as u32)),
);
let repair_data = data.clone(); let repair_data = data.clone();
c.bench("roundtrip repair 10KB", Benchmark::new("", move |b| b.iter(|| { c.bench(
let encoder = SourceBlockEncoder::new(1, symbol_size, &repair_data); "roundtrip repair 10KB",
let mut decoder = SourceBlockDecoder::new(1, symbol_size, elements as u64); Benchmark::new("", move |b| {
let mut result = None; b.iter(|| {
for packet in encoder.repair_packets(0, (elements / symbol_size as usize) as u32) { let encoder = SourceBlockEncoder::new(1, symbol_size, &repair_data);
result = decoder.decode(packet); let mut decoder = SourceBlockDecoder::new(1, symbol_size, elements as u64);
} let mut result = None;
return result for packet in encoder.repair_packets(0, (elements / symbol_size as usize) as u32) {
})).throughput(Throughput::Bytes(data.len() as u32))); result = decoder.decode(packet);
}
return result;
})
})
.throughput(Throughput::Bytes(data.len() as u32)),
);
} }
criterion_group!(benches, criterion_benchmark); criterion_group!(benches, criterion_benchmark);

@ -1,9 +1,8 @@
use rand::Rng; use rand::Rng;
use raptorq::SourceBlockEncoder; use raptorq::SourceBlockEncoder;
fn main() { fn main() {
let elements = 10*1024; let elements = 10 * 1024;
let symbol_size = 512; let symbol_size = 512;
let mut data: Vec<u8> = vec![0; elements]; let mut data: Vec<u8> = vec![0; elements];
for i in 0..elements { for i in 0..elements {

@ -1,7 +1,7 @@
use raptorq::extended_source_block_symbols;
use raptorq::generate_constraint_matrix;
use raptorq::IntermediateSymbolDecoder; use raptorq::IntermediateSymbolDecoder;
use raptorq::Octet; use raptorq::Octet;
use raptorq::generate_constraint_matrix;
use raptorq::extended_source_block_symbols;
use raptorq::Symbol; use raptorq::Symbol;
fn main() { fn main() {
@ -17,18 +17,28 @@ fn main() {
} }
} }
} }
println!("Original density for {}x{}: {} of {}", a.height(), a.width(), density, a.height() * a.width()); println!(
"Original density for {}x{}: {} of {}",
a.height(),
a.width(),
density,
a.height() * a.width()
);
let symbols = vec![Symbol::zero(1); a.width()]; let symbols = vec![Symbol::zero(1); a.width()];
let mut decoder = IntermediateSymbolDecoder::new(a, symbols, num_symbols); let mut decoder = IntermediateSymbolDecoder::new(a, symbols, num_symbols);
decoder.execute(); decoder.execute();
println!("Optimized decoder mul ops: {} ({:.1} per symbol), add ops: {} ({:.1} per symbol)", println!(
decoder.get_symbol_mul_ops(), "Optimized decoder mul ops: {} ({:.1} per symbol), add ops: {} ({:.1} per symbol)",
decoder.get_symbol_mul_ops() as f64 / num_symbols as f64, decoder.get_symbol_mul_ops(),
decoder.get_symbol_add_ops(), decoder.get_symbol_mul_ops() as f64 / num_symbols as f64,
decoder.get_symbol_add_ops() as f64 / num_symbols as f64); decoder.get_symbol_add_ops(),
println!("By phase mul ops: {:?}, add ops: {:?}", decoder.get_symbol_add_ops() as f64 / num_symbols as f64
decoder.get_symbol_mul_ops_by_phase(), );
decoder.get_symbol_add_ops_by_phase()); println!(
"By phase mul ops: {:?}, add ops: {:?}",
decoder.get_symbol_mul_ops_by_phase(),
decoder.get_symbol_add_ops_by_phase()
);
} }
} }

@ -1,5 +1,5 @@
use rand::Rng;
use rand::seq::SliceRandom; use rand::seq::SliceRandom;
use rand::Rng;
use raptorq::{Decoder, Encoder, EncodingPacket}; use raptorq::{Decoder, Encoder, EncodingPacket};
fn main() { fn main() {
@ -13,7 +13,9 @@ fn main() {
let encoder = Encoder::with_defaults(&data, 1400); let encoder = Encoder::with_defaults(&data, 1400);
// Perform the encoding, and serialize to Vec<u8> for transmission // Perform the encoding, and serialize to Vec<u8> for transmission
let mut packets: Vec<Vec<u8>> = encoder.get_encoded_packets(15).iter() let mut packets: Vec<Vec<u8>> = encoder
.get_encoded_packets(15)
.iter()
.map(|packet| packet.serialize()) .map(|packet| packet.serialize())
.collect(); .collect();
@ -40,4 +42,4 @@ fn main() {
// Check that even though some of the data was lost we are able to reconstruct the original message // Check that even though some of the data was lost we are able to reconstruct the original message
assert_eq!(result.unwrap(), data); assert_eq!(result.unwrap(), data);
} }

@ -1,14 +1,14 @@
#[derive(Clone)] #[derive(Clone)]
pub struct ArrayMap<T> { pub struct ArrayMap<T> {
offset: usize, offset: usize,
elements: Vec<Option<T>> elements: Vec<Option<T>>,
} }
impl <T: std::clone::Clone> ArrayMap<T> { impl<T: std::clone::Clone> ArrayMap<T> {
pub fn new(start_key: usize, end_key: usize) -> ArrayMap<T> { pub fn new(start_key: usize, end_key: usize) -> ArrayMap<T> {
ArrayMap { ArrayMap {
offset: start_key, offset: start_key,
elements: vec![None; end_key - start_key] elements: vec![None; end_key - start_key],
} }
} }
@ -38,14 +38,14 @@ impl <T: std::clone::Clone> ArrayMap<T> {
#[derive(Clone)] #[derive(Clone)]
pub struct UsizeArrayMap { pub struct UsizeArrayMap {
offset: usize, offset: usize,
elements: Vec<usize> elements: Vec<usize>,
} }
impl UsizeArrayMap { impl UsizeArrayMap {
pub fn new(start_key: usize, end_key: usize) -> UsizeArrayMap { pub fn new(start_key: usize, end_key: usize) -> UsizeArrayMap {
UsizeArrayMap { UsizeArrayMap {
offset: start_key, offset: start_key,
elements: vec![0; end_key - start_key] elements: vec![0; end_key - start_key],
} }
} }
@ -73,14 +73,14 @@ impl UsizeArrayMap {
#[derive(Clone)] #[derive(Clone)]
pub struct BoolArrayMap { pub struct BoolArrayMap {
offset: usize, offset: usize,
elements: Vec<bool> elements: Vec<bool>,
} }
impl BoolArrayMap { impl BoolArrayMap {
pub fn new(start_key: usize, end_key: usize) -> BoolArrayMap { pub fn new(start_key: usize, end_key: usize) -> BoolArrayMap {
BoolArrayMap { BoolArrayMap {
offset: start_key, offset: start_key,
elements: vec![false; end_key - start_key] elements: vec![false; end_key - start_key],
} }
} }

@ -10,7 +10,7 @@ use crate::systematic_constants::SYSTEMATIC_INDICES_AND_PARAMETERS;
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub struct PayloadId { pub struct PayloadId {
source_block_number: u8, source_block_number: u8,
encoding_symbol_id: u32 encoding_symbol_id: u32,
} }
impl PayloadId { impl PayloadId {
@ -19,14 +19,14 @@ impl PayloadId {
assert!(encoding_symbol_id < 16777216); assert!(encoding_symbol_id < 16777216);
PayloadId { PayloadId {
source_block_number, source_block_number,
encoding_symbol_id encoding_symbol_id,
} }
} }
pub fn deserialize(data: &[u8; 4]) -> PayloadId { pub fn deserialize(data: &[u8; 4]) -> PayloadId {
PayloadId { PayloadId {
source_block_number: data[0], source_block_number: data[0],
encoding_symbol_id: ((data[1] as u32) << 16) + ((data[2] as u32) << 8) + data[3] as u32 encoding_symbol_id: ((data[1] as u32) << 16) + ((data[2] as u32) << 8) + data[3] as u32,
} }
} }
@ -35,7 +35,7 @@ impl PayloadId {
self.source_block_number, self.source_block_number,
(self.encoding_symbol_id >> 16) as u8, (self.encoding_symbol_id >> 16) as u8,
((self.encoding_symbol_id >> 8) & 0xFF) as u8, ((self.encoding_symbol_id >> 8) & 0xFF) as u8,
(self.encoding_symbol_id & 0xFF) as u8 (self.encoding_symbol_id & 0xFF) as u8,
] ]
} }
@ -52,22 +52,19 @@ impl PayloadId {
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub struct EncodingPacket { pub struct EncodingPacket {
payload_id: PayloadId, payload_id: PayloadId,
data: Vec<u8> data: Vec<u8>,
} }
impl EncodingPacket { impl EncodingPacket {
pub fn new(payload_id: PayloadId, data: Vec<u8>) -> EncodingPacket { pub fn new(payload_id: PayloadId, data: Vec<u8>) -> EncodingPacket {
EncodingPacket { EncodingPacket { payload_id, data }
payload_id,
data
}
} }
pub fn deserialize(data: &[u8]) -> EncodingPacket { pub fn deserialize(data: &[u8]) -> EncodingPacket {
let payload_data = [data[0], data[1], data[2], data[3]]; let payload_data = [data[0], data[1], data[2], data[3]];
EncodingPacket { EncodingPacket {
payload_id: PayloadId::deserialize(&payload_data), payload_id: PayloadId::deserialize(&payload_data),
data: Vec::from(&data[4..]) data: Vec::from(&data[4..]),
} }
} }
@ -94,11 +91,17 @@ pub struct ObjectTransmissionInformation {
symbol_size: u16, symbol_size: u16,
num_source_blocks: u8, num_source_blocks: u8,
num_sub_blocks: u16, num_sub_blocks: u16,
symbol_alignment: u8 symbol_alignment: u8,
} }
impl ObjectTransmissionInformation { impl ObjectTransmissionInformation {
pub fn new(transfer_length: u64, symbol_size: u16, source_blocks: u8, sub_blocks: u16, alignment: u8) -> ObjectTransmissionInformation { pub fn new(
transfer_length: u64,
symbol_size: u16,
source_blocks: u8,
sub_blocks: u16,
alignment: u8,
) -> ObjectTransmissionInformation {
assert!(transfer_length <= 946270874880); assert!(transfer_length <= 946270874880);
assert_eq!(symbol_size % alignment as u16, 0); assert_eq!(symbol_size % alignment as u16, 0);
ObjectTransmissionInformation { ObjectTransmissionInformation {
@ -106,18 +109,21 @@ impl ObjectTransmissionInformation {
symbol_size, symbol_size,
num_source_blocks: source_blocks, num_source_blocks: source_blocks,
num_sub_blocks: sub_blocks, num_sub_blocks: sub_blocks,
symbol_alignment: alignment symbol_alignment: alignment,
} }
} }
pub fn deserialize(data: &[u8; 12]) -> ObjectTransmissionInformation { pub fn deserialize(data: &[u8; 12]) -> ObjectTransmissionInformation {
ObjectTransmissionInformation { ObjectTransmissionInformation {
transfer_length: ((data[0] as u64) << 32) + ((data[1] as u64) << 24) + transfer_length: ((data[0] as u64) << 32)
((data[2] as u64) << 16) + ((data[3] as u64) << 8) + (data[4] as u64), + ((data[1] as u64) << 24)
+ ((data[2] as u64) << 16)
+ ((data[3] as u64) << 8)
+ (data[4] as u64),
symbol_size: ((data[6] as u16) << 8) + data[7] as u16, symbol_size: ((data[6] as u16) << 8) + data[7] as u16,
num_source_blocks: data[8], num_source_blocks: data[8],
num_sub_blocks: ((data[9] as u16) << 8) + data[10] as u16, num_sub_blocks: ((data[9] as u16) << 8) + data[10] as u16,
symbol_alignment: data[11] symbol_alignment: data[11],
} }
} }
@ -134,7 +140,7 @@ impl ObjectTransmissionInformation {
self.num_source_blocks, self.num_source_blocks,
(self.num_sub_blocks >> 8) as u8, (self.num_sub_blocks >> 8) as u8,
(self.num_sub_blocks & 0xFF) as u8, (self.num_sub_blocks & 0xFF) as u8,
self.symbol_alignment self.symbol_alignment,
] ]
} }
@ -158,11 +164,14 @@ impl ObjectTransmissionInformation {
self.symbol_alignment self.symbol_alignment
} }
pub fn with_defaults(transfer_length: u64, max_packet_size: u16) -> ObjectTransmissionInformation { pub fn with_defaults(
transfer_length: u64,
max_packet_size: u16,
) -> ObjectTransmissionInformation {
let alignment = 8; let alignment = 8;
assert!(max_packet_size >= alignment); assert!(max_packet_size >= alignment);
let symbol_size = max_packet_size - (max_packet_size % alignment); let symbol_size = max_packet_size - (max_packet_size % alignment);
let max_memory = 10*1024*1024; let max_memory = 10 * 1024 * 1024;
let sub_symbol_size = 8; let sub_symbol_size = 8;
let kt = (transfer_length as f64 / symbol_size as f64).ceil(); let kt = (transfer_length as f64 / symbol_size as f64).ceil();
@ -193,8 +202,7 @@ impl ObjectTransmissionInformation {
symbol_size, symbol_size,
num_source_blocks: num_source_blocks as u8, num_source_blocks: num_source_blocks as u8,
num_sub_blocks: n as u16, num_sub_blocks: n as u16,
symbol_alignment: alignment as u8 symbol_alignment: alignment as u8,
} }
} }
} }
@ -212,9 +220,10 @@ pub fn partition(i: u32, j: u32) -> (u32, u32, u32, u32) {
pub fn deg(v: u32, lt_symbols: u32) -> u32 { pub fn deg(v: u32, lt_symbols: u32) -> u32 {
assert!(v < 1048576); assert!(v < 1048576);
let f: [u32; 31] = [ let f: [u32; 31] = [
0, 5243, 529531, 704294, 791675, 844104, 879057, 904023, 922747, 937311, 948962, 0, 5243, 529531, 704294, 791675, 844104, 879057, 904023, 922747, 937311, 948962, 958494,
958494, 966438, 973160, 978921, 983914, 988283, 992138, 995565, 998631, 1001391, 966438, 973160, 978921, 983914, 988283, 992138, 995565, 998631, 1001391, 1003887, 1006157,
1003887, 1006157, 1008229, 1010129, 1011876, 1013490, 1014983, 1016370, 1017662, 1048576]; 1008229, 1010129, 1011876, 1013490, 1014983, 1016370, 1017662, 1048576,
];
for d in 1..f.len() { for d in 1..f.len() {
if v < f[d] { if v < f[d] {
@ -226,22 +235,25 @@ pub fn deg(v: u32, lt_symbols: u32) -> u32 {
// Tuple[K', X] as defined in section 5.3.5.4 // Tuple[K', X] as defined in section 5.3.5.4
#[allow(non_snake_case)] #[allow(non_snake_case)]
pub fn intermediate_tuple(source_block_symbols: u32, internal_symbol_id: u32) -> (u32, u32, u32, u32, u32, u32) { pub fn intermediate_tuple(
source_block_symbols: u32,
internal_symbol_id: u32,
) -> (u32, u32, u32, u32, u32, u32) {
let J = systematic_index(source_block_symbols); let J = systematic_index(source_block_symbols);
let W = num_lt_symbols(source_block_symbols); let W = num_lt_symbols(source_block_symbols);
let P1 = calculate_p1(source_block_symbols); let P1 = calculate_p1(source_block_symbols);
let mut A = 53591 + J*997; let mut A = 53591 + J * 997;
if A % 2 == 0 { if A % 2 == 0 {
A = A + 1 A = A + 1
} }
let B = 10267*(J + 1); let B = 10267 * (J + 1);
let y: u32 = ((B as u64 + internal_symbol_id as u64 * A as u64) % 4294967296) as u32; let y: u32 = ((B as u64 + internal_symbol_id as u64 * A as u64) % 4294967296) as u32;
let v = rand(y, 0, 1048576); let v = rand(y, 0, 1048576);
let d = deg(v, W); let d = deg(v, W);
let a = 1 + rand(y, 1, W-1); let a = 1 + rand(y, 1, W - 1);
let b = rand(y, 2, W); let b = rand(y, 2, W);
let mut d1 = 2; let mut d1 = 2;
@ -249,7 +261,7 @@ pub fn intermediate_tuple(source_block_symbols: u32, internal_symbol_id: u32) ->
d1 = 2 + rand(internal_symbol_id, 3, 2); d1 = 2 + rand(internal_symbol_id, 3, 2);
} }
let a1 = 1 + rand(internal_symbol_id, 4, P1-1); let a1 = 1 + rand(internal_symbol_id, 4, P1 - 1);
let b1 = rand(internal_symbol_id, 5, P1); let b1 = rand(internal_symbol_id, 5, P1);
(d, a, b, d1, a1, b1) (d, a, b, d1, a1, b1)
@ -257,19 +269,25 @@ pub fn intermediate_tuple(source_block_symbols: u32, internal_symbol_id: u32) ->
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::{EncodingPacket, ObjectTransmissionInformation, PayloadId};
use rand::Rng; use rand::Rng;
use crate::{PayloadId, EncodingPacket, ObjectTransmissionInformation};
#[test] #[test]
fn payload_id_serialization() { fn payload_id_serialization() {
let payload_id = PayloadId::new(rand::thread_rng().gen(), rand::thread_rng().gen_range(0, 256 * 256 * 256)); let payload_id = PayloadId::new(
rand::thread_rng().gen(),
rand::thread_rng().gen_range(0, 256 * 256 * 256),
);
let deserialized = PayloadId::deserialize(&payload_id.serialize()); let deserialized = PayloadId::deserialize(&payload_id.serialize());
assert_eq!(deserialized, payload_id); assert_eq!(deserialized, payload_id);
} }
#[test] #[test]
fn encoding_packet_serialization() { fn encoding_packet_serialization() {
let payload_id = PayloadId::new(rand::thread_rng().gen(), rand::thread_rng().gen_range(0, 256 * 256 * 256)); let payload_id = PayloadId::new(
rand::thread_rng().gen(),
rand::thread_rng().gen_range(0, 256 * 256 * 256),
);
let packet = EncodingPacket::new(payload_id, vec![rand::thread_rng().gen()]); let packet = EncodingPacket::new(payload_id, vec![rand::thread_rng().gen()]);
let deserialized = EncodingPacket::deserialize(&packet.serialize()); let deserialized = EncodingPacket::deserialize(&packet.serialize());
assert_eq!(deserialized, packet); assert_eq!(deserialized, packet);
@ -277,7 +295,10 @@ mod tests {
#[test] #[test]
fn oti_serialization() { fn oti_serialization() {
let oti = ObjectTransmissionInformation::with_defaults(rand::thread_rng().gen_range(0, 256 * 256 * 256 * 256 * 256), rand::thread_rng().gen()); let oti = ObjectTransmissionInformation::with_defaults(
rand::thread_rng().gen_range(0, 256 * 256 * 256 * 256 * 256),
rand::thread_rng().gen(),
);
let deserialized = ObjectTransmissionInformation::deserialize(&oti.serialize()); let deserialized = ObjectTransmissionInformation::deserialize(&oti.serialize());
assert_eq!(deserialized, oti); assert_eq!(deserialized, oti);
} }

@ -1,14 +1,14 @@
use crate::rng::rand; use crate::base::intermediate_tuple;
use crate::systematic_constants::extended_source_block_symbols;
use crate::systematic_constants::num_hdpc_symbols;
use crate::systematic_constants::num_ldpc_symbols;
use crate::systematic_constants::num_pi_symbols;
use crate::systematic_constants::num_lt_symbols;
use crate::systematic_constants::num_intermediate_symbols;
use crate::matrix::OctetMatrix; use crate::matrix::OctetMatrix;
use crate::octet::Octet; use crate::octet::Octet;
use crate::rng::rand;
use crate::systematic_constants::calculate_p1; use crate::systematic_constants::calculate_p1;
use crate::base::intermediate_tuple; use crate::systematic_constants::extended_source_block_symbols;
use crate::systematic_constants::num_hdpc_symbols;
use crate::systematic_constants::num_intermediate_symbols;
use crate::systematic_constants::num_ldpc_symbols;
use crate::systematic_constants::num_lt_symbols;
use crate::systematic_constants::num_pi_symbols;
// Generates the GAMMA matrix // Generates the GAMMA matrix
// See section 5.3.3.3 // See section 5.3.3.3
@ -31,8 +31,12 @@ fn generate_mt(H: usize, Kprime: usize, S: usize) -> OctetMatrix {
let mut matrix = OctetMatrix::new(H, Kprime + S); let mut matrix = OctetMatrix::new(H, Kprime + S);
for i in 0..H { for i in 0..H {
for j in 0..=(Kprime + S - 2) { for j in 0..=(Kprime + S - 2) {
if i == rand((j + 1) as u32, 6, H as u32) as usize || if i == rand((j + 1) as u32, 6, H as u32) as usize
i == ((rand((j + 1) as u32, 6, H as u32) + rand((j + 1) as u32, 7, (H - 1) as u32) + 1) % (H as u32)) as usize { || i == ((rand((j + 1) as u32, 6, H as u32)
+ rand((j + 1) as u32, 7, (H - 1) as u32)
+ 1)
% (H as u32)) as usize
{
matrix.set(i, j, Octet::one()); matrix.set(i, j, Octet::one());
} }
} }
@ -42,8 +46,10 @@ fn generate_mt(H: usize, Kprime: usize, S: usize) -> OctetMatrix {
} }
// Simulates Enc[] function to get indices of accessed intermediate symbols, as defined in section 5.3.5.3 // Simulates Enc[] function to get indices of accessed intermediate symbols, as defined in section 5.3.5.3
pub fn enc_indices(source_block_symbols: u32, pub fn enc_indices(
source_tuple: (u32, u32, u32, u32, u32, u32)) -> Vec<usize> { source_block_symbols: u32,
source_tuple: (u32, u32, u32, u32, u32, u32),
) -> Vec<usize> {
let w = num_lt_symbols(source_block_symbols); let w = num_lt_symbols(source_block_symbols);
let p = num_pi_symbols(source_block_symbols); let p = num_pi_symbols(source_block_symbols);
let p1 = calculate_p1(source_block_symbols); let p1 = calculate_p1(source_block_symbols);
@ -82,7 +88,10 @@ pub fn enc_indices(source_block_symbols: u32,
// See section 5.3.3.4.2 // See section 5.3.3.4.2
#[allow(non_snake_case)] #[allow(non_snake_case)]
pub fn generate_constraint_matrix(source_block_symbols: u32, encoded_symbol_indices: &[u32]) -> OctetMatrix { pub fn generate_constraint_matrix(
source_block_symbols: u32,
encoded_symbol_indices: &[u32],
) -> OctetMatrix {
let Kprime = extended_source_block_symbols(source_block_symbols) as usize; let Kprime = extended_source_block_symbols(source_block_symbols) as usize;
let S = num_ldpc_symbols(source_block_symbols) as usize; let S = num_ldpc_symbols(source_block_symbols) as usize;
let H = num_hdpc_symbols(source_block_symbols) as usize; let H = num_hdpc_symbols(source_block_symbols) as usize;

@ -1,20 +1,20 @@
use std::collections::HashSet; use crate::base::intermediate_tuple;
use crate::base::partition;
use crate::base::EncodingPacket; use crate::base::EncodingPacket;
use crate::base::ObjectTransmissionInformation;
use crate::constraint_matrix::enc_indices;
use crate::constraint_matrix::generate_constraint_matrix;
use crate::pi_solver::fused_inverse_mul_symbols;
use crate::symbol::Symbol; use crate::symbol::Symbol;
use crate::systematic_constants::extended_source_block_symbols; use crate::systematic_constants::extended_source_block_symbols;
use crate::systematic_constants::num_ldpc_symbols;
use crate::systematic_constants::num_hdpc_symbols; use crate::systematic_constants::num_hdpc_symbols;
use crate::constraint_matrix::generate_constraint_matrix; use crate::systematic_constants::num_ldpc_symbols;
use crate::base::intermediate_tuple; use std::collections::HashSet;
use crate::pi_solver::fused_inverse_mul_symbols;
use crate::constraint_matrix::enc_indices;
use crate::base::ObjectTransmissionInformation;
use crate::base::partition;
pub struct Decoder { pub struct Decoder {
config: ObjectTransmissionInformation, config: ObjectTransmissionInformation,
block_decoders: Vec<SourceBlockDecoder>, block_decoders: Vec<SourceBlockDecoder>,
blocks: Vec<Option<Vec<u8>>> blocks: Vec<Option<Vec<u8>>>,
} }
impl Decoder { impl Decoder {
@ -24,21 +24,29 @@ impl Decoder {
// TODO: support subblocks // TODO: support subblocks
assert_eq!(1, config.sub_blocks()); assert_eq!(1, config.sub_blocks());
// let (tl, ts, nl, ns) = partition((config.symbol_size() / config.alignment() as u16) as u32, config.sub_blocks() as u32); // let (tl, ts, nl, ns) = partition((config.symbol_size() / config.alignment() as u16) as u32, config.sub_blocks() as u32);
let mut decoders = vec![]; let mut decoders = vec![];
for i in 0..zl { for i in 0..zl {
decoders.push(SourceBlockDecoder::new(i as u8, config.symbol_size(), kl as u64 * config.symbol_size() as u64)); decoders.push(SourceBlockDecoder::new(
i as u8,
config.symbol_size(),
kl as u64 * config.symbol_size() as u64,
));
} }
for i in 0..zs { for i in 0..zs {
decoders.push(SourceBlockDecoder::new(i as u8, config.symbol_size(), ks as u64 * config.symbol_size() as u64)); decoders.push(SourceBlockDecoder::new(
i as u8,
config.symbol_size(),
ks as u64 * config.symbol_size() as u64,
));
} }
Decoder { Decoder {
config, config,
block_decoders: decoders, block_decoders: decoders,
blocks: vec![None; (zl + zs) as usize] blocks: vec![None; (zl + zs) as usize],
} }
} }
@ -46,7 +54,6 @@ impl Decoder {
let block_number = packet.payload_id().source_block_number() as usize; let block_number = packet.payload_id().source_block_number() as usize;
if self.blocks[block_number].is_none() { if self.blocks[block_number].is_none() {
self.blocks[block_number] = self.block_decoders[block_number].decode(packet); self.blocks[block_number] = self.block_decoders[block_number].decode(packet);
} }
for block in self.blocks.iter() { for block in self.blocks.iter() {
if block.is_none() { if block.is_none() {
@ -71,7 +78,7 @@ pub struct SourceBlockDecoder {
repair_packets: Vec<EncodingPacket>, repair_packets: Vec<EncodingPacket>,
received_source_symbols: u32, received_source_symbols: u32,
received_esi: HashSet<u32>, received_esi: HashSet<u32>,
decoded: bool decoded: bool,
} }
impl SourceBlockDecoder { impl SourceBlockDecoder {
@ -89,23 +96,29 @@ impl SourceBlockDecoder {
repair_packets: vec![], repair_packets: vec![],
received_source_symbols: 0, received_source_symbols: 0,
received_esi, received_esi,
decoded: false decoded: false,
} }
} }
pub fn decode(&mut self, packet: EncodingPacket) -> Option<Vec<u8>> { pub fn decode(&mut self, packet: EncodingPacket) -> Option<Vec<u8>> {
assert_eq!(self.source_block_id, packet.payload_id().source_block_number()); assert_eq!(
self.source_block_id,
packet.payload_id().source_block_number()
);
let num_extended_symbols = extended_source_block_symbols(self.source_block_symbols); let num_extended_symbols = extended_source_block_symbols(self.source_block_symbols);
if self.received_esi.insert(packet.payload_id().encoding_symbol_id()) { if self
.received_esi
.insert(packet.payload_id().encoding_symbol_id())
{
if packet.payload_id().encoding_symbol_id() >= num_extended_symbols { if packet.payload_id().encoding_symbol_id() >= num_extended_symbols {
// Repair symbol // Repair symbol
self.repair_packets.push(packet); self.repair_packets.push(packet);
} } else {
else {
// Check that this is not an extended symbol (which aren't explicitly sent) // Check that this is not an extended symbol (which aren't explicitly sent)
assert!(packet.payload_id().encoding_symbol_id() < self.source_block_symbols); assert!(packet.payload_id().encoding_symbol_id() < self.source_block_symbols);
// Source symbol // Source symbol
self.source_symbols[packet.payload_id().encoding_symbol_id() as usize] = Some(Symbol::new(packet.data().clone())); self.source_symbols[packet.payload_id().encoding_symbol_id() as usize] =
Some(Symbol::new(packet.data().clone()));
self.received_source_symbols += 1; self.received_source_symbols += 1;
} }
} }
@ -147,11 +160,13 @@ impl SourceBlockDecoder {
d.push(Symbol::new(repair_packet.data().clone())); d.push(Symbol::new(repair_packet.data().clone()));
} }
let constraint_matrix = generate_constraint_matrix(self.source_block_symbols, &encoded_indices); let constraint_matrix =
let intermediate_symbols = fused_inverse_mul_symbols(constraint_matrix, d, self.source_block_symbols); generate_constraint_matrix(self.source_block_symbols, &encoded_indices);
let intermediate_symbols =
fused_inverse_mul_symbols(constraint_matrix, d, self.source_block_symbols);
if intermediate_symbols == None { if intermediate_symbols == None {
return None return None;
} }
let intermediate_symbols = intermediate_symbols.unwrap(); let intermediate_symbols = intermediate_symbols.unwrap();
@ -159,8 +174,7 @@ impl SourceBlockDecoder {
for i in 0..self.source_block_symbols as usize { for i in 0..self.source_block_symbols as usize {
if self.source_symbols[i] != None { if self.source_symbols[i] != None {
result.extend(self.source_symbols[i].clone().unwrap().bytes()) result.extend(self.source_symbols[i].clone().unwrap().bytes())
} } else {
else {
let rebuilt = self.rebuild_source_symbol(&intermediate_symbols, i as u32); let rebuilt = self.rebuild_source_symbol(&intermediate_symbols, i as u32);
result.extend(rebuilt.bytes()); result.extend(rebuilt.bytes());
} }
@ -172,7 +186,11 @@ impl SourceBlockDecoder {
None None
} }
fn rebuild_source_symbol(&self, intermediate_symbols: &Vec<Symbol>, source_symbol_id: u32) -> Symbol { fn rebuild_source_symbol(
&self,
intermediate_symbols: &Vec<Symbol>,
source_symbol_id: u32,
) -> Symbol {
let tuple = intermediate_tuple(self.source_block_symbols, source_symbol_id); let tuple = intermediate_tuple(self.source_block_symbols, source_symbol_id);
let mut rebuilt = Symbol::zero(self.symbol_size as usize); let mut rebuilt = Symbol::zero(self.symbol_size as usize);
@ -182,4 +200,3 @@ impl SourceBlockDecoder {
rebuilt rebuilt
} }
} }

@ -1,63 +1,77 @@
use crate::base::intermediate_tuple;
use crate::base::partition;
use crate::base::EncodingPacket; use crate::base::EncodingPacket;
use crate::base::PayloadId; use crate::base::PayloadId;
use crate::systematic_constants::extended_source_block_symbols; use crate::constraint_matrix::generate_constraint_matrix;
use crate::systematic_constants::num_pi_symbols; use crate::pi_solver::fused_inverse_mul_symbols;
use crate::symbol::Symbol; use crate::symbol::Symbol;
use crate::systematic_constants::num_lt_symbols;
use crate::systematic_constants::calculate_p1; use crate::systematic_constants::calculate_p1;
use crate::systematic_constants::extended_source_block_symbols;
use crate::systematic_constants::num_hdpc_symbols;
use crate::systematic_constants::num_intermediate_symbols; use crate::systematic_constants::num_intermediate_symbols;
use crate::systematic_constants::num_ldpc_symbols; use crate::systematic_constants::num_ldpc_symbols;
use crate::systematic_constants::num_hdpc_symbols; use crate::systematic_constants::num_lt_symbols;
use crate::constraint_matrix::generate_constraint_matrix; use crate::systematic_constants::num_pi_symbols;
use crate::base::intermediate_tuple;
use crate::pi_solver::fused_inverse_mul_symbols;
use crate::base::partition;
use crate::ObjectTransmissionInformation; use crate::ObjectTransmissionInformation;
pub struct Encoder { pub struct Encoder {
config: ObjectTransmissionInformation, config: ObjectTransmissionInformation,
blocks: Vec<SourceBlockEncoder> blocks: Vec<SourceBlockEncoder>,
} }
impl Encoder { impl Encoder {
pub fn with_defaults(data: &[u8], maximum_transmission_unit: u16) -> Encoder { pub fn with_defaults(data: &[u8], maximum_transmission_unit: u16) -> Encoder {
let config = ObjectTransmissionInformation::with_defaults(data.len() as u64, maximum_transmission_unit); let config = ObjectTransmissionInformation::with_defaults(
data.len() as u64,
maximum_transmission_unit,
);
let kt = (config.transfer_length() as f64 / config.symbol_size() as f64).ceil() as u32; let kt = (config.transfer_length() as f64 / config.symbol_size() as f64).ceil() as u32;
let (kl, ks, zl, zs) = partition(kt, config.source_blocks() as u32); let (kl, ks, zl, zs) = partition(kt, config.source_blocks() as u32);
// TODO: support subblocks // TODO: support subblocks
assert_eq!(1, config.sub_blocks()); assert_eq!(1, config.sub_blocks());
// let (tl, ts, nl, ns) = partition((config.symbol_size() / config.alignment() as u16) as u32, config.sub_blocks() as u32); // let (tl, ts, nl, ns) = partition((config.symbol_size() / config.alignment() as u16) as u32, config.sub_blocks() as u32);
let mut data_index = 0; let mut data_index = 0;
let mut blocks = vec![]; let mut blocks = vec![];
for i in 0..zl { for i in 0..zl {
let offset = kl as usize * config.symbol_size() as usize; let offset = kl as usize * config.symbol_size() as usize;
blocks.push(SourceBlockEncoder::new(i as u8, config.symbol_size(), &data[data_index..(data_index + offset)])); blocks.push(SourceBlockEncoder::new(
i as u8,
config.symbol_size(),
&data[data_index..(data_index + offset)],
));
data_index += offset; data_index += offset;
} }
for i in 0..zs { for i in 0..zs {
let offset = ks as usize * config.symbol_size() as usize; let offset = ks as usize * config.symbol_size() as usize;
if data_index + offset < data.len() { if data_index + offset < data.len() {
blocks.push(SourceBlockEncoder::new(i as u8, config.symbol_size(), &data[data_index..(data_index + offset)])); blocks.push(SourceBlockEncoder::new(
} i as u8,
else { config.symbol_size(),
&data[data_index..(data_index + offset)],
));
} else {
// Should only be possible when Kt * T > F. See third to last paragraph in section 4.4.1.2 // Should only be possible when Kt * T > F. See third to last paragraph in section 4.4.1.2
assert!(kt as usize * config.symbol_size() as usize > data.len()); assert!(kt as usize * config.symbol_size() as usize > data.len());
// Zero pad the last symbol // Zero pad the last symbol
let mut padded = Vec::from(&data[data_index..]); let mut padded = Vec::from(&data[data_index..]);
padded.extend(vec![0; kt as usize * config.symbol_size() as usize - data.len()]); padded.extend(vec![
blocks.push(SourceBlockEncoder::new(i as u8, config.symbol_size(), &padded)); 0;
kt as usize * config.symbol_size() as usize - data.len()
]);
blocks.push(SourceBlockEncoder::new(
i as u8,
config.symbol_size(),
&padded,
));
} }
data_index += offset; data_index += offset;
} }
Encoder { Encoder { config, blocks }
config,
blocks
}
} }
pub fn get_config(&self) -> ObjectTransmissionInformation { pub fn get_config(&self) -> ObjectTransmissionInformation {
@ -81,43 +95,57 @@ impl Encoder {
pub struct SourceBlockEncoder { pub struct SourceBlockEncoder {
source_block_id: u8, source_block_id: u8,
source_symbols: Vec<Symbol>, source_symbols: Vec<Symbol>,
intermediate_symbols: Vec<Symbol> intermediate_symbols: Vec<Symbol>,
} }
impl SourceBlockEncoder { impl SourceBlockEncoder {
pub fn new(source_block_id: u8, symbol_size: u16, data: &[u8]) -> SourceBlockEncoder { pub fn new(source_block_id: u8, symbol_size: u16, data: &[u8]) -> SourceBlockEncoder {
assert_eq!(data.len() % symbol_size as usize, 0); assert_eq!(data.len() % symbol_size as usize, 0);
let source_symbols: Vec<Symbol> = data.chunks(symbol_size as usize) let source_symbols: Vec<Symbol> = data
.chunks(symbol_size as usize)
.map(|x| Symbol::new(Vec::from(x))) .map(|x| Symbol::new(Vec::from(x)))
.collect(); .collect();
let intermediate_symbols = gen_intermediate_symbols(&source_symbols, symbol_size as usize); let intermediate_symbols = gen_intermediate_symbols(&source_symbols, symbol_size as usize);
SourceBlockEncoder { SourceBlockEncoder {
source_block_id, source_block_id,
source_symbols, source_symbols,
intermediate_symbols intermediate_symbols,
} }
} }
pub fn source_packets(&self) -> Vec<EncodingPacket> { pub fn source_packets(&self) -> Vec<EncodingPacket> {
let mut esi: i32 = -1; let mut esi: i32 = -1;
self.source_symbols.iter().map(|symbol| { self.source_symbols
esi += 1; .iter()
EncodingPacket::new( .map(|symbol| {
PayloadId::new(self.source_block_id, esi as u32), esi += 1;
symbol.bytes().clone() EncodingPacket::new(
) PayloadId::new(self.source_block_id, esi as u32),
}).collect() symbol.bytes().clone(),
)
})
.collect()
} }
// See section 5.3.4 // See section 5.3.4
pub fn repair_packets(&self, start_repair_symbol_id: u32, packets: u32) -> Vec<EncodingPacket> { pub fn repair_packets(&self, start_repair_symbol_id: u32, packets: u32) -> Vec<EncodingPacket> {
let start_encoding_symbol_id = start_repair_symbol_id + extended_source_block_symbols(self.source_symbols.len() as u32); let start_encoding_symbol_id = start_repair_symbol_id
+ extended_source_block_symbols(self.source_symbols.len() as u32);
let mut result = vec![]; let mut result = vec![];
for i in 0..packets { for i in 0..packets {
let tuple = intermediate_tuple(self.source_symbols.len() as u32, start_encoding_symbol_id + i); let tuple = intermediate_tuple(
self.source_symbols.len() as u32,
start_encoding_symbol_id + i,
);
result.push(EncodingPacket::new( result.push(EncodingPacket::new(
PayloadId::new(self.source_block_id, start_encoding_symbol_id + i), PayloadId::new(self.source_block_id, start_encoding_symbol_id + i),
enc(self.source_symbols.len() as u32, &self.intermediate_symbols, tuple).bytes().clone() enc(
self.source_symbols.len() as u32,
&self.intermediate_symbols,
tuple,
)
.bytes()
.clone(),
)); ));
} }
result result
@ -151,9 +179,11 @@ fn gen_intermediate_symbols(source_block: &Vec<Symbol>, symbol_size: usize) -> V
} }
// Enc[] function, as defined in section 5.3.5.3 // Enc[] function, as defined in section 5.3.5.3
fn enc(source_block_symbols: u32, fn enc(
intermediate_symbols: &Vec<Symbol>, source_block_symbols: u32,
source_tuple: (u32, u32, u32, u32, u32, u32)) -> Symbol { intermediate_symbols: &Vec<Symbol>,
source_tuple: (u32, u32, u32, u32, u32, u32),
) -> Symbol {
let w = num_lt_symbols(source_block_symbols); let w = num_lt_symbols(source_block_symbols);
let p = num_pi_symbols(source_block_symbols); let p = num_pi_symbols(source_block_symbols);
let p1 = calculate_p1(source_block_symbols); let p1 = calculate_p1(source_block_symbols);
@ -192,10 +222,10 @@ fn enc(source_block_symbols: u32,
mod tests { mod tests {
use rand::Rng; use rand::Rng;
use crate::symbol::Symbol;
use crate::encoder::enc;
use crate::base::intermediate_tuple; use crate::base::intermediate_tuple;
use crate::encoder::enc;
use crate::encoder::gen_intermediate_symbols; use crate::encoder::gen_intermediate_symbols;
use crate::symbol::Symbol;
use crate::systematic_constants::num_ldpc_symbols; use crate::systematic_constants::num_ldpc_symbols;
use crate::systematic_constants::num_lt_symbols; use crate::systematic_constants::num_lt_symbols;
use crate::systematic_constants::num_pi_symbols; use crate::systematic_constants::num_pi_symbols;

@ -1,32 +1,32 @@
mod util;
mod arraymap; mod arraymap;
mod systematic_constants; mod base;
mod rng; mod constraint_matrix;
mod decoder;
mod encoder;
mod matrix;
mod octet; mod octet;
mod octets; mod octets;
mod symbol;
mod matrix;
mod constraint_matrix;
mod base;
mod pi_solver; mod pi_solver;
mod encoder; mod rng;
mod decoder; mod symbol;
mod systematic_constants;
mod util;
pub use crate::base::PayloadId;
pub use crate::base::EncodingPacket; pub use crate::base::EncodingPacket;
pub use crate::base::ObjectTransmissionInformation; pub use crate::base::ObjectTransmissionInformation;
pub use crate::encoder::SourceBlockEncoder; pub use crate::base::PayloadId;
pub use crate::encoder::Encoder;
pub use crate::decoder::SourceBlockDecoder;
pub use crate::decoder::Decoder; pub use crate::decoder::Decoder;
pub use crate::decoder::SourceBlockDecoder;
pub use crate::encoder::Encoder;
pub use crate::encoder::SourceBlockEncoder;
#[cfg(feature = "benchmarking")] #[cfg(feature = "benchmarking")]
pub use crate::constraint_matrix::generate_constraint_matrix; pub use crate::constraint_matrix::generate_constraint_matrix;
#[cfg(feature = "benchmarking")] #[cfg(feature = "benchmarking")]
pub use crate::systematic_constants::extended_source_block_symbols; pub use crate::octet::Octet;
#[cfg(feature = "benchmarking")] #[cfg(feature = "benchmarking")]
pub use crate::pi_solver::IntermediateSymbolDecoder; pub use crate::pi_solver::IntermediateSymbolDecoder;
#[cfg(feature = "benchmarking")] #[cfg(feature = "benchmarking")]
pub use crate::octet::Octet;
#[cfg(feature = "benchmarking")]
pub use crate::symbol::Symbol; pub use crate::symbol::Symbol;
#[cfg(feature = "benchmarking")]
pub use crate::systematic_constants::extended_source_block_symbols;

@ -1,14 +1,14 @@
use std::ops::Mul;
use crate::octet::Octet; use crate::octet::Octet;
use crate::octets::fused_addassign_mul_scalar;
use crate::octets::add_assign; use crate::octets::add_assign;
use crate::octets::fused_addassign_mul_scalar;
use crate::util::get_both_indices; use crate::util::get_both_indices;
use std::ops::Mul;
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub struct OctetMatrix { pub struct OctetMatrix {
height: usize, height: usize,
width: usize, width: usize,
elements: Vec<Vec<u8>> elements: Vec<Vec<u8>>,
} }
impl OctetMatrix { impl OctetMatrix {
@ -20,7 +20,7 @@ impl OctetMatrix {
OctetMatrix { OctetMatrix {
height, height,
width, width,
elements elements,
} }
} }
@ -48,7 +48,7 @@ impl OctetMatrix {
Octet::new(self.elements[i][j]) Octet::new(self.elements[i][j])
} }
pub fn swap_rows(&mut self, i: usize, j:usize) { pub fn swap_rows(&mut self, i: usize, j: usize) {
self.elements.swap(i, j); self.elements.swap(i, j);
} }
@ -73,8 +73,7 @@ impl OctetMatrix {
} }
if scalar == Octet::one() { if scalar == Octet::one() {
add_assign(&mut temp[row], &self.elements[i]); add_assign(&mut temp[row], &self.elements[i]);
} } else {
else {
fused_addassign_mul_scalar(&mut temp[row], &self.elements[i], &scalar); fused_addassign_mul_scalar(&mut temp[row], &self.elements[i], &scalar);
} }
} }
@ -90,8 +89,7 @@ impl OctetMatrix {
if *scalar == Octet::one() { if *scalar == Octet::one() {
add_assign(dest_row, temp_row); add_assign(dest_row, temp_row);
} } else {
else {
fused_addassign_mul_scalar(dest_row, temp_row, scalar); fused_addassign_mul_scalar(dest_row, temp_row, scalar);
} }
} }
@ -122,9 +120,12 @@ impl<'a, 'b> Mul<&'b OctetMatrix> for &'a OctetMatrix {
} }
if scalar == Octet::one() { if scalar == Octet::one() {
add_assign(&mut result.elements[row], &rhs.elements[i]); add_assign(&mut result.elements[row], &rhs.elements[i]);
} } else {
else { fused_addassign_mul_scalar(
fused_addassign_mul_scalar(&mut result.elements[row], &rhs.elements[i], &scalar); &mut result.elements[row],
&rhs.elements[i],
&scalar,
);
} }
} }
} }

@ -1,8 +1,8 @@
use std::ops::Add; use std::ops::Add;
use std::ops::Mul;
use std::ops::Div;
use std::ops::Sub;
use std::ops::AddAssign; use std::ops::AddAssign;
use std::ops::Div;
use std::ops::Mul;
use std::ops::Sub;
// As defined in section 5.7.3 // As defined in section 5.7.3
#[rustfmt::skip] #[rustfmt::skip]
@ -88,7 +88,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(7), calculate_octet_mul_hi_table_inner(7),
calculate_octet_mul_hi_table_inner(8), calculate_octet_mul_hi_table_inner(8),
calculate_octet_mul_hi_table_inner(9), calculate_octet_mul_hi_table_inner(9),
calculate_octet_mul_hi_table_inner(10), calculate_octet_mul_hi_table_inner(10),
calculate_octet_mul_hi_table_inner(11), calculate_octet_mul_hi_table_inner(11),
calculate_octet_mul_hi_table_inner(12), calculate_octet_mul_hi_table_inner(12),
@ -99,7 +98,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(17), calculate_octet_mul_hi_table_inner(17),
calculate_octet_mul_hi_table_inner(18), calculate_octet_mul_hi_table_inner(18),
calculate_octet_mul_hi_table_inner(19), calculate_octet_mul_hi_table_inner(19),
calculate_octet_mul_hi_table_inner(20), calculate_octet_mul_hi_table_inner(20),
calculate_octet_mul_hi_table_inner(21), calculate_octet_mul_hi_table_inner(21),
calculate_octet_mul_hi_table_inner(22), calculate_octet_mul_hi_table_inner(22),
@ -110,7 +108,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(27), calculate_octet_mul_hi_table_inner(27),
calculate_octet_mul_hi_table_inner(28), calculate_octet_mul_hi_table_inner(28),
calculate_octet_mul_hi_table_inner(29), calculate_octet_mul_hi_table_inner(29),
calculate_octet_mul_hi_table_inner(30), calculate_octet_mul_hi_table_inner(30),
calculate_octet_mul_hi_table_inner(31), calculate_octet_mul_hi_table_inner(31),
calculate_octet_mul_hi_table_inner(32), calculate_octet_mul_hi_table_inner(32),
@ -121,7 +118,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(37), calculate_octet_mul_hi_table_inner(37),
calculate_octet_mul_hi_table_inner(38), calculate_octet_mul_hi_table_inner(38),
calculate_octet_mul_hi_table_inner(39), calculate_octet_mul_hi_table_inner(39),
calculate_octet_mul_hi_table_inner(40), calculate_octet_mul_hi_table_inner(40),
calculate_octet_mul_hi_table_inner(41), calculate_octet_mul_hi_table_inner(41),
calculate_octet_mul_hi_table_inner(42), calculate_octet_mul_hi_table_inner(42),
@ -132,7 +128,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(47), calculate_octet_mul_hi_table_inner(47),
calculate_octet_mul_hi_table_inner(48), calculate_octet_mul_hi_table_inner(48),
calculate_octet_mul_hi_table_inner(49), calculate_octet_mul_hi_table_inner(49),
calculate_octet_mul_hi_table_inner(50), calculate_octet_mul_hi_table_inner(50),
calculate_octet_mul_hi_table_inner(51), calculate_octet_mul_hi_table_inner(51),
calculate_octet_mul_hi_table_inner(52), calculate_octet_mul_hi_table_inner(52),
@ -143,7 +138,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(57), calculate_octet_mul_hi_table_inner(57),
calculate_octet_mul_hi_table_inner(58), calculate_octet_mul_hi_table_inner(58),
calculate_octet_mul_hi_table_inner(59), calculate_octet_mul_hi_table_inner(59),
calculate_octet_mul_hi_table_inner(60), calculate_octet_mul_hi_table_inner(60),
calculate_octet_mul_hi_table_inner(61), calculate_octet_mul_hi_table_inner(61),
calculate_octet_mul_hi_table_inner(62), calculate_octet_mul_hi_table_inner(62),
@ -154,7 +148,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(67), calculate_octet_mul_hi_table_inner(67),
calculate_octet_mul_hi_table_inner(68), calculate_octet_mul_hi_table_inner(68),
calculate_octet_mul_hi_table_inner(69), calculate_octet_mul_hi_table_inner(69),
calculate_octet_mul_hi_table_inner(70), calculate_octet_mul_hi_table_inner(70),
calculate_octet_mul_hi_table_inner(71), calculate_octet_mul_hi_table_inner(71),
calculate_octet_mul_hi_table_inner(72), calculate_octet_mul_hi_table_inner(72),
@ -165,7 +158,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(77), calculate_octet_mul_hi_table_inner(77),
calculate_octet_mul_hi_table_inner(78), calculate_octet_mul_hi_table_inner(78),
calculate_octet_mul_hi_table_inner(79), calculate_octet_mul_hi_table_inner(79),
calculate_octet_mul_hi_table_inner(80), calculate_octet_mul_hi_table_inner(80),
calculate_octet_mul_hi_table_inner(81), calculate_octet_mul_hi_table_inner(81),
calculate_octet_mul_hi_table_inner(82), calculate_octet_mul_hi_table_inner(82),
@ -176,7 +168,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(87), calculate_octet_mul_hi_table_inner(87),
calculate_octet_mul_hi_table_inner(88), calculate_octet_mul_hi_table_inner(88),
calculate_octet_mul_hi_table_inner(89), calculate_octet_mul_hi_table_inner(89),
calculate_octet_mul_hi_table_inner(90), calculate_octet_mul_hi_table_inner(90),
calculate_octet_mul_hi_table_inner(91), calculate_octet_mul_hi_table_inner(91),
calculate_octet_mul_hi_table_inner(92), calculate_octet_mul_hi_table_inner(92),
@ -187,7 +178,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(97), calculate_octet_mul_hi_table_inner(97),
calculate_octet_mul_hi_table_inner(98), calculate_octet_mul_hi_table_inner(98),
calculate_octet_mul_hi_table_inner(99), calculate_octet_mul_hi_table_inner(99),
calculate_octet_mul_hi_table_inner(100), calculate_octet_mul_hi_table_inner(100),
calculate_octet_mul_hi_table_inner(101), calculate_octet_mul_hi_table_inner(101),
calculate_octet_mul_hi_table_inner(102), calculate_octet_mul_hi_table_inner(102),
@ -198,7 +188,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(107), calculate_octet_mul_hi_table_inner(107),
calculate_octet_mul_hi_table_inner(108), calculate_octet_mul_hi_table_inner(108),
calculate_octet_mul_hi_table_inner(109), calculate_octet_mul_hi_table_inner(109),
calculate_octet_mul_hi_table_inner(110), calculate_octet_mul_hi_table_inner(110),
calculate_octet_mul_hi_table_inner(111), calculate_octet_mul_hi_table_inner(111),
calculate_octet_mul_hi_table_inner(112), calculate_octet_mul_hi_table_inner(112),
@ -209,7 +198,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(117), calculate_octet_mul_hi_table_inner(117),
calculate_octet_mul_hi_table_inner(118), calculate_octet_mul_hi_table_inner(118),
calculate_octet_mul_hi_table_inner(119), calculate_octet_mul_hi_table_inner(119),
calculate_octet_mul_hi_table_inner(120), calculate_octet_mul_hi_table_inner(120),
calculate_octet_mul_hi_table_inner(121), calculate_octet_mul_hi_table_inner(121),
calculate_octet_mul_hi_table_inner(122), calculate_octet_mul_hi_table_inner(122),
@ -220,7 +208,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(127), calculate_octet_mul_hi_table_inner(127),
calculate_octet_mul_hi_table_inner(128), calculate_octet_mul_hi_table_inner(128),
calculate_octet_mul_hi_table_inner(129), calculate_octet_mul_hi_table_inner(129),
calculate_octet_mul_hi_table_inner(130), calculate_octet_mul_hi_table_inner(130),
calculate_octet_mul_hi_table_inner(131), calculate_octet_mul_hi_table_inner(131),
calculate_octet_mul_hi_table_inner(132), calculate_octet_mul_hi_table_inner(132),
@ -231,7 +218,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(137), calculate_octet_mul_hi_table_inner(137),
calculate_octet_mul_hi_table_inner(138), calculate_octet_mul_hi_table_inner(138),
calculate_octet_mul_hi_table_inner(139), calculate_octet_mul_hi_table_inner(139),
calculate_octet_mul_hi_table_inner(140), calculate_octet_mul_hi_table_inner(140),
calculate_octet_mul_hi_table_inner(141), calculate_octet_mul_hi_table_inner(141),
calculate_octet_mul_hi_table_inner(142), calculate_octet_mul_hi_table_inner(142),
@ -242,7 +228,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(147), calculate_octet_mul_hi_table_inner(147),
calculate_octet_mul_hi_table_inner(148), calculate_octet_mul_hi_table_inner(148),
calculate_octet_mul_hi_table_inner(149), calculate_octet_mul_hi_table_inner(149),
calculate_octet_mul_hi_table_inner(150), calculate_octet_mul_hi_table_inner(150),
calculate_octet_mul_hi_table_inner(151), calculate_octet_mul_hi_table_inner(151),
calculate_octet_mul_hi_table_inner(152), calculate_octet_mul_hi_table_inner(152),
@ -253,7 +238,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(157), calculate_octet_mul_hi_table_inner(157),
calculate_octet_mul_hi_table_inner(158), calculate_octet_mul_hi_table_inner(158),
calculate_octet_mul_hi_table_inner(159), calculate_octet_mul_hi_table_inner(159),
calculate_octet_mul_hi_table_inner(160), calculate_octet_mul_hi_table_inner(160),
calculate_octet_mul_hi_table_inner(161), calculate_octet_mul_hi_table_inner(161),
calculate_octet_mul_hi_table_inner(162), calculate_octet_mul_hi_table_inner(162),
@ -264,7 +248,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(167), calculate_octet_mul_hi_table_inner(167),
calculate_octet_mul_hi_table_inner(168), calculate_octet_mul_hi_table_inner(168),
calculate_octet_mul_hi_table_inner(169), calculate_octet_mul_hi_table_inner(169),
calculate_octet_mul_hi_table_inner(170), calculate_octet_mul_hi_table_inner(170),
calculate_octet_mul_hi_table_inner(171), calculate_octet_mul_hi_table_inner(171),
calculate_octet_mul_hi_table_inner(172), calculate_octet_mul_hi_table_inner(172),
@ -275,7 +258,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(177), calculate_octet_mul_hi_table_inner(177),
calculate_octet_mul_hi_table_inner(178), calculate_octet_mul_hi_table_inner(178),
calculate_octet_mul_hi_table_inner(179), calculate_octet_mul_hi_table_inner(179),
calculate_octet_mul_hi_table_inner(180), calculate_octet_mul_hi_table_inner(180),
calculate_octet_mul_hi_table_inner(181), calculate_octet_mul_hi_table_inner(181),
calculate_octet_mul_hi_table_inner(182), calculate_octet_mul_hi_table_inner(182),
@ -286,7 +268,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(187), calculate_octet_mul_hi_table_inner(187),
calculate_octet_mul_hi_table_inner(188), calculate_octet_mul_hi_table_inner(188),
calculate_octet_mul_hi_table_inner(189), calculate_octet_mul_hi_table_inner(189),
calculate_octet_mul_hi_table_inner(190), calculate_octet_mul_hi_table_inner(190),
calculate_octet_mul_hi_table_inner(191), calculate_octet_mul_hi_table_inner(191),
calculate_octet_mul_hi_table_inner(192), calculate_octet_mul_hi_table_inner(192),
@ -297,7 +278,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(197), calculate_octet_mul_hi_table_inner(197),
calculate_octet_mul_hi_table_inner(198), calculate_octet_mul_hi_table_inner(198),
calculate_octet_mul_hi_table_inner(199), calculate_octet_mul_hi_table_inner(199),
calculate_octet_mul_hi_table_inner(200), calculate_octet_mul_hi_table_inner(200),
calculate_octet_mul_hi_table_inner(201), calculate_octet_mul_hi_table_inner(201),
calculate_octet_mul_hi_table_inner(202), calculate_octet_mul_hi_table_inner(202),
@ -308,7 +288,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(207), calculate_octet_mul_hi_table_inner(207),
calculate_octet_mul_hi_table_inner(208), calculate_octet_mul_hi_table_inner(208),
calculate_octet_mul_hi_table_inner(209), calculate_octet_mul_hi_table_inner(209),
calculate_octet_mul_hi_table_inner(210), calculate_octet_mul_hi_table_inner(210),
calculate_octet_mul_hi_table_inner(211), calculate_octet_mul_hi_table_inner(211),
calculate_octet_mul_hi_table_inner(212), calculate_octet_mul_hi_table_inner(212),
@ -319,7 +298,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(217), calculate_octet_mul_hi_table_inner(217),
calculate_octet_mul_hi_table_inner(218), calculate_octet_mul_hi_table_inner(218),
calculate_octet_mul_hi_table_inner(219), calculate_octet_mul_hi_table_inner(219),
calculate_octet_mul_hi_table_inner(220), calculate_octet_mul_hi_table_inner(220),
calculate_octet_mul_hi_table_inner(221), calculate_octet_mul_hi_table_inner(221),
calculate_octet_mul_hi_table_inner(222), calculate_octet_mul_hi_table_inner(222),
@ -330,7 +308,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(227), calculate_octet_mul_hi_table_inner(227),
calculate_octet_mul_hi_table_inner(228), calculate_octet_mul_hi_table_inner(228),
calculate_octet_mul_hi_table_inner(229), calculate_octet_mul_hi_table_inner(229),
calculate_octet_mul_hi_table_inner(230), calculate_octet_mul_hi_table_inner(230),
calculate_octet_mul_hi_table_inner(231), calculate_octet_mul_hi_table_inner(231),
calculate_octet_mul_hi_table_inner(232), calculate_octet_mul_hi_table_inner(232),
@ -341,7 +318,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(237), calculate_octet_mul_hi_table_inner(237),
calculate_octet_mul_hi_table_inner(238), calculate_octet_mul_hi_table_inner(238),
calculate_octet_mul_hi_table_inner(239), calculate_octet_mul_hi_table_inner(239),
calculate_octet_mul_hi_table_inner(240), calculate_octet_mul_hi_table_inner(240),
calculate_octet_mul_hi_table_inner(241), calculate_octet_mul_hi_table_inner(241),
calculate_octet_mul_hi_table_inner(242), calculate_octet_mul_hi_table_inner(242),
@ -352,7 +328,6 @@ const fn calculate_octet_mul_hi_table() -> [[u8; 32]; 256] {
calculate_octet_mul_hi_table_inner(247), calculate_octet_mul_hi_table_inner(247),
calculate_octet_mul_hi_table_inner(248), calculate_octet_mul_hi_table_inner(248),
calculate_octet_mul_hi_table_inner(249), calculate_octet_mul_hi_table_inner(249),
calculate_octet_mul_hi_table_inner(250), calculate_octet_mul_hi_table_inner(250),
calculate_octet_mul_hi_table_inner(251), calculate_octet_mul_hi_table_inner(251),
calculate_octet_mul_hi_table_inner(252), calculate_octet_mul_hi_table_inner(252),
@ -368,42 +343,35 @@ const fn calculate_octet_mul_hi_table_inner(x: usize) -> [u8; 32] {
const_mul(x, 1 << 4), const_mul(x, 1 << 4),
const_mul(x, 2 << 4), const_mul(x, 2 << 4),
const_mul(x, 3 << 4), const_mul(x, 3 << 4),
const_mul(x, 4 << 4), const_mul(x, 4 << 4),
const_mul(x, 5 << 4), const_mul(x, 5 << 4),
const_mul(x, 6 << 4), const_mul(x, 6 << 4),
const_mul(x, 7 << 4), const_mul(x, 7 << 4),
const_mul(x, 8 << 4), const_mul(x, 8 << 4),
const_mul(x, 9 << 4), const_mul(x, 9 << 4),
const_mul(x, 10 << 4), const_mul(x, 10 << 4),
const_mul(x, 11 << 4), const_mul(x, 11 << 4),
const_mul(x, 12 << 4), const_mul(x, 12 << 4),
const_mul(x, 13 << 4), const_mul(x, 13 << 4),
const_mul(x, 14 << 4), const_mul(x, 14 << 4),
const_mul(x, 15 << 4), const_mul(x, 15 << 4),
0, 0,
const_mul(x, 1 << 4), const_mul(x, 1 << 4),
const_mul(x, 2 << 4), const_mul(x, 2 << 4),
const_mul(x, 3 << 4), const_mul(x, 3 << 4),
const_mul(x, 4 << 4), const_mul(x, 4 << 4),
const_mul(x, 5 << 4), const_mul(x, 5 << 4),
const_mul(x, 6 << 4), const_mul(x, 6 << 4),
const_mul(x, 7 << 4), const_mul(x, 7 << 4),
const_mul(x, 8 << 4), const_mul(x, 8 << 4),
const_mul(x, 9 << 4), const_mul(x, 9 << 4),
const_mul(x, 10 << 4), const_mul(x, 10 << 4),
const_mul(x, 11 << 4), const_mul(x, 11 << 4),
const_mul(x, 12 << 4), const_mul(x, 12 << 4),
const_mul(x, 13 << 4), const_mul(x, 13 << 4),
const_mul(x, 14 << 4), const_mul(x, 14 << 4),
const_mul(x, 15 << 4), const_mul(x, 15 << 4),
] ];
} }
const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] { const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
@ -418,7 +386,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(7), calculate_octet_mul_low_table_inner(7),
calculate_octet_mul_low_table_inner(8), calculate_octet_mul_low_table_inner(8),
calculate_octet_mul_low_table_inner(9), calculate_octet_mul_low_table_inner(9),
calculate_octet_mul_low_table_inner(10), calculate_octet_mul_low_table_inner(10),
calculate_octet_mul_low_table_inner(11), calculate_octet_mul_low_table_inner(11),
calculate_octet_mul_low_table_inner(12), calculate_octet_mul_low_table_inner(12),
@ -429,7 +396,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(17), calculate_octet_mul_low_table_inner(17),
calculate_octet_mul_low_table_inner(18), calculate_octet_mul_low_table_inner(18),
calculate_octet_mul_low_table_inner(19), calculate_octet_mul_low_table_inner(19),
calculate_octet_mul_low_table_inner(20), calculate_octet_mul_low_table_inner(20),
calculate_octet_mul_low_table_inner(21), calculate_octet_mul_low_table_inner(21),
calculate_octet_mul_low_table_inner(22), calculate_octet_mul_low_table_inner(22),
@ -440,7 +406,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(27), calculate_octet_mul_low_table_inner(27),
calculate_octet_mul_low_table_inner(28), calculate_octet_mul_low_table_inner(28),
calculate_octet_mul_low_table_inner(29), calculate_octet_mul_low_table_inner(29),
calculate_octet_mul_low_table_inner(30), calculate_octet_mul_low_table_inner(30),
calculate_octet_mul_low_table_inner(31), calculate_octet_mul_low_table_inner(31),
calculate_octet_mul_low_table_inner(32), calculate_octet_mul_low_table_inner(32),
@ -451,7 +416,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(37), calculate_octet_mul_low_table_inner(37),
calculate_octet_mul_low_table_inner(38), calculate_octet_mul_low_table_inner(38),
calculate_octet_mul_low_table_inner(39), calculate_octet_mul_low_table_inner(39),
calculate_octet_mul_low_table_inner(40), calculate_octet_mul_low_table_inner(40),
calculate_octet_mul_low_table_inner(41), calculate_octet_mul_low_table_inner(41),
calculate_octet_mul_low_table_inner(42), calculate_octet_mul_low_table_inner(42),
@ -462,7 +426,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(47), calculate_octet_mul_low_table_inner(47),
calculate_octet_mul_low_table_inner(48), calculate_octet_mul_low_table_inner(48),
calculate_octet_mul_low_table_inner(49), calculate_octet_mul_low_table_inner(49),
calculate_octet_mul_low_table_inner(50), calculate_octet_mul_low_table_inner(50),
calculate_octet_mul_low_table_inner(51), calculate_octet_mul_low_table_inner(51),
calculate_octet_mul_low_table_inner(52), calculate_octet_mul_low_table_inner(52),
@ -473,7 +436,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(57), calculate_octet_mul_low_table_inner(57),
calculate_octet_mul_low_table_inner(58), calculate_octet_mul_low_table_inner(58),
calculate_octet_mul_low_table_inner(59), calculate_octet_mul_low_table_inner(59),
calculate_octet_mul_low_table_inner(60), calculate_octet_mul_low_table_inner(60),
calculate_octet_mul_low_table_inner(61), calculate_octet_mul_low_table_inner(61),
calculate_octet_mul_low_table_inner(62), calculate_octet_mul_low_table_inner(62),
@ -484,7 +446,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(67), calculate_octet_mul_low_table_inner(67),
calculate_octet_mul_low_table_inner(68), calculate_octet_mul_low_table_inner(68),
calculate_octet_mul_low_table_inner(69), calculate_octet_mul_low_table_inner(69),
calculate_octet_mul_low_table_inner(70), calculate_octet_mul_low_table_inner(70),
calculate_octet_mul_low_table_inner(71), calculate_octet_mul_low_table_inner(71),
calculate_octet_mul_low_table_inner(72), calculate_octet_mul_low_table_inner(72),
@ -495,7 +456,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(77), calculate_octet_mul_low_table_inner(77),
calculate_octet_mul_low_table_inner(78), calculate_octet_mul_low_table_inner(78),
calculate_octet_mul_low_table_inner(79), calculate_octet_mul_low_table_inner(79),
calculate_octet_mul_low_table_inner(80), calculate_octet_mul_low_table_inner(80),
calculate_octet_mul_low_table_inner(81), calculate_octet_mul_low_table_inner(81),
calculate_octet_mul_low_table_inner(82), calculate_octet_mul_low_table_inner(82),
@ -506,7 +466,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(87), calculate_octet_mul_low_table_inner(87),
calculate_octet_mul_low_table_inner(88), calculate_octet_mul_low_table_inner(88),
calculate_octet_mul_low_table_inner(89), calculate_octet_mul_low_table_inner(89),
calculate_octet_mul_low_table_inner(90), calculate_octet_mul_low_table_inner(90),
calculate_octet_mul_low_table_inner(91), calculate_octet_mul_low_table_inner(91),
calculate_octet_mul_low_table_inner(92), calculate_octet_mul_low_table_inner(92),
@ -517,7 +476,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(97), calculate_octet_mul_low_table_inner(97),
calculate_octet_mul_low_table_inner(98), calculate_octet_mul_low_table_inner(98),
calculate_octet_mul_low_table_inner(99), calculate_octet_mul_low_table_inner(99),
calculate_octet_mul_low_table_inner(100), calculate_octet_mul_low_table_inner(100),
calculate_octet_mul_low_table_inner(101), calculate_octet_mul_low_table_inner(101),
calculate_octet_mul_low_table_inner(102), calculate_octet_mul_low_table_inner(102),
@ -528,7 +486,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(107), calculate_octet_mul_low_table_inner(107),
calculate_octet_mul_low_table_inner(108), calculate_octet_mul_low_table_inner(108),
calculate_octet_mul_low_table_inner(109), calculate_octet_mul_low_table_inner(109),
calculate_octet_mul_low_table_inner(110), calculate_octet_mul_low_table_inner(110),
calculate_octet_mul_low_table_inner(111), calculate_octet_mul_low_table_inner(111),
calculate_octet_mul_low_table_inner(112), calculate_octet_mul_low_table_inner(112),
@ -539,7 +496,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(117), calculate_octet_mul_low_table_inner(117),
calculate_octet_mul_low_table_inner(118), calculate_octet_mul_low_table_inner(118),
calculate_octet_mul_low_table_inner(119), calculate_octet_mul_low_table_inner(119),
calculate_octet_mul_low_table_inner(120), calculate_octet_mul_low_table_inner(120),
calculate_octet_mul_low_table_inner(121), calculate_octet_mul_low_table_inner(121),
calculate_octet_mul_low_table_inner(122), calculate_octet_mul_low_table_inner(122),
@ -550,7 +506,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(127), calculate_octet_mul_low_table_inner(127),
calculate_octet_mul_low_table_inner(128), calculate_octet_mul_low_table_inner(128),
calculate_octet_mul_low_table_inner(129), calculate_octet_mul_low_table_inner(129),
calculate_octet_mul_low_table_inner(130), calculate_octet_mul_low_table_inner(130),
calculate_octet_mul_low_table_inner(131), calculate_octet_mul_low_table_inner(131),
calculate_octet_mul_low_table_inner(132), calculate_octet_mul_low_table_inner(132),
@ -561,7 +516,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(137), calculate_octet_mul_low_table_inner(137),
calculate_octet_mul_low_table_inner(138), calculate_octet_mul_low_table_inner(138),
calculate_octet_mul_low_table_inner(139), calculate_octet_mul_low_table_inner(139),
calculate_octet_mul_low_table_inner(140), calculate_octet_mul_low_table_inner(140),
calculate_octet_mul_low_table_inner(141), calculate_octet_mul_low_table_inner(141),
calculate_octet_mul_low_table_inner(142), calculate_octet_mul_low_table_inner(142),
@ -572,7 +526,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(147), calculate_octet_mul_low_table_inner(147),
calculate_octet_mul_low_table_inner(148), calculate_octet_mul_low_table_inner(148),
calculate_octet_mul_low_table_inner(149), calculate_octet_mul_low_table_inner(149),
calculate_octet_mul_low_table_inner(150), calculate_octet_mul_low_table_inner(150),
calculate_octet_mul_low_table_inner(151), calculate_octet_mul_low_table_inner(151),
calculate_octet_mul_low_table_inner(152), calculate_octet_mul_low_table_inner(152),
@ -583,7 +536,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(157), calculate_octet_mul_low_table_inner(157),
calculate_octet_mul_low_table_inner(158), calculate_octet_mul_low_table_inner(158),
calculate_octet_mul_low_table_inner(159), calculate_octet_mul_low_table_inner(159),
calculate_octet_mul_low_table_inner(160), calculate_octet_mul_low_table_inner(160),
calculate_octet_mul_low_table_inner(161), calculate_octet_mul_low_table_inner(161),
calculate_octet_mul_low_table_inner(162), calculate_octet_mul_low_table_inner(162),
@ -594,7 +546,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(167), calculate_octet_mul_low_table_inner(167),
calculate_octet_mul_low_table_inner(168), calculate_octet_mul_low_table_inner(168),
calculate_octet_mul_low_table_inner(169), calculate_octet_mul_low_table_inner(169),
calculate_octet_mul_low_table_inner(170), calculate_octet_mul_low_table_inner(170),
calculate_octet_mul_low_table_inner(171), calculate_octet_mul_low_table_inner(171),
calculate_octet_mul_low_table_inner(172), calculate_octet_mul_low_table_inner(172),
@ -605,7 +556,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(177), calculate_octet_mul_low_table_inner(177),
calculate_octet_mul_low_table_inner(178), calculate_octet_mul_low_table_inner(178),
calculate_octet_mul_low_table_inner(179), calculate_octet_mul_low_table_inner(179),
calculate_octet_mul_low_table_inner(180), calculate_octet_mul_low_table_inner(180),
calculate_octet_mul_low_table_inner(181), calculate_octet_mul_low_table_inner(181),
calculate_octet_mul_low_table_inner(182), calculate_octet_mul_low_table_inner(182),
@ -616,7 +566,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(187), calculate_octet_mul_low_table_inner(187),
calculate_octet_mul_low_table_inner(188), calculate_octet_mul_low_table_inner(188),
calculate_octet_mul_low_table_inner(189), calculate_octet_mul_low_table_inner(189),
calculate_octet_mul_low_table_inner(190), calculate_octet_mul_low_table_inner(190),
calculate_octet_mul_low_table_inner(191), calculate_octet_mul_low_table_inner(191),
calculate_octet_mul_low_table_inner(192), calculate_octet_mul_low_table_inner(192),
@ -627,7 +576,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(197), calculate_octet_mul_low_table_inner(197),
calculate_octet_mul_low_table_inner(198), calculate_octet_mul_low_table_inner(198),
calculate_octet_mul_low_table_inner(199), calculate_octet_mul_low_table_inner(199),
calculate_octet_mul_low_table_inner(200), calculate_octet_mul_low_table_inner(200),
calculate_octet_mul_low_table_inner(201), calculate_octet_mul_low_table_inner(201),
calculate_octet_mul_low_table_inner(202), calculate_octet_mul_low_table_inner(202),
@ -638,7 +586,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(207), calculate_octet_mul_low_table_inner(207),
calculate_octet_mul_low_table_inner(208), calculate_octet_mul_low_table_inner(208),
calculate_octet_mul_low_table_inner(209), calculate_octet_mul_low_table_inner(209),
calculate_octet_mul_low_table_inner(210), calculate_octet_mul_low_table_inner(210),
calculate_octet_mul_low_table_inner(211), calculate_octet_mul_low_table_inner(211),
calculate_octet_mul_low_table_inner(212), calculate_octet_mul_low_table_inner(212),
@ -649,7 +596,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(217), calculate_octet_mul_low_table_inner(217),
calculate_octet_mul_low_table_inner(218), calculate_octet_mul_low_table_inner(218),
calculate_octet_mul_low_table_inner(219), calculate_octet_mul_low_table_inner(219),
calculate_octet_mul_low_table_inner(220), calculate_octet_mul_low_table_inner(220),
calculate_octet_mul_low_table_inner(221), calculate_octet_mul_low_table_inner(221),
calculate_octet_mul_low_table_inner(222), calculate_octet_mul_low_table_inner(222),
@ -660,7 +606,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(227), calculate_octet_mul_low_table_inner(227),
calculate_octet_mul_low_table_inner(228), calculate_octet_mul_low_table_inner(228),
calculate_octet_mul_low_table_inner(229), calculate_octet_mul_low_table_inner(229),
calculate_octet_mul_low_table_inner(230), calculate_octet_mul_low_table_inner(230),
calculate_octet_mul_low_table_inner(231), calculate_octet_mul_low_table_inner(231),
calculate_octet_mul_low_table_inner(232), calculate_octet_mul_low_table_inner(232),
@ -671,7 +616,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(237), calculate_octet_mul_low_table_inner(237),
calculate_octet_mul_low_table_inner(238), calculate_octet_mul_low_table_inner(238),
calculate_octet_mul_low_table_inner(239), calculate_octet_mul_low_table_inner(239),
calculate_octet_mul_low_table_inner(240), calculate_octet_mul_low_table_inner(240),
calculate_octet_mul_low_table_inner(241), calculate_octet_mul_low_table_inner(241),
calculate_octet_mul_low_table_inner(242), calculate_octet_mul_low_table_inner(242),
@ -682,7 +626,6 @@ const fn calculate_octet_mul_low_table() -> [[u8; 32]; 256] {
calculate_octet_mul_low_table_inner(247), calculate_octet_mul_low_table_inner(247),
calculate_octet_mul_low_table_inner(248), calculate_octet_mul_low_table_inner(248),
calculate_octet_mul_low_table_inner(249), calculate_octet_mul_low_table_inner(249),
calculate_octet_mul_low_table_inner(250), calculate_octet_mul_low_table_inner(250),
calculate_octet_mul_low_table_inner(251), calculate_octet_mul_low_table_inner(251),
calculate_octet_mul_low_table_inner(252), calculate_octet_mul_low_table_inner(252),
@ -698,42 +641,35 @@ const fn calculate_octet_mul_low_table_inner(x: usize) -> [u8; 32] {
const_mul(x, 1), const_mul(x, 1),
const_mul(x, 2), const_mul(x, 2),
const_mul(x, 3), const_mul(x, 3),
const_mul(x, 4), const_mul(x, 4),
const_mul(x, 5), const_mul(x, 5),
const_mul(x, 6), const_mul(x, 6),
const_mul(x, 7), const_mul(x, 7),
const_mul(x, 8), const_mul(x, 8),
const_mul(x, 9), const_mul(x, 9),
const_mul(x, 10), const_mul(x, 10),
const_mul(x, 11), const_mul(x, 11),
const_mul(x, 12), const_mul(x, 12),
const_mul(x, 13), const_mul(x, 13),
const_mul(x, 14), const_mul(x, 14),
const_mul(x, 15), const_mul(x, 15),
0, 0,
const_mul(x, 1), const_mul(x, 1),
const_mul(x, 2), const_mul(x, 2),
const_mul(x, 3), const_mul(x, 3),
const_mul(x, 4), const_mul(x, 4),
const_mul(x, 5), const_mul(x, 5),
const_mul(x, 6), const_mul(x, 6),
const_mul(x, 7), const_mul(x, 7),
const_mul(x, 8), const_mul(x, 8),
const_mul(x, 9), const_mul(x, 9),
const_mul(x, 10), const_mul(x, 10),
const_mul(x, 11), const_mul(x, 11),
const_mul(x, 12), const_mul(x, 12),
const_mul(x, 13), const_mul(x, 13),
const_mul(x, 14), const_mul(x, 14),
const_mul(x, 15), const_mul(x, 15),
] ];
} }
const fn calculate_octet_mul_table() -> [[u8; 256]; 256] { const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
@ -748,7 +684,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(7), calculate_octet_mul_table_inner(7),
calculate_octet_mul_table_inner(8), calculate_octet_mul_table_inner(8),
calculate_octet_mul_table_inner(9), calculate_octet_mul_table_inner(9),
calculate_octet_mul_table_inner(10), calculate_octet_mul_table_inner(10),
calculate_octet_mul_table_inner(11), calculate_octet_mul_table_inner(11),
calculate_octet_mul_table_inner(12), calculate_octet_mul_table_inner(12),
@ -759,7 +694,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(17), calculate_octet_mul_table_inner(17),
calculate_octet_mul_table_inner(18), calculate_octet_mul_table_inner(18),
calculate_octet_mul_table_inner(19), calculate_octet_mul_table_inner(19),
calculate_octet_mul_table_inner(20), calculate_octet_mul_table_inner(20),
calculate_octet_mul_table_inner(21), calculate_octet_mul_table_inner(21),
calculate_octet_mul_table_inner(22), calculate_octet_mul_table_inner(22),
@ -770,7 +704,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(27), calculate_octet_mul_table_inner(27),
calculate_octet_mul_table_inner(28), calculate_octet_mul_table_inner(28),
calculate_octet_mul_table_inner(29), calculate_octet_mul_table_inner(29),
calculate_octet_mul_table_inner(30), calculate_octet_mul_table_inner(30),
calculate_octet_mul_table_inner(31), calculate_octet_mul_table_inner(31),
calculate_octet_mul_table_inner(32), calculate_octet_mul_table_inner(32),
@ -781,7 +714,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(37), calculate_octet_mul_table_inner(37),
calculate_octet_mul_table_inner(38), calculate_octet_mul_table_inner(38),
calculate_octet_mul_table_inner(39), calculate_octet_mul_table_inner(39),
calculate_octet_mul_table_inner(40), calculate_octet_mul_table_inner(40),
calculate_octet_mul_table_inner(41), calculate_octet_mul_table_inner(41),
calculate_octet_mul_table_inner(42), calculate_octet_mul_table_inner(42),
@ -792,7 +724,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(47), calculate_octet_mul_table_inner(47),
calculate_octet_mul_table_inner(48), calculate_octet_mul_table_inner(48),
calculate_octet_mul_table_inner(49), calculate_octet_mul_table_inner(49),
calculate_octet_mul_table_inner(50), calculate_octet_mul_table_inner(50),
calculate_octet_mul_table_inner(51), calculate_octet_mul_table_inner(51),
calculate_octet_mul_table_inner(52), calculate_octet_mul_table_inner(52),
@ -803,7 +734,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(57), calculate_octet_mul_table_inner(57),
calculate_octet_mul_table_inner(58), calculate_octet_mul_table_inner(58),
calculate_octet_mul_table_inner(59), calculate_octet_mul_table_inner(59),
calculate_octet_mul_table_inner(60), calculate_octet_mul_table_inner(60),
calculate_octet_mul_table_inner(61), calculate_octet_mul_table_inner(61),
calculate_octet_mul_table_inner(62), calculate_octet_mul_table_inner(62),
@ -814,7 +744,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(67), calculate_octet_mul_table_inner(67),
calculate_octet_mul_table_inner(68), calculate_octet_mul_table_inner(68),
calculate_octet_mul_table_inner(69), calculate_octet_mul_table_inner(69),
calculate_octet_mul_table_inner(70), calculate_octet_mul_table_inner(70),
calculate_octet_mul_table_inner(71), calculate_octet_mul_table_inner(71),
calculate_octet_mul_table_inner(72), calculate_octet_mul_table_inner(72),
@ -825,7 +754,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(77), calculate_octet_mul_table_inner(77),
calculate_octet_mul_table_inner(78), calculate_octet_mul_table_inner(78),
calculate_octet_mul_table_inner(79), calculate_octet_mul_table_inner(79),
calculate_octet_mul_table_inner(80), calculate_octet_mul_table_inner(80),
calculate_octet_mul_table_inner(81), calculate_octet_mul_table_inner(81),
calculate_octet_mul_table_inner(82), calculate_octet_mul_table_inner(82),
@ -836,7 +764,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(87), calculate_octet_mul_table_inner(87),
calculate_octet_mul_table_inner(88), calculate_octet_mul_table_inner(88),
calculate_octet_mul_table_inner(89), calculate_octet_mul_table_inner(89),
calculate_octet_mul_table_inner(90), calculate_octet_mul_table_inner(90),
calculate_octet_mul_table_inner(91), calculate_octet_mul_table_inner(91),
calculate_octet_mul_table_inner(92), calculate_octet_mul_table_inner(92),
@ -847,7 +774,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(97), calculate_octet_mul_table_inner(97),
calculate_octet_mul_table_inner(98), calculate_octet_mul_table_inner(98),
calculate_octet_mul_table_inner(99), calculate_octet_mul_table_inner(99),
calculate_octet_mul_table_inner(100), calculate_octet_mul_table_inner(100),
calculate_octet_mul_table_inner(101), calculate_octet_mul_table_inner(101),
calculate_octet_mul_table_inner(102), calculate_octet_mul_table_inner(102),
@ -858,7 +784,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(107), calculate_octet_mul_table_inner(107),
calculate_octet_mul_table_inner(108), calculate_octet_mul_table_inner(108),
calculate_octet_mul_table_inner(109), calculate_octet_mul_table_inner(109),
calculate_octet_mul_table_inner(110), calculate_octet_mul_table_inner(110),
calculate_octet_mul_table_inner(111), calculate_octet_mul_table_inner(111),
calculate_octet_mul_table_inner(112), calculate_octet_mul_table_inner(112),
@ -869,7 +794,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(117), calculate_octet_mul_table_inner(117),
calculate_octet_mul_table_inner(118), calculate_octet_mul_table_inner(118),
calculate_octet_mul_table_inner(119), calculate_octet_mul_table_inner(119),
calculate_octet_mul_table_inner(120), calculate_octet_mul_table_inner(120),
calculate_octet_mul_table_inner(121), calculate_octet_mul_table_inner(121),
calculate_octet_mul_table_inner(122), calculate_octet_mul_table_inner(122),
@ -880,7 +804,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(127), calculate_octet_mul_table_inner(127),
calculate_octet_mul_table_inner(128), calculate_octet_mul_table_inner(128),
calculate_octet_mul_table_inner(129), calculate_octet_mul_table_inner(129),
calculate_octet_mul_table_inner(130), calculate_octet_mul_table_inner(130),
calculate_octet_mul_table_inner(131), calculate_octet_mul_table_inner(131),
calculate_octet_mul_table_inner(132), calculate_octet_mul_table_inner(132),
@ -891,7 +814,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(137), calculate_octet_mul_table_inner(137),
calculate_octet_mul_table_inner(138), calculate_octet_mul_table_inner(138),
calculate_octet_mul_table_inner(139), calculate_octet_mul_table_inner(139),
calculate_octet_mul_table_inner(140), calculate_octet_mul_table_inner(140),
calculate_octet_mul_table_inner(141), calculate_octet_mul_table_inner(141),
calculate_octet_mul_table_inner(142), calculate_octet_mul_table_inner(142),
@ -902,7 +824,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(147), calculate_octet_mul_table_inner(147),
calculate_octet_mul_table_inner(148), calculate_octet_mul_table_inner(148),
calculate_octet_mul_table_inner(149), calculate_octet_mul_table_inner(149),
calculate_octet_mul_table_inner(150), calculate_octet_mul_table_inner(150),
calculate_octet_mul_table_inner(151), calculate_octet_mul_table_inner(151),
calculate_octet_mul_table_inner(152), calculate_octet_mul_table_inner(152),
@ -913,7 +834,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(157), calculate_octet_mul_table_inner(157),
calculate_octet_mul_table_inner(158), calculate_octet_mul_table_inner(158),
calculate_octet_mul_table_inner(159), calculate_octet_mul_table_inner(159),
calculate_octet_mul_table_inner(160), calculate_octet_mul_table_inner(160),
calculate_octet_mul_table_inner(161), calculate_octet_mul_table_inner(161),
calculate_octet_mul_table_inner(162), calculate_octet_mul_table_inner(162),
@ -924,7 +844,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(167), calculate_octet_mul_table_inner(167),
calculate_octet_mul_table_inner(168), calculate_octet_mul_table_inner(168),
calculate_octet_mul_table_inner(169), calculate_octet_mul_table_inner(169),
calculate_octet_mul_table_inner(170), calculate_octet_mul_table_inner(170),
calculate_octet_mul_table_inner(171), calculate_octet_mul_table_inner(171),
calculate_octet_mul_table_inner(172), calculate_octet_mul_table_inner(172),
@ -935,7 +854,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(177), calculate_octet_mul_table_inner(177),
calculate_octet_mul_table_inner(178), calculate_octet_mul_table_inner(178),
calculate_octet_mul_table_inner(179), calculate_octet_mul_table_inner(179),
calculate_octet_mul_table_inner(180), calculate_octet_mul_table_inner(180),
calculate_octet_mul_table_inner(181), calculate_octet_mul_table_inner(181),
calculate_octet_mul_table_inner(182), calculate_octet_mul_table_inner(182),
@ -946,7 +864,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(187), calculate_octet_mul_table_inner(187),
calculate_octet_mul_table_inner(188), calculate_octet_mul_table_inner(188),
calculate_octet_mul_table_inner(189), calculate_octet_mul_table_inner(189),
calculate_octet_mul_table_inner(190), calculate_octet_mul_table_inner(190),
calculate_octet_mul_table_inner(191), calculate_octet_mul_table_inner(191),
calculate_octet_mul_table_inner(192), calculate_octet_mul_table_inner(192),
@ -957,7 +874,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(197), calculate_octet_mul_table_inner(197),
calculate_octet_mul_table_inner(198), calculate_octet_mul_table_inner(198),
calculate_octet_mul_table_inner(199), calculate_octet_mul_table_inner(199),
calculate_octet_mul_table_inner(200), calculate_octet_mul_table_inner(200),
calculate_octet_mul_table_inner(201), calculate_octet_mul_table_inner(201),
calculate_octet_mul_table_inner(202), calculate_octet_mul_table_inner(202),
@ -968,7 +884,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(207), calculate_octet_mul_table_inner(207),
calculate_octet_mul_table_inner(208), calculate_octet_mul_table_inner(208),
calculate_octet_mul_table_inner(209), calculate_octet_mul_table_inner(209),
calculate_octet_mul_table_inner(210), calculate_octet_mul_table_inner(210),
calculate_octet_mul_table_inner(211), calculate_octet_mul_table_inner(211),
calculate_octet_mul_table_inner(212), calculate_octet_mul_table_inner(212),
@ -979,7 +894,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(217), calculate_octet_mul_table_inner(217),
calculate_octet_mul_table_inner(218), calculate_octet_mul_table_inner(218),
calculate_octet_mul_table_inner(219), calculate_octet_mul_table_inner(219),
calculate_octet_mul_table_inner(220), calculate_octet_mul_table_inner(220),
calculate_octet_mul_table_inner(221), calculate_octet_mul_table_inner(221),
calculate_octet_mul_table_inner(222), calculate_octet_mul_table_inner(222),
@ -990,7 +904,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(227), calculate_octet_mul_table_inner(227),
calculate_octet_mul_table_inner(228), calculate_octet_mul_table_inner(228),
calculate_octet_mul_table_inner(229), calculate_octet_mul_table_inner(229),
calculate_octet_mul_table_inner(230), calculate_octet_mul_table_inner(230),
calculate_octet_mul_table_inner(231), calculate_octet_mul_table_inner(231),
calculate_octet_mul_table_inner(232), calculate_octet_mul_table_inner(232),
@ -1001,7 +914,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(237), calculate_octet_mul_table_inner(237),
calculate_octet_mul_table_inner(238), calculate_octet_mul_table_inner(238),
calculate_octet_mul_table_inner(239), calculate_octet_mul_table_inner(239),
calculate_octet_mul_table_inner(240), calculate_octet_mul_table_inner(240),
calculate_octet_mul_table_inner(241), calculate_octet_mul_table_inner(241),
calculate_octet_mul_table_inner(242), calculate_octet_mul_table_inner(242),
@ -1012,7 +924,6 @@ const fn calculate_octet_mul_table() -> [[u8; 256]; 256] {
calculate_octet_mul_table_inner(247), calculate_octet_mul_table_inner(247),
calculate_octet_mul_table_inner(248), calculate_octet_mul_table_inner(248),
calculate_octet_mul_table_inner(249), calculate_octet_mul_table_inner(249),
calculate_octet_mul_table_inner(250), calculate_octet_mul_table_inner(250),
calculate_octet_mul_table_inner(251), calculate_octet_mul_table_inner(251),
calculate_octet_mul_table_inner(252), calculate_octet_mul_table_inner(252),
@ -1034,7 +945,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 7), const_mul(x, 7),
const_mul(x, 8), const_mul(x, 8),
const_mul(x, 9), const_mul(x, 9),
const_mul(x, 10), const_mul(x, 10),
const_mul(x, 11), const_mul(x, 11),
const_mul(x, 12), const_mul(x, 12),
@ -1045,7 +955,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 17), const_mul(x, 17),
const_mul(x, 18), const_mul(x, 18),
const_mul(x, 19), const_mul(x, 19),
const_mul(x, 20), const_mul(x, 20),
const_mul(x, 21), const_mul(x, 21),
const_mul(x, 22), const_mul(x, 22),
@ -1056,7 +965,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 27), const_mul(x, 27),
const_mul(x, 28), const_mul(x, 28),
const_mul(x, 29), const_mul(x, 29),
const_mul(x, 30), const_mul(x, 30),
const_mul(x, 31), const_mul(x, 31),
const_mul(x, 32), const_mul(x, 32),
@ -1067,7 +975,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 37), const_mul(x, 37),
const_mul(x, 38), const_mul(x, 38),
const_mul(x, 39), const_mul(x, 39),
const_mul(x, 40), const_mul(x, 40),
const_mul(x, 41), const_mul(x, 41),
const_mul(x, 42), const_mul(x, 42),
@ -1078,7 +985,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 47), const_mul(x, 47),
const_mul(x, 48), const_mul(x, 48),
const_mul(x, 49), const_mul(x, 49),
const_mul(x, 50), const_mul(x, 50),
const_mul(x, 51), const_mul(x, 51),
const_mul(x, 52), const_mul(x, 52),
@ -1089,7 +995,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 57), const_mul(x, 57),
const_mul(x, 58), const_mul(x, 58),
const_mul(x, 59), const_mul(x, 59),
const_mul(x, 60), const_mul(x, 60),
const_mul(x, 61), const_mul(x, 61),
const_mul(x, 62), const_mul(x, 62),
@ -1100,7 +1005,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 67), const_mul(x, 67),
const_mul(x, 68), const_mul(x, 68),
const_mul(x, 69), const_mul(x, 69),
const_mul(x, 70), const_mul(x, 70),
const_mul(x, 71), const_mul(x, 71),
const_mul(x, 72), const_mul(x, 72),
@ -1111,7 +1015,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 77), const_mul(x, 77),
const_mul(x, 78), const_mul(x, 78),
const_mul(x, 79), const_mul(x, 79),
const_mul(x, 80), const_mul(x, 80),
const_mul(x, 81), const_mul(x, 81),
const_mul(x, 82), const_mul(x, 82),
@ -1122,7 +1025,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 87), const_mul(x, 87),
const_mul(x, 88), const_mul(x, 88),
const_mul(x, 89), const_mul(x, 89),
const_mul(x, 90), const_mul(x, 90),
const_mul(x, 91), const_mul(x, 91),
const_mul(x, 92), const_mul(x, 92),
@ -1133,7 +1035,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 97), const_mul(x, 97),
const_mul(x, 98), const_mul(x, 98),
const_mul(x, 99), const_mul(x, 99),
const_mul(x, 100), const_mul(x, 100),
const_mul(x, 101), const_mul(x, 101),
const_mul(x, 102), const_mul(x, 102),
@ -1144,7 +1045,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 107), const_mul(x, 107),
const_mul(x, 108), const_mul(x, 108),
const_mul(x, 109), const_mul(x, 109),
const_mul(x, 110), const_mul(x, 110),
const_mul(x, 111), const_mul(x, 111),
const_mul(x, 112), const_mul(x, 112),
@ -1155,7 +1055,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 117), const_mul(x, 117),
const_mul(x, 118), const_mul(x, 118),
const_mul(x, 119), const_mul(x, 119),
const_mul(x, 120), const_mul(x, 120),
const_mul(x, 121), const_mul(x, 121),
const_mul(x, 122), const_mul(x, 122),
@ -1166,7 +1065,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 127), const_mul(x, 127),
const_mul(x, 128), const_mul(x, 128),
const_mul(x, 129), const_mul(x, 129),
const_mul(x, 130), const_mul(x, 130),
const_mul(x, 131), const_mul(x, 131),
const_mul(x, 132), const_mul(x, 132),
@ -1177,7 +1075,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 137), const_mul(x, 137),
const_mul(x, 138), const_mul(x, 138),
const_mul(x, 139), const_mul(x, 139),
const_mul(x, 140), const_mul(x, 140),
const_mul(x, 141), const_mul(x, 141),
const_mul(x, 142), const_mul(x, 142),
@ -1188,7 +1085,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 147), const_mul(x, 147),
const_mul(x, 148), const_mul(x, 148),
const_mul(x, 149), const_mul(x, 149),
const_mul(x, 150), const_mul(x, 150),
const_mul(x, 151), const_mul(x, 151),
const_mul(x, 152), const_mul(x, 152),
@ -1199,7 +1095,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 157), const_mul(x, 157),
const_mul(x, 158), const_mul(x, 158),
const_mul(x, 159), const_mul(x, 159),
const_mul(x, 160), const_mul(x, 160),
const_mul(x, 161), const_mul(x, 161),
const_mul(x, 162), const_mul(x, 162),
@ -1210,7 +1105,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 167), const_mul(x, 167),
const_mul(x, 168), const_mul(x, 168),
const_mul(x, 169), const_mul(x, 169),
const_mul(x, 170), const_mul(x, 170),
const_mul(x, 171), const_mul(x, 171),
const_mul(x, 172), const_mul(x, 172),
@ -1221,7 +1115,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 177), const_mul(x, 177),
const_mul(x, 178), const_mul(x, 178),
const_mul(x, 179), const_mul(x, 179),
const_mul(x, 180), const_mul(x, 180),
const_mul(x, 181), const_mul(x, 181),
const_mul(x, 182), const_mul(x, 182),
@ -1232,7 +1125,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 187), const_mul(x, 187),
const_mul(x, 188), const_mul(x, 188),
const_mul(x, 189), const_mul(x, 189),
const_mul(x, 190), const_mul(x, 190),
const_mul(x, 191), const_mul(x, 191),
const_mul(x, 192), const_mul(x, 192),
@ -1243,7 +1135,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 197), const_mul(x, 197),
const_mul(x, 198), const_mul(x, 198),
const_mul(x, 199), const_mul(x, 199),
const_mul(x, 200), const_mul(x, 200),
const_mul(x, 201), const_mul(x, 201),
const_mul(x, 202), const_mul(x, 202),
@ -1254,7 +1145,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 207), const_mul(x, 207),
const_mul(x, 208), const_mul(x, 208),
const_mul(x, 209), const_mul(x, 209),
const_mul(x, 210), const_mul(x, 210),
const_mul(x, 211), const_mul(x, 211),
const_mul(x, 212), const_mul(x, 212),
@ -1265,7 +1155,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 217), const_mul(x, 217),
const_mul(x, 218), const_mul(x, 218),
const_mul(x, 219), const_mul(x, 219),
const_mul(x, 220), const_mul(x, 220),
const_mul(x, 221), const_mul(x, 221),
const_mul(x, 222), const_mul(x, 222),
@ -1276,7 +1165,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 227), const_mul(x, 227),
const_mul(x, 228), const_mul(x, 228),
const_mul(x, 229), const_mul(x, 229),
const_mul(x, 230), const_mul(x, 230),
const_mul(x, 231), const_mul(x, 231),
const_mul(x, 232), const_mul(x, 232),
@ -1287,7 +1175,6 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 237), const_mul(x, 237),
const_mul(x, 238), const_mul(x, 238),
const_mul(x, 239), const_mul(x, 239),
const_mul(x, 240), const_mul(x, 240),
const_mul(x, 241), const_mul(x, 241),
const_mul(x, 242), const_mul(x, 242),
@ -1298,43 +1185,36 @@ const fn calculate_octet_mul_table_inner(x: usize) -> [u8; 256] {
const_mul(x, 247), const_mul(x, 247),
const_mul(x, 248), const_mul(x, 248),
const_mul(x, 249), const_mul(x, 249),
const_mul(x, 250), const_mul(x, 250),
const_mul(x, 251), const_mul(x, 251),
const_mul(x, 252), const_mul(x, 252),
const_mul(x, 253), const_mul(x, 253),
const_mul(x, 254), const_mul(x, 254),
const_mul(x, 255), const_mul(x, 255),
] ];
} }
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub struct Octet { pub struct Octet {
value: u8 value: u8,
} }
impl Octet { impl Octet {
pub fn new(value: u8) -> Octet { pub fn new(value: u8) -> Octet {
Octet { Octet { value }
value
}
} }
pub fn zero() -> Octet { pub fn zero() -> Octet {
Octet { Octet { value: 0 }
value: 0
}
} }
pub fn one() -> Octet { pub fn one() -> Octet {
Octet { Octet { value: 1 }
value: 1
}
} }
pub fn alpha(i: u8) -> Octet { pub fn alpha(i: u8) -> Octet {
Octet { Octet {
value: OCT_EXP[i as usize] value: OCT_EXP[i as usize],
} }
} }
@ -1361,7 +1241,7 @@ impl Add for Octet {
fn add(self, other: Octet) -> Octet { fn add(self, other: Octet) -> Octet {
Octet { Octet {
// As defined in section 5.7.2, addition on octets is implemented as bitxor // As defined in section 5.7.2, addition on octets is implemented as bitxor
value: self.value ^ other.value value: self.value ^ other.value,
} }
} }
} }
@ -1372,7 +1252,7 @@ impl<'a, 'b> Add<&'b Octet> for &'a Octet {
fn add(self, other: &'b Octet) -> Octet { fn add(self, other: &'b Octet) -> Octet {
Octet { Octet {
// As defined in section 5.7.2, addition on octets is implemented as bitxor // As defined in section 5.7.2, addition on octets is implemented as bitxor
value: self.value ^ other.value value: self.value ^ other.value,
} }
} }
} }
@ -1395,7 +1275,7 @@ impl Sub for Octet {
fn sub(self, rhs: Octet) -> Octet { fn sub(self, rhs: Octet) -> Octet {
Octet { Octet {
// As defined in section 5.7.2, subtraction on octets is implemented as bitxor // As defined in section 5.7.2, subtraction on octets is implemented as bitxor
value: self.value ^ rhs.value value: self.value ^ rhs.value,
} }
} }
} }
@ -1414,18 +1294,15 @@ impl<'a, 'b> Mul<&'b Octet> for &'a Octet {
fn mul(self, other: &'b Octet) -> Octet { fn mul(self, other: &'b Octet) -> Octet {
// As defined in section 5.7.2, multiplication is implemented via the tables above // As defined in section 5.7.2, multiplication is implemented via the tables above
if self.value == 0 || other.value == 0 { if self.value == 0 || other.value == 0 {
Octet { Octet { value: 0 }
value: 0 } else {
}
}
else {
unsafe { unsafe {
// This is safe because value is a u8, and OCT_LOG is 256 elements long // This is safe because value is a u8, and OCT_LOG is 256 elements long
let log_u = *OCT_LOG.get_unchecked(self.value as usize) as usize; let log_u = *OCT_LOG.get_unchecked(self.value as usize) as usize;
let log_v = *OCT_LOG.get_unchecked(other.value as usize) as usize; let log_v = *OCT_LOG.get_unchecked(other.value as usize) as usize;
// This is safe because the sum of two values in OCT_LOG cannot exceed 509 // This is safe because the sum of two values in OCT_LOG cannot exceed 509
Octet { Octet {
value: *OCT_EXP.get_unchecked(log_u + log_v) value: *OCT_EXP.get_unchecked(log_u + log_v),
} }
} }
} }
@ -1447,15 +1324,12 @@ impl<'a, 'b> Div<&'b Octet> for &'a Octet {
assert_ne!(0, rhs.value); assert_ne!(0, rhs.value);
// As defined in section 5.7.2, division is implemented via the tables above // As defined in section 5.7.2, division is implemented via the tables above
if self.value == 0 { if self.value == 0 {
Octet { Octet { value: 0 }
value: 0 } else {
}
}
else {
let log_u = OCT_LOG[self.value as usize] as usize; let log_u = OCT_LOG[self.value as usize] as usize;
let log_v = OCT_LOG[rhs.value as usize] as usize; let log_v = OCT_LOG[rhs.value as usize] as usize;
Octet { Octet {
value: OCT_EXP[255 + log_u - log_v] value: OCT_EXP[255 + log_u - log_v],
} }
} }
} }
@ -1466,10 +1340,10 @@ mod tests {
use rand::Rng; use rand::Rng;
use crate::octet::Octet; use crate::octet::Octet;
use crate::octet::OCT_LOG;
use crate::octet::OCT_EXP;
use crate::octet::OCTET_MUL_LOW_BITS;
use crate::octet::OCTET_MUL_HI_BITS; use crate::octet::OCTET_MUL_HI_BITS;
use crate::octet::OCTET_MUL_LOW_BITS;
use crate::octet::OCT_EXP;
use crate::octet::OCT_LOG;
#[test] #[test]
fn multiplication_tables() { fn multiplication_tables() {
@ -1486,7 +1360,7 @@ mod tests {
#[test] #[test]
fn addition() { fn addition() {
let octet = Octet { let octet = Octet {
value: rand::thread_rng().gen() value: rand::thread_rng().gen(),
}; };
// See section 5.7.2. u is its own additive inverse // See section 5.7.2. u is its own additive inverse
assert_eq!(Octet::zero(), &octet + &octet); assert_eq!(Octet::zero(), &octet + &octet);
@ -1495,7 +1369,7 @@ mod tests {
#[test] #[test]
fn multiplication_identity() { fn multiplication_identity() {
let octet = Octet { let octet = Octet {
value: rand::thread_rng().gen() value: rand::thread_rng().gen(),
}; };
assert_eq!(octet, &octet * &Octet::one()); assert_eq!(octet, &octet * &Octet::one());
} }
@ -1503,7 +1377,7 @@ mod tests {
#[test] #[test]
fn multiplicative_inverse() { fn multiplicative_inverse() {
let octet = Octet { let octet = Octet {
value: rand::thread_rng().gen_range(1, 255) value: rand::thread_rng().gen_range(1, 255),
}; };
let one = Octet::one(); let one = Octet::one();
assert_eq!(one, &octet * &(&one / &octet)); assert_eq!(one, &octet * &(&one / &octet));
@ -1512,7 +1386,7 @@ mod tests {
#[test] #[test]
fn division() { fn division() {
let octet = Octet { let octet = Octet {
value: rand::thread_rng().gen_range(1, 255) value: rand::thread_rng().gen_range(1, 255),
}; };
assert_eq!(Octet::one(), &octet / &octet); assert_eq!(Octet::one(), &octet / &octet);
} }
@ -1520,7 +1394,7 @@ mod tests {
#[test] #[test]
fn unsafe_mul_gaurantees() { fn unsafe_mul_gaurantees() {
let max_value = *OCT_LOG.iter().max().unwrap() as usize; let max_value = *OCT_LOG.iter().max().unwrap() as usize;
assert!(2*max_value < OCT_EXP.len()); assert!(2 * max_value < OCT_EXP.len());
} }
#[test] #[test]

@ -1,15 +1,17 @@
use crate::octet::Octet; use crate::octet::Octet;
use crate::octet::OCTET_MUL; use crate::octet::OCTET_MUL;
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
use crate::octet::OCTET_MUL_LOW_BITS;
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
use crate::octet::OCTET_MUL_HI_BITS; use crate::octet::OCTET_MUL_HI_BITS;
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
use crate::octet::OCTET_MUL_LOW_BITS;
fn mulassign_scalar_fallback(octets: &mut [u8], scalar: &Octet) { fn mulassign_scalar_fallback(octets: &mut [u8], scalar: &Octet) {
let scalar_index = scalar.byte() as usize; let scalar_index = scalar.byte() as usize;
for i in 0..octets.len() { for i in 0..octets.len() {
unsafe { unsafe {
*octets.get_unchecked_mut(i) = *OCTET_MUL.get_unchecked(scalar_index).get_unchecked(*octets.get_unchecked(i) as usize); *octets.get_unchecked_mut(i) = *OCTET_MUL
.get_unchecked(scalar_index)
.get_unchecked(*octets.get_unchecked(i) as usize);
} }
} }
} }
@ -22,11 +24,13 @@ unsafe fn mulassign_scalar_avx2(octets: &mut [u8], scalar: &Octet) {
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
use std::arch::x86_64::*; use std::arch::x86_64::*;
let low_mask =_mm256_set1_epi8(0x0F); let low_mask = _mm256_set1_epi8(0x0F);
let hi_mask = _mm256_set1_epi8(0xF0 as u8 as i8); let hi_mask = _mm256_set1_epi8(0xF0 as u8 as i8);
let self_avx_ptr = octets.as_mut_ptr() as *mut __m256i; let self_avx_ptr = octets.as_mut_ptr() as *mut __m256i;
let low_table =_mm256_loadu_si256(OCTET_MUL_LOW_BITS[scalar.byte() as usize].as_ptr() as *const __m256i); let low_table =
let hi_table =_mm256_loadu_si256(OCTET_MUL_HI_BITS[scalar.byte() as usize].as_ptr() as *const __m256i); _mm256_loadu_si256(OCTET_MUL_LOW_BITS[scalar.byte() as usize].as_ptr() as *const __m256i);
let hi_table =
_mm256_loadu_si256(OCTET_MUL_HI_BITS[scalar.byte() as usize].as_ptr() as *const __m256i);
for i in 0..(octets.len() / 32) { for i in 0..(octets.len() / 32) {
let self_vec = _mm256_loadu_si256(self_avx_ptr.add(i)); let self_vec = _mm256_loadu_si256(self_avx_ptr.add(i));
@ -42,7 +46,9 @@ unsafe fn mulassign_scalar_avx2(octets: &mut [u8], scalar: &Octet) {
let remainder = octets.len() % 32; let remainder = octets.len() % 32;
let scalar_index = scalar.byte() as usize; let scalar_index = scalar.byte() as usize;
for i in (octets.len() - remainder)..octets.len() { for i in (octets.len() - remainder)..octets.len() {
*octets.get_unchecked_mut(i) = *OCTET_MUL.get_unchecked(scalar_index).get_unchecked(*octets.get_unchecked(i) as usize); *octets.get_unchecked_mut(i) = *OCTET_MUL
.get_unchecked(scalar_index)
.get_unchecked(*octets.get_unchecked(i) as usize);
} }
} }
@ -62,8 +68,10 @@ pub fn mulassign_scalar(octets: &mut [u8], scalar: &Octet) {
fn fused_addassign_mul_scalar_fallback(octets: &mut [u8], other: &[u8], scalar: &Octet) { fn fused_addassign_mul_scalar_fallback(octets: &mut [u8], other: &[u8], scalar: &Octet) {
let scalar_index = scalar.byte() as usize; let scalar_index = scalar.byte() as usize;
for i in 0..octets.len() { for i in 0..octets.len() {
unsafe { unsafe {
*octets.get_unchecked_mut(i) ^= *OCTET_MUL.get_unchecked(scalar_index).get_unchecked(*other.get_unchecked(i) as usize); *octets.get_unchecked_mut(i) ^= *OCTET_MUL
.get_unchecked(scalar_index)
.get_unchecked(*other.get_unchecked(i) as usize);
} }
} }
} }
@ -76,12 +84,14 @@ unsafe fn fused_addassign_mul_scalar_avx2(octets: &mut [u8], other: &[u8], scala
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
use std::arch::x86_64::*; use std::arch::x86_64::*;
let low_mask =_mm256_set1_epi8(0x0F); let low_mask = _mm256_set1_epi8(0x0F);
let hi_mask = _mm256_set1_epi8(0xF0 as u8 as i8); let hi_mask = _mm256_set1_epi8(0xF0 as u8 as i8);
let self_avx_ptr = octets.as_mut_ptr() as *mut __m256i; let self_avx_ptr = octets.as_mut_ptr() as *mut __m256i;
let other_avx_ptr = other.as_ptr() as *const __m256i; let other_avx_ptr = other.as_ptr() as *const __m256i;
let low_table =_mm256_loadu_si256(OCTET_MUL_LOW_BITS[scalar.byte() as usize].as_ptr() as *const __m256i); let low_table =
let hi_table =_mm256_loadu_si256(OCTET_MUL_HI_BITS[scalar.byte() as usize].as_ptr() as *const __m256i); _mm256_loadu_si256(OCTET_MUL_LOW_BITS[scalar.byte() as usize].as_ptr() as *const __m256i);
let hi_table =
_mm256_loadu_si256(OCTET_MUL_HI_BITS[scalar.byte() as usize].as_ptr() as *const __m256i);
for i in 0..(octets.len() / 32) { for i in 0..(octets.len() / 32) {
// Multiply by scalar // Multiply by scalar
@ -102,13 +112,23 @@ unsafe fn fused_addassign_mul_scalar_avx2(octets: &mut [u8], other: &[u8], scala
let remainder = octets.len() % 32; let remainder = octets.len() % 32;
let scalar_index = scalar.byte() as usize; let scalar_index = scalar.byte() as usize;
for i in (octets.len() - remainder)..octets.len() { for i in (octets.len() - remainder)..octets.len() {
*octets.get_unchecked_mut(i) ^= *OCTET_MUL.get_unchecked(scalar_index).get_unchecked(*other.get_unchecked(i) as usize); *octets.get_unchecked_mut(i) ^= *OCTET_MUL
.get_unchecked(scalar_index)
.get_unchecked(*other.get_unchecked(i) as usize);
} }
} }
pub fn fused_addassign_mul_scalar(octets: &mut [u8], other: &[u8], scalar: &Octet) { pub fn fused_addassign_mul_scalar(octets: &mut [u8], other: &[u8], scalar: &Octet) {
debug_assert_ne!(*scalar, Octet::one(), "Don't call this with one. Use += instead"); debug_assert_ne!(
debug_assert_ne!(*scalar, Octet::zero(), "Don't call with zero. It's very inefficient"); *scalar,
Octet::one(),
"Don't call this with one. Use += instead"
);
debug_assert_ne!(
*scalar,
Octet::zero(),
"Don't call with zero. It's very inefficient"
);
assert_eq!(octets.len(), other.len()); assert_eq!(octets.len(), other.len());
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
@ -191,7 +211,7 @@ unsafe fn count_ones_and_nonzeros_avx2(octets: &[u8]) -> (usize, usize) {
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
use std::arch::x86_64::*; use std::arch::x86_64::*;
let avx_ones =_mm256_set1_epi8(1); let avx_ones = _mm256_set1_epi8(1);
let avx_zeros = _mm256_set1_epi8(0); let avx_zeros = _mm256_set1_epi8(0);
let avx_ptr = octets.as_ptr() as *const __m256i; let avx_ptr = octets.as_ptr() as *const __m256i;
@ -216,7 +236,7 @@ unsafe fn count_ones_and_nonzeros_avx2(octets: &[u8]) -> (usize, usize) {
let mut remainder = octets.len() % 32; let mut remainder = octets.len() % 32;
if remainder >= 16 { if remainder >= 16 {
remainder -= 16; remainder -= 16;
let avx_ones =_mm_set1_epi8(1); let avx_ones = _mm_set1_epi8(1);
let avx_zeros = _mm_set1_epi8(0); let avx_zeros = _mm_set1_epi8(0);
let avx_ptr = octets.as_ptr().add((octets.len() / 32) * 32) as *const __m128i; let avx_ptr = octets.as_ptr().add((octets.len() / 32) * 32) as *const __m128i;

@ -1,5 +1,5 @@
use crate::arraymap::{ArrayMap, BoolArrayMap};
use crate::arraymap::UsizeArrayMap; use crate::arraymap::UsizeArrayMap;
use crate::arraymap::{ArrayMap, BoolArrayMap};
use crate::matrix::OctetMatrix; use crate::matrix::OctetMatrix;
use crate::octet::Octet; use crate::octet::Octet;
use crate::octets::count_ones_and_nonzeros; use crate::octets::count_ones_and_nonzeros;
@ -19,13 +19,17 @@ struct FirstPhaseRowSelectionStats {
hdpc_rows: Vec<bool>, hdpc_rows: Vec<bool>,
start_col: usize, start_col: usize,
end_col: usize, end_col: usize,
start_row: usize start_row: usize,
} }
impl FirstPhaseRowSelectionStats { impl FirstPhaseRowSelectionStats {
#[inline(never)] #[inline(never)]
#[allow(non_snake_case)] #[allow(non_snake_case)]
pub fn new(matrix: &OctetMatrix, end_col: usize, num_source_symbols: u32) -> FirstPhaseRowSelectionStats { pub fn new(
matrix: &OctetMatrix,
end_col: usize,
num_source_symbols: u32,
) -> FirstPhaseRowSelectionStats {
let S = num_ldpc_symbols(num_source_symbols); let S = num_ldpc_symbols(num_source_symbols);
let H = num_hdpc_symbols(num_source_symbols); let H = num_hdpc_symbols(num_source_symbols);
@ -43,7 +47,7 @@ impl FirstPhaseRowSelectionStats {
hdpc_rows, hdpc_rows,
start_col: 0, start_col: 0,
end_col, end_col,
start_row: 0 start_row: 0,
}; };
for row in 0..matrix.height() { for row in 0..matrix.height() {
@ -67,8 +71,10 @@ impl FirstPhaseRowSelectionStats {
// Recompute all stored statistics for the given row // Recompute all stored statistics for the given row
pub fn recompute_row(&mut self, row: usize, matrix: &OctetMatrix) { pub fn recompute_row(&mut self, row: usize, matrix: &OctetMatrix) {
let (ones, non_zero) = count_ones_and_nonzeros(&matrix.get_row(row)[self.start_col..self.end_col]); let (ones, non_zero) =
self.non_zeros_histogram.decrement(self.non_zeros_per_row.get(row)); count_ones_and_nonzeros(&matrix.get_row(row)[self.start_col..self.end_col]);
self.non_zeros_histogram
.decrement(self.non_zeros_per_row.get(row));
self.non_zeros_histogram.increment(non_zero); self.non_zeros_histogram.increment(non_zero);
self.non_zeros_per_row.insert(row, non_zero); self.non_zeros_per_row.insert(row, non_zero);
self.ones_per_row.insert(row, ones); self.ones_per_row.insert(row, ones);
@ -87,13 +93,21 @@ impl FirstPhaseRowSelectionStats {
// Set the valid columns, and recalculate statistics // Set the valid columns, and recalculate statistics
#[inline(never)] #[inline(never)]
pub fn resize(&mut self, start_row: usize, end_row: usize, start_col: usize, end_col: usize, matrix: &OctetMatrix) { pub fn resize(
&mut self,
start_row: usize,
end_row: usize,
start_col: usize,
end_col: usize,
matrix: &OctetMatrix,
) {
// Only shrinking is supported // Only shrinking is supported
assert!(start_col > self.start_col); assert!(start_col > self.start_col);
assert!(end_col <= self.end_col); assert!(end_col <= self.end_col);
assert_eq!(self.start_row, start_row - 1); assert_eq!(self.start_row, start_row - 1);
self.non_zeros_histogram.decrement(self.non_zeros_per_row.get(self.start_row)); self.non_zeros_histogram
.decrement(self.non_zeros_per_row.get(self.start_row));
for row in start_row..end_row { for row in start_row..end_row {
for col in self.start_col..start_col { for col in self.start_col..start_col {
@ -127,7 +141,11 @@ impl FirstPhaseRowSelectionStats {
} }
#[inline(never)] #[inline(never)]
fn first_phase_graph_substep_build_adjacency(&self, rows_with_two_ones: &Vec<usize>, matrix: &OctetMatrix) -> ArrayMap<Vec<(usize, usize)>> { fn first_phase_graph_substep_build_adjacency(
&self,
rows_with_two_ones: &Vec<usize>,
matrix: &OctetMatrix,
) -> ArrayMap<Vec<(usize, usize)>> {
let mut adjacent_nodes = ArrayMap::new(self.start_col, self.end_col); let mut adjacent_nodes = ArrayMap::new(self.start_col, self.end_col);
for row in rows_with_two_ones.iter() { for row in rows_with_two_ones.iter() {
@ -157,8 +175,7 @@ impl FirstPhaseRowSelectionStats {
let mut new_nodes = Vec::with_capacity(10); let mut new_nodes = Vec::with_capacity(10);
new_nodes.push((ones[1], *row)); new_nodes.push((ones[1], *row));
adjacent_nodes.insert(ones[0], new_nodes); adjacent_nodes.insert(ones[0], new_nodes);
} } else {
else {
first.unwrap().push((ones[1], *row)); first.unwrap().push((ones[1], *row));
} }
let second = adjacent_nodes.get_mut(ones[1]); let second = adjacent_nodes.get_mut(ones[1]);
@ -166,8 +183,7 @@ impl FirstPhaseRowSelectionStats {
let mut new_nodes = Vec::with_capacity(10); let mut new_nodes = Vec::with_capacity(10);
new_nodes.push((ones[0], *row)); new_nodes.push((ones[0], *row));
adjacent_nodes.insert(ones[1], new_nodes); adjacent_nodes.insert(ones[1], new_nodes);
} } else {
else {
second.unwrap().push((ones[0], *row)); second.unwrap().push((ones[0], *row));
} }
} }
@ -176,8 +192,15 @@ impl FirstPhaseRowSelectionStats {
} }
#[inline(never)] #[inline(never)]
fn first_phase_graph_substep(&self, start_row: usize, end_row: usize, rows_with_two_ones: &Vec<usize>, matrix: &OctetMatrix) -> usize { fn first_phase_graph_substep(
let adjacent_nodes = self.first_phase_graph_substep_build_adjacency(rows_with_two_ones, matrix); &self,
start_row: usize,
end_row: usize,
rows_with_two_ones: &Vec<usize>,
matrix: &OctetMatrix,
) -> usize {
let adjacent_nodes =
self.first_phase_graph_substep_build_adjacency(rows_with_two_ones, matrix);
let mut visited = BoolArrayMap::new(start_row, end_row); let mut visited = BoolArrayMap::new(start_row, end_row);
let mut examplar_largest_component_row = None; let mut examplar_largest_component_row = None;
@ -214,7 +237,12 @@ impl FirstPhaseRowSelectionStats {
} }
#[inline(never)] #[inline(never)]
fn first_phase_original_degree_substep(&self, start_row: usize, end_row: usize, r: usize) -> usize { fn first_phase_original_degree_substep(
&self,
start_row: usize,
end_row: usize,
r: usize,
) -> usize {
let mut chosen_hdpc = None; let mut chosen_hdpc = None;
let mut chosen_hdpc_original_degree = std::usize::MAX; let mut chosen_hdpc_original_degree = std::usize::MAX;
let mut chosen_non_hdpc = None; let mut chosen_non_hdpc = None;
@ -228,8 +256,7 @@ impl FirstPhaseRowSelectionStats {
chosen_hdpc = Some(row); chosen_hdpc = Some(row);
chosen_hdpc_original_degree = row_original_degree; chosen_hdpc_original_degree = row_original_degree;
} }
} } else if row_original_degree < chosen_non_hdpc_original_degree {
else if row_original_degree < chosen_non_hdpc_original_degree {
chosen_non_hdpc = Some(row); chosen_non_hdpc = Some(row);
chosen_non_hdpc_original_degree = row_original_degree; chosen_non_hdpc_original_degree = row_original_degree;
} }
@ -237,8 +264,7 @@ impl FirstPhaseRowSelectionStats {
} }
if chosen_non_hdpc != None { if chosen_non_hdpc != None {
return chosen_non_hdpc.unwrap(); return chosen_non_hdpc.unwrap();
} } else {
else {
return chosen_hdpc.unwrap(); return chosen_hdpc.unwrap();
} }
} }
@ -246,7 +272,12 @@ impl FirstPhaseRowSelectionStats {
// Verify there there are no non-HPDC rows with exactly two non-zero entries, greater than one // Verify there there are no non-HPDC rows with exactly two non-zero entries, greater than one
#[inline(never)] #[inline(never)]
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
fn first_phase_graph_substep_verify(&self, start_row: usize, end_row: usize, rows_with_two_ones: &Vec<usize>) { fn first_phase_graph_substep_verify(
&self,
start_row: usize,
end_row: usize,
rows_with_two_ones: &Vec<usize>,
) {
for row in start_row..end_row { for row in start_row..end_row {
if self.non_zeros_per_row.get(row) == 2 { if self.non_zeros_per_row.get(row) == 2 {
assert!(rows_with_two_ones.contains(&row) || self.hdpc_rows[row]); assert!(rows_with_two_ones.contains(&row) || self.hdpc_rows[row]);
@ -257,7 +288,12 @@ impl FirstPhaseRowSelectionStats {
// Helper method for decoder phase 1 // Helper method for decoder phase 1
// selects from [start_row, end_row) reading [start_col, end_col) // selects from [start_row, end_row) reading [start_col, end_col)
// Returns (the chosen row, and "r" number of non-zero values the row has) // Returns (the chosen row, and "r" number of non-zero values the row has)
pub fn first_phase_selection(&self, start_row: usize, end_row: usize, matrix: &OctetMatrix) -> (Option<usize>, Option<usize>) { pub fn first_phase_selection(
&self,
start_row: usize,
end_row: usize,
matrix: &OctetMatrix,
) -> (Option<usize>, Option<usize>) {
let mut r = None; let mut r = None;
for i in 1..(self.end_col - self.start_col + 1) { for i in 1..(self.end_col - self.start_col + 1) {
if self.non_zeros_histogram.get(i) > 0 { if self.non_zeros_histogram.get(i) > 0 {
@ -288,15 +324,24 @@ impl FirstPhaseRowSelectionStats {
if rows_with_two_ones.len() > 0 { if rows_with_two_ones.len() > 0 {
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
self.first_phase_graph_substep_verify(start_row, end_row, &rows_with_two_ones); self.first_phase_graph_substep_verify(start_row, end_row, &rows_with_two_ones);
return (Some(self.first_phase_graph_substep(start_row, end_row, &rows_with_two_ones, matrix)), r); return (
} Some(self.first_phase_graph_substep(
else { start_row,
end_row,
&rows_with_two_ones,
matrix,
)),
r,
);
} else {
// See paragraph starting "If r = 2 and there is no row with exactly 2 ones in V" // See paragraph starting "If r = 2 and there is no row with exactly 2 ones in V"
return (row_with_two_greater_than_one, r); return (row_with_two_greater_than_one, r);
} }
} } else {
else { return (
return (Some(self.first_phase_original_degree_substep(start_row, end_row, r.unwrap())), r); Some(self.first_phase_original_degree_substep(start_row, end_row, r.unwrap())),
r,
);
} }
} }
} }
@ -316,11 +361,15 @@ pub struct IntermediateSymbolDecoder {
debug_symbol_mul_ops: u32, debug_symbol_mul_ops: u32,
debug_symbol_add_ops: u32, debug_symbol_add_ops: u32,
debug_symbol_mul_ops_by_phase: Vec<u32>, debug_symbol_mul_ops_by_phase: Vec<u32>,
debug_symbol_add_ops_by_phase: Vec<u32> debug_symbol_add_ops_by_phase: Vec<u32>,
} }
impl IntermediateSymbolDecoder { impl IntermediateSymbolDecoder {
pub fn new(matrix: OctetMatrix, symbols: Vec<Symbol>, num_source_symbols: u32) -> IntermediateSymbolDecoder { pub fn new(
matrix: OctetMatrix,
symbols: Vec<Symbol>,
num_source_symbols: u32,
) -> IntermediateSymbolDecoder {
assert!(matrix.width() <= symbols.len()); assert!(matrix.width() <= symbols.len());
assert_eq!(matrix.height(), symbols.len()); assert_eq!(matrix.height(), symbols.len());
let mut c = Vec::with_capacity(matrix.width()); let mut c = Vec::with_capacity(matrix.width());
@ -345,14 +394,20 @@ impl IntermediateSymbolDecoder {
debug_symbol_mul_ops: 0, debug_symbol_mul_ops: 0,
debug_symbol_add_ops: 0, debug_symbol_add_ops: 0,
debug_symbol_mul_ops_by_phase: vec![0; 5], debug_symbol_mul_ops_by_phase: vec![0; 5],
debug_symbol_add_ops_by_phase: vec![0; 5] debug_symbol_add_ops_by_phase: vec![0; 5],
} }
} }
// Returns true iff all elements in A between [start_row, end_row) // Returns true iff all elements in A between [start_row, end_row)
// and [start_column, end_column) are zero // and [start_column, end_column) are zero
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
fn all_zeroes(&self, start_row: usize, end_row: usize, start_column: usize, end_column: usize) -> bool { fn all_zeroes(
&self,
start_row: usize,
end_row: usize,
start_column: usize,
end_column: usize,
) -> bool {
for row in start_row..end_row { for row in start_row..end_row {
for column in start_column..end_column { for column in start_column..end_column {
if self.A.get(row, column) != Octet::zero() { if self.A.get(row, column) != Octet::zero() {
@ -372,8 +427,7 @@ impl IntermediateSymbolDecoder {
let dest; let dest;
if swapped_columns == 0 { if swapped_columns == 0 {
dest = self.i; dest = self.i;
} } else {
else {
dest = self.A.width() - self.u - swapped_columns; dest = self.A.width() - self.u - swapped_columns;
} }
// No need to swap the first i rows, as they are all zero (see submatrix above V) // No need to swap the first i rows, as they are all zero (see submatrix above V)
@ -408,13 +462,18 @@ impl IntermediateSymbolDecoder {
// +-----------+-----------------+---------+ // +-----------+-----------------+---------+
// Figure 6: Submatrices of A in the First Phase // Figure 6: Submatrices of A in the First Phase
let mut selection_helper = FirstPhaseRowSelectionStats::new(&self.A, self.A.width() - self.u, self.num_source_symbols); let mut selection_helper = FirstPhaseRowSelectionStats::new(
&self.A,
self.A.width() - self.u,
self.num_source_symbols,
);
while self.i + self.u < self.L { while self.i + self.u < self.L {
// Calculate r // Calculate r
// "Let r be the minimum integer such that at least one row of A has // "Let r be the minimum integer such that at least one row of A has
// exactly r nonzeros in V." // exactly r nonzeros in V."
let (chosen_row, r) = selection_helper.first_phase_selection(self.i, self.A.height(), &self.A); let (chosen_row, r) =
selection_helper.first_phase_selection(self.i, self.A.height(), &self.A);
if r == None { if r == None {
return false; return false;
@ -442,8 +501,7 @@ impl IntermediateSymbolDecoder {
// Hot path for r == 1, since it's very common due to maximum connected // Hot path for r == 1, since it's very common due to maximum connected
// component selection, and recompute_row() is expensive // component selection, and recompute_row() is expensive
selection_helper.eliminate_leading_value(row, &leading_value); selection_helper.eliminate_leading_value(row, &leading_value);
} } else {
else {
selection_helper.recompute_row(row, &self.A); selection_helper.recompute_row(row, &self.A);
} }
} }
@ -451,7 +509,13 @@ impl IntermediateSymbolDecoder {
self.i += 1; self.i += 1;
self.u += r - 1; self.u += r - 1;
selection_helper.resize(self.i, self.A.height(), self.i, self.A.width() - self.u, &self.A); selection_helper.resize(
self.i,
self.A.height(),
self.i,
self.A.width() - self.u,
&self.A,
);
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
self.first_phase_verify(); self.first_phase_verify();
} }
@ -468,8 +532,7 @@ impl IntermediateSymbolDecoder {
for col in 0..self.i { for col in 0..self.i {
if row == col { if row == col {
assert_eq!(Octet::one(), self.A.get(row, col)); assert_eq!(Octet::one(), self.A.get(row, col));
} } else {
else {
assert_eq!(Octet::zero(), self.A.get(row, col)); assert_eq!(Octet::zero(), self.A.get(row, col));
} }
} }
@ -540,8 +603,7 @@ impl IntermediateSymbolDecoder {
self.debug_symbol_add_ops += 1; self.debug_symbol_add_ops += 1;
let (dest, temp) = get_both_indices(&mut self.D, self.d[row], self.d[col]); let (dest, temp) = get_both_indices(&mut self.D, self.d[row], self.d[col]);
*dest += temp; *dest += temp;
} } else {
else {
self.debug_symbol_mul_ops += 1; self.debug_symbol_mul_ops += 1;
self.debug_symbol_add_ops += 1; self.debug_symbol_add_ops += 1;
let (dest, temp) = get_both_indices(&mut self.D, self.d[row], self.d[col]); let (dest, temp) = get_both_indices(&mut self.D, self.d[row], self.d[col]);
@ -568,8 +630,7 @@ impl IntermediateSymbolDecoder {
// The rest of A should be identity matrix // The rest of A should be identity matrix
if row == col { if row == col {
assert_eq!(Octet::one(), self.A.get(row, col)); assert_eq!(Octet::one(), self.A.get(row, col));
} } else {
else {
assert_eq!(Octet::zero(), self.A.get(row, col)); assert_eq!(Octet::zero(), self.A.get(row, col));
} }
} }
@ -629,8 +690,7 @@ impl IntermediateSymbolDecoder {
for col in (self.A.width() - self.u)..self.A.width() { for col in (self.A.width() - self.u)..self.A.width() {
if row == col { if row == col {
assert_eq!(Octet::one(), self.A.get(row, col)); assert_eq!(Octet::one(), self.A.get(row, col));
} } else {
else {
assert_eq!(Octet::zero(), self.A.get(row, col)); assert_eq!(Octet::zero(), self.A.get(row, col));
} }
} }
@ -673,8 +733,7 @@ impl IntermediateSymbolDecoder {
for col in 0..self.A.width() { for col in 0..self.A.width() {
if row == col { if row == col {
assert_eq!(Octet::one(), self.A.get(row, col)); assert_eq!(Octet::one(), self.A.get(row, col));
} } else {
else {
assert_eq!(Octet::zero(), self.A.get(row, col)); assert_eq!(Octet::zero(), self.A.get(row, col));
} }
} }
@ -774,8 +833,7 @@ impl IntermediateSymbolDecoder {
self.debug_symbol_add_ops += 1; self.debug_symbol_add_ops += 1;
let (dest, temp) = get_both_indices(&mut self.D, self.d[iprime], self.d[i]); let (dest, temp) = get_both_indices(&mut self.D, self.d[iprime], self.d[i]);
*dest += temp; *dest += temp;
} } else {
else {
self.debug_symbol_add_ops += 1; self.debug_symbol_add_ops += 1;
self.debug_symbol_mul_ops += 1; self.debug_symbol_mul_ops += 1;
let (dest, temp) = get_both_indices(&mut self.D, self.d[iprime], self.d[i]); let (dest, temp) = get_both_indices(&mut self.D, self.d[iprime], self.d[i]);
@ -797,7 +855,7 @@ impl IntermediateSymbolDecoder {
#[inline(never)] #[inline(never)]
pub fn execute(&mut self) -> Option<Vec<Symbol>> { pub fn execute(&mut self) -> Option<Vec<Symbol>> {
if !self.first_phase() { if !self.first_phase() {
return None return None;
} }
if !self.second_phase() { if !self.second_phase() {
@ -824,7 +882,11 @@ impl IntermediateSymbolDecoder {
// Fused implementation for self.inverse().mul_symbols(symbols) // Fused implementation for self.inverse().mul_symbols(symbols)
// See section 5.4.2.1 // See section 5.4.2.1
pub fn fused_inverse_mul_symbols(matrix: OctetMatrix, symbols: Vec<Symbol>, num_source_symbols: u32) -> Option<Vec<Symbol>> { pub fn fused_inverse_mul_symbols(
matrix: OctetMatrix,
symbols: Vec<Symbol>,
num_source_symbols: u32,
) -> Option<Vec<Symbol>> {
IntermediateSymbolDecoder::new(matrix, symbols, num_source_symbols).execute() IntermediateSymbolDecoder::new(matrix, symbols, num_source_symbols).execute()
} }
@ -837,15 +899,25 @@ mod tests {
#[test] #[test]
fn operations_per_symbol() { fn operations_per_symbol() {
for &(elements, expected_mul_ops, expected_add_ops) in [(10, 35.0, 50.0), (100, 16.0, 35.0)].iter() { for &(elements, expected_mul_ops, expected_add_ops) in
[(10, 35.0, 50.0), (100, 16.0, 35.0)].iter()
{
let num_symbols = extended_source_block_symbols(elements); let num_symbols = extended_source_block_symbols(elements);
let indices: Vec<u32> = (0..num_symbols).collect(); let indices: Vec<u32> = (0..num_symbols).collect();
let a = generate_constraint_matrix(num_symbols, &indices); let a = generate_constraint_matrix(num_symbols, &indices);
let symbols = vec![Symbol::zero(1); a.width()]; let symbols = vec![Symbol::zero(1); a.width()];
let mut decoder = IntermediateSymbolDecoder::new(a, symbols, num_symbols); let mut decoder = IntermediateSymbolDecoder::new(a, symbols, num_symbols);
decoder.execute(); decoder.execute();
assert!((decoder.get_symbol_mul_ops() as f64 / num_symbols as f64) < expected_mul_ops, "mul ops per symbol = {}", (decoder.get_symbol_mul_ops() as f64 / num_symbols as f64)); assert!(
assert!((decoder.get_symbol_add_ops() as f64 / num_symbols as f64) < expected_add_ops, "add ops per symbol = {}", (decoder.get_symbol_add_ops() as f64 / num_symbols as f64)); (decoder.get_symbol_mul_ops() as f64 / num_symbols as f64) < expected_mul_ops,
"mul ops per symbol = {}",
(decoder.get_symbol_mul_ops() as f64 / num_symbols as f64)
);
assert!(
(decoder.get_symbol_add_ops() as f64 / num_symbols as f64) < expected_add_ops,
"add ops per symbol = {}",
(decoder.get_symbol_add_ops() as f64 / num_symbols as f64)
);
} }
} }
} }

@ -1,24 +1,22 @@
use std::ops::AddAssign;
use crate::octet::Octet; use crate::octet::Octet;
use crate::octets::mulassign_scalar;
use crate::octets::fused_addassign_mul_scalar;
use crate::octets::add_assign; use crate::octets::add_assign;
use crate::octets::fused_addassign_mul_scalar;
use crate::octets::mulassign_scalar;
use std::ops::AddAssign;
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub struct Symbol { pub struct Symbol {
value: Vec<u8> value: Vec<u8>,
} }
impl Symbol { impl Symbol {
pub fn new(value: Vec<u8>) -> Symbol { pub fn new(value: Vec<u8>) -> Symbol {
Symbol { Symbol { value }
value
}
} }
pub fn zero(size: usize) -> Symbol { pub fn zero(size: usize) -> Symbol {
Symbol { Symbol {
value: vec![0; size] value: vec![0; size],
} }
} }

@ -479,7 +479,8 @@ pub const SYSTEMATIC_INDICES_AND_PARAMETERS: [(u32, u32, u32, u32, u32); 477] =
(54735, 233, 877, 16, 55259), (54735, 233, 877, 16, 55259),
(55289, 362, 883, 16, 55817), (55289, 362, 883, 16, 55817),
(55843, 963, 907, 16, 56393), (55843, 963, 907, 16, 56393),
(56403, 471, 907, 16, 56951)]; (56403, 471, 907, 16, 56951),
];
const P1_TABLE: [(u32, u32); 477] = [ const P1_TABLE: [(u32, u32); 477] = [
(10, 11), (10, 11),
@ -958,7 +959,8 @@ const P1_TABLE: [(u32, u32); 477] = [
(54735, 373), (54735, 373),
(55289, 373), (55289, 373),
(55843, 373), (55843, 373),
(56403, 379)]; (56403, 379),
];
// Calculates, K', the extended source block size, in symbols, for a given source block size // Calculates, K', the extended source block size, in symbols, for a given source block size
// See section 5.3.1 // See section 5.3.1
@ -1023,9 +1025,9 @@ pub fn num_lt_symbols(source_block_symbols: u32) -> u32 {
// Calculates, L, the number of intermediate symbols, for a given number of source block symbols // Calculates, L, the number of intermediate symbols, for a given number of source block symbols
// See section 5.3.3.3 // See section 5.3.3.3
pub fn num_intermediate_symbols(source_block_symbols: u32) -> u32 { pub fn num_intermediate_symbols(source_block_symbols: u32) -> u32 {
extended_source_block_symbols(source_block_symbols) + extended_source_block_symbols(source_block_symbols)
num_ldpc_symbols(source_block_symbols) + + num_ldpc_symbols(source_block_symbols)
num_hdpc_symbols(source_block_symbols) + num_hdpc_symbols(source_block_symbols)
} }
// Calculates, P, the number of PI symbols, for a given number of source block symbols // Calculates, P, the number of PI symbols, for a given number of source block symbols
@ -1047,9 +1049,9 @@ pub fn calculate_p1(source_block_symbols: u32) -> u32 {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::systematic_constants::{MAX_SOURCE_SYMBOLS_PER_BLOCK, num_pi_symbols, calculate_p1};
use crate::systematic_constants::num_ldpc_symbols; use crate::systematic_constants::num_ldpc_symbols;
use crate::systematic_constants::num_lt_symbols; use crate::systematic_constants::num_lt_symbols;
use crate::systematic_constants::{calculate_p1, num_pi_symbols, MAX_SOURCE_SYMBOLS_PER_BLOCK};
#[test] #[test]
fn all_prime() { fn all_prime() {
@ -1067,8 +1069,7 @@ mod tests {
while !primal::is_prime(p1 as u64) { while !primal::is_prime(p1 as u64) {
if p1 % 2 == 0 { if p1 % 2 == 0 {
p1 += 1; p1 += 1;
} } else {
else {
p1 += 2; p1 += 2;
} }
} }

@ -4,10 +4,9 @@ pub fn get_both_indices<T>(vector: &mut Vec<T>, i: usize, j: usize) -> (&mut T,
debug_assert!(j < vector.len()); debug_assert!(j < vector.len());
if i < j { if i < j {
let (first, last) = vector.split_at_mut(j); let (first, last) = vector.split_at_mut(j);
return (&mut first[i], &mut last[0]) return (&mut first[i], &mut last[0]);
} } else {
else {
let (first, last) = vector.split_at_mut(i); let (first, last) = vector.split_at_mut(i);
return (&mut last[0], &mut first[j]) return (&mut last[0], &mut first[j]);
} }
} }

@ -1,11 +1,11 @@
#[cfg(test)] #[cfg(test)]
mod codec_tests { mod codec_tests {
use rand::Rng;
use rand::seq::SliceRandom; use rand::seq::SliceRandom;
use raptorq::SourceBlockEncoder; use rand::Rng;
use raptorq::SourceBlockDecoder;
use raptorq::Encoder;
use raptorq::Decoder; use raptorq::Decoder;
use raptorq::Encoder;
use raptorq::SourceBlockDecoder;
use raptorq::SourceBlockEncoder;
#[test] #[test]
fn random_erasure() { fn random_erasure() {