Internals: Polyfill array_map.

This commit is contained in:
Brian Smith 2021-03-19 11:25:00 -07:00
parent 45604135a6
commit 2a6b7484dc
5 changed files with 46 additions and 38 deletions

View File

@ -212,6 +212,7 @@ include = [
"src/pbkdf2.rs",
"src/pkcs8.rs",
"src/polyfill.rs",
"src/polyfill/array_map.rs",
"src/polyfill/chunks_fixed.rs",
"src/rand.rs",
"src/rsa/convert_nist_rsa_test_vectors.py",

View File

@ -14,7 +14,7 @@
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
use super::{quic::Sample, Nonce};
use crate::polyfill::ChunksFixed;
use crate::polyfill::{array_map::Map, ChunksFixed};
#[cfg(any(
test,
@ -35,17 +35,8 @@ pub struct Key([u32; KEY_LEN / 4]);
impl From<[u8; KEY_LEN]> for Key {
#[inline]
fn from(value: [u8; KEY_LEN]) -> Self {
let value = value.chunks_fixed();
Self([
u32::from_le_bytes(value[0]),
u32::from_le_bytes(value[1]),
u32::from_le_bytes(value[2]),
u32::from_le_bytes(value[3]),
u32::from_le_bytes(value[4]),
u32::from_le_bytes(value[5]),
u32::from_le_bytes(value[6]),
u32::from_le_bytes(value[7]),
])
let value: &[[u8; 4]; KEY_LEN / 4] = value.chunks_fixed();
Self(value.array_map(u32::from_le_bytes))
}
}
@ -202,12 +193,7 @@ pub struct Iv([u32; 4]);
impl Iv {
fn assume_unique_for_key(value: [u8; 16]) -> Self {
let value: &[[u8; 4]; 4] = value.chunks_fixed();
Self([
u32::from_le_bytes(value[0]),
u32::from_le_bytes(value[1]),
u32::from_le_bytes(value[2]),
u32::from_le_bytes(value[3]),
])
Self(value.array_map(u32::from_le_bytes))
}
fn into_counter_for_single_block_less_safe(self) -> Counter {

View File

@ -24,6 +24,7 @@
// The goal for this implementation is to drive the overhead as close to zero
// as possible.
use crate::polyfill::array_map::Map;
use crate::{
c, cpu, debug,
endian::{ArrayEncoding, BigEndian},
@ -463,32 +464,14 @@ pub const MAX_CHAINING_LEN: usize = MAX_OUTPUT_LEN;
fn sha256_format_output(input: State) -> Output {
let input = unsafe { &input.as32 };
Output {
as32: [
BigEndian::from(input[0]),
BigEndian::from(input[1]),
BigEndian::from(input[2]),
BigEndian::from(input[3]),
BigEndian::from(input[4]),
BigEndian::from(input[5]),
BigEndian::from(input[6]),
BigEndian::from(input[7]),
],
as32: input.array_map(BigEndian::from),
}
}
fn sha512_format_output(input: State) -> Output {
let input = unsafe { &input.as64 };
Output {
as64: [
BigEndian::from(input[0]),
BigEndian::from(input[1]),
BigEndian::from(input[2]),
BigEndian::from(input[3]),
BigEndian::from(input[4]),
BigEndian::from(input[5]),
BigEndian::from(input[6]),
BigEndian::from(input[7]),
],
as64: input.array_map(BigEndian::from),
}
}

View File

@ -41,4 +41,6 @@ pub mod slice {
#[macro_use]
mod chunks_fixed;
pub(crate) mod array_map;
pub use chunks_fixed::*;

36
src/polyfill/array_map.rs Normal file
View File

@ -0,0 +1,36 @@
// Copyright 2015-2016 Brian Smith.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
// TODO: Replace this with use of the array_map feature
// (https://github.com/rust-lang/rust/issues/75243) when it becomes stable.
pub(crate) trait Map<A, B, BArray> {
fn array_map(self, f: impl Fn(A) -> B) -> BArray;
}
impl<A, B> Map<A, B, [B; 4]> for [A; 4] {
#[inline]
fn array_map(self, f: impl Fn(A) -> B) -> [B; 4] {
let [a0, a1, a2, a3] = self;
[f(a0), f(a1), f(a2), f(a3)]
}
}
impl<A, B> Map<A, B, [B; 8]> for [A; 8] {
#[inline]
fn array_map(self, f: impl Fn(A) -> B) -> [B; 8] {
let [a0, a1, a2, a3, a4, a5, a6, a7] = self;
[f(a0), f(a1), f(a2), f(a3), f(a4), f(a5), f(a6), f(a7)]
}
}