Skip to content

Commit

Permalink
AEAD/Polyfill: Use ArraySplitMap instead of ChunksFixed.
Browse files Browse the repository at this point in the history
This is a step towards eliminating the `unsafe` code in `ChunksFixed`.
  • Loading branch information
briansmith committed Oct 13, 2023
1 parent 8c2aa7c commit 6e6b118
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 17 deletions.
5 changes: 2 additions & 3 deletions src/aead/chacha.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

use super::{quic::Sample, Nonce};
use crate::{cpu, polyfill::ChunksFixed};
use crate::cpu;

#[cfg(any(
test,
Expand All @@ -38,9 +38,8 @@ pub struct Key {

impl Key {
pub(super) fn new(value: [u8; KEY_LEN], cpu_features: cpu::Features) -> Self {
let value: &[[u8; 4]; KEY_LEN / 4] = value.chunks_fixed();
Self {
words: value.map(u32::from_le_bytes),
words: value.array_split_map(u32::from_le_bytes),
cpu_features,
}
}
Expand Down
5 changes: 2 additions & 3 deletions src/aead/gcm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use super::{
block::{Block, BLOCK_LEN},
Aad,
};
use crate::{cpu, polyfill::ChunksFixed};
use crate::{cpu, polyfill::ArraySplitMap};
use core::ops::BitXorAssign;

#[cfg(not(target_arch = "aarch64"))]
Expand All @@ -30,8 +30,7 @@ pub struct Key {

impl Key {
pub(super) fn new(h_be: Block, cpu_features: cpu::Features) -> Self {
let h_be: &[[u8; 8]; 2] = h_be.as_ref().chunks_fixed();
let h: [u64; 2] = h_be.map(u64::from_be_bytes);
let h: [u64; 2] = h_be.as_ref().array_split_map(u64::from_be_bytes);

let mut key = Self {
h_table: HTable {
Expand Down
15 changes: 6 additions & 9 deletions src/aead/gcm/gcm_nohw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
// Unlike the BearSSL notes, we use u128 in the 64-bit implementation.

use super::{Block, Xi, BLOCK_LEN};
use crate::polyfill::ChunksFixed;
use crate::polyfill::ArraySplitMap;

#[cfg(target_pointer_width = "64")]
fn gcm_mul64_nohw(a: u64, b: u64) -> (u64, u64) {
Expand Down Expand Up @@ -224,21 +224,18 @@ pub(super) fn gmult(xi: &mut Xi, h: super::u128) {

pub(super) fn ghash(xi: &mut Xi, h: super::u128, input: &[[u8; BLOCK_LEN]]) {
with_swapped_xi(xi, |swapped| {
input.iter().for_each(|input| {
let input: &[[u8; 8]; 2] = input.chunks_fixed();
swapped[0] ^= u64::from_be_bytes(input[1]);
swapped[1] ^= u64::from_be_bytes(input[0]);
input.iter().for_each(|&input| {
let input = input.array_split_map(u64::from_be_bytes);
swapped[0] ^= input[1];
swapped[1] ^= input[0];

Check warning on line 230 in src/aead/gcm/gcm_nohw.rs

View check run for this annotation

Codecov / codecov/patch

src/aead/gcm/gcm_nohw.rs#L227-L230

Added lines #L227 - L230 were not covered by tests
gcm_polyval_nohw(swapped, h);
});
});
}

#[inline]
fn with_swapped_xi(Xi(xi): &mut Xi, f: impl FnOnce(&mut [u64; 2])) {
let unswapped: [u64; 2] = {
let xi: &[[u8; 8]; 2] = xi.as_ref().chunks_fixed();
xi.map(u64::from_be_bytes)
};
let unswapped: [u64; 2] = xi.as_ref().array_split_map(u64::from_be_bytes);

Check warning on line 238 in src/aead/gcm/gcm_nohw.rs

View check run for this annotation

Codecov / codecov/patch

src/aead/gcm/gcm_nohw.rs#L238

Added line #L238 was not covered by tests
let mut swapped: [u64; 2] = [unswapped[1], unswapped[0]];
f(&mut swapped);
let reswapped = [swapped[1], swapped[0]];
Expand Down
29 changes: 29 additions & 0 deletions src/polyfill/array_split_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,32 @@ impl<I, O> ArraySplitMap<I, O, 4, 4> for [I; 16] {
]
}
}

impl<I, O> ArraySplitMap<I, O, 4, 8> for [I; 32] {
#[inline]
fn array_split_map(self, f: impl Fn([I; 4]) -> O) -> [O; 8] {
let [a0, a1, a2, a3, b0, b1, b2, b3, c0, c1, c2, c3, d0, d1, d2, d3, e0, e1, e2, e3, f0, f1, f2, f3, g0, g1, g2, g3, h0, h1, h2, h3] =
self;
[
f([a0, a1, a2, a3]),
f([b0, b1, b2, b3]),
f([c0, c1, c2, c3]),
f([d0, d1, d2, d3]),
f([e0, e1, e2, e3]),
f([f0, f1, f2, f3]),
f([g0, g1, g2, g3]),
f([h0, h1, h2, h3]),
]
}
}

impl<I, O> ArraySplitMap<I, O, 8, 2> for [I; 16] {
#[inline]
fn array_split_map(self, f: impl Fn([I; 8]) -> O) -> [O; 2] {
let [a0, a1, a2, a3, a4, a5, a6, a7, b0, b1, b2, b3, b4, b5, b6, b7] = self;
[
f([a0, a1, a2, a3, a4, a5, a6, a7]),
f([b0, b1, b2, b3, b4, b5, b6, b7]),
]
}
}
2 changes: 0 additions & 2 deletions src/polyfill/chunks_fixed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,5 @@ macro_rules! define_chunks_fixed {
}

// Sorted by the first value, then the second value.
define_chunks_fixed!(16, 8);
define_chunks_fixed!(32, 4);
define_chunks_fixed!(64, 32);
define_chunks_fixed!(80, 20);

0 comments on commit 6e6b118

Please sign in to comment.