Skip to content

Commit

Permalink
Use new *Dirty traits from the digest crate
Browse files Browse the repository at this point in the history
Updates all of the hash implementations in this repo to use the new
`*Dirty` traits which support blanket impls of the original traits,
which either consume the hasher instance or can be reset.

This will also provide a marginal efficiency boost, at least until
placement return lands (which, as it were, may be soon).
  • Loading branch information
tarcieri committed Jun 9, 2020
1 parent 2c14fad commit 9d48b6d
Show file tree
Hide file tree
Showing 23 changed files with 232 additions and 240 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 11 additions & 11 deletions blake2/src/blake2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ macro_rules! blake2_impl {
use $crate::simd::{Vector4, $vec};

use byteorder::{ByteOrder, LittleEndian};
use digest::{Update, BlockInput, FixedOutput, VariableOutput, Reset};
use digest::{Update, BlockInput, FixedOutputDirty, VariableOutputDirty, Reset};
use digest::InvalidOutputSize;
use digest::generic_array::GenericArray;
use digest::generic_array::typenum::{U4, Unsigned};
Expand Down Expand Up @@ -204,12 +204,12 @@ macro_rules! blake2_impl {
}

#[doc(hidden)]
pub fn finalize_last_node(self) -> Output {
pub fn finalize_last_node(mut self) -> Output {
self.finalize_with_flag(!0)
}


fn finalize_with_flag(mut self, f1: $word) -> Output {
fn finalize_with_flag(&mut self, f1: $word) -> Output {
let off = self.t as usize % (2 * $bytes::to_usize());
if off != 0 {
zero(&mut self.m.as_mut_bytes()[off..]);
Expand Down Expand Up @@ -278,7 +278,7 @@ macro_rules! blake2_impl {
}
}

impl VariableOutput for $state {
impl VariableOutputDirty for $state {
fn new(output_size: usize) -> Result<Self, InvalidOutputSize> {
if output_size == 0 || output_size > $bytes::to_usize() {
return Err(InvalidOutputSize);
Expand All @@ -290,14 +290,14 @@ macro_rules! blake2_impl {
self.n
}

fn finalize_variable<F: FnOnce(&[u8])>(self, f: F) {
fn finalize_variable_dirty(&mut self, f: impl FnOnce(&[u8])) {
let n = self.n;
let res = self.finalize_with_flag(0);
f(&res[..n]);
}
}

impl Reset for $state {
impl Reset for $state {
fn reset(&mut self) {
self.t = self.t0;
self.m = self.m0;
Expand Down Expand Up @@ -340,15 +340,15 @@ macro_rules! blake2_impl {
}
}

impl FixedOutput for $fix_state {
impl FixedOutputDirty for $fix_state {
type OutputSize = $bytes;

fn finalize_fixed(self) -> Output {
self.state.finalize_with_flag(0)
fn finalize_into_dirty(&mut self, out: &mut Output) {
out.copy_from_slice(&self.state.finalize_with_flag(0));
}
}

impl Reset for $fix_state {
impl Reset for $fix_state {
fn reset(&mut self) {
self.state.reset()
}
Expand Down Expand Up @@ -381,7 +381,7 @@ macro_rules! blake2_impl {
<Self as Reset>::reset(self)
}

fn finalize(self) -> crypto_mac::Output<Self> {
fn finalize(mut self) -> crypto_mac::Output<Self> {
crypto_mac::Output::new(self.state.finalize_with_flag(0))
}
}
Expand Down
40 changes: 19 additions & 21 deletions gost94/src/gost94.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@
use block_buffer::block_padding::ZeroPadding;
use block_buffer::byteorder::{ByteOrder, LE};
use block_buffer::BlockBuffer;
use digest::generic_array::typenum::U32;
use digest::generic_array::GenericArray;
use digest::impl_write;
use digest::{BlockInput, FixedOutput, Reset, Update};
use digest::{consts::U32, generic_array::GenericArray};
use digest::{BlockInput, FixedOutputDirty, Reset, Update};

pub(crate) type Block = [u8; 32];

Expand Down Expand Up @@ -238,31 +237,30 @@ impl Update for Gost94 {
}
}

impl FixedOutput for Gost94 {
impl FixedOutputDirty for Gost94 {
type OutputSize = U32;

fn finalize_fixed(mut self) -> GenericArray<u8, U32> {
{
let self_state = &mut self.state;
fn finalize_into_dirty(&mut self, out: &mut GenericArray<u8, U32>) {
let self_state = &mut self.state;

if self.buffer.position() != 0 {
let block = self
.buffer
.pad_with::<ZeroPadding>()
.expect("we never use input_lazy");
self_state.process_block(block);
}
if self.buffer.position() != 0 {
let block = self
.buffer
.pad_with::<ZeroPadding>()
.expect("we never use input_lazy");

let mut buf = Block::default();
self_state.process_block(block);
}

LE::write_u64_into(&self_state.n, &mut buf);
self_state.f(&buf);
let mut buf = Block::default();

LE::write_u64_into(&self_state.sigma, &mut buf);
self_state.f(&buf);
}
LE::write_u64_into(&self_state.n, &mut buf);
self_state.f(&buf);

LE::write_u64_into(&self_state.sigma, &mut buf);
self_state.f(&buf);

GenericArray::clone_from_slice(&self.state.h)
out.copy_from_slice(&self.state.h);
}
}

Expand Down
11 changes: 5 additions & 6 deletions gost94/src/macros.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
macro_rules! gost94_impl {
($state:ident, $sbox:expr) => {
use digest::generic_array::typenum::U32;
use digest::generic_array::GenericArray;
use digest::impl_write;
use digest::{BlockInput, FixedOutput, Reset, Update};
use digest::{consts::U32, generic_array::GenericArray};
use digest::{BlockInput, FixedOutputDirty, Reset, Update};
use $crate::gost94::{Block, Gost94, SBox};

/// GOST94 state
Expand Down Expand Up @@ -31,11 +30,11 @@ macro_rules! gost94_impl {
}
}

impl FixedOutput for $state {
impl FixedOutputDirty for $state {
type OutputSize = U32;

fn finalize_fixed(self) -> GenericArray<u8, Self::OutputSize> {
self.sh.finalize_fixed()
fn finalize_into_dirty(&mut self, out: &mut GenericArray<u8, U32>) {
self.sh.finalize_into_dirty(out)
}
}

Expand Down
10 changes: 4 additions & 6 deletions groestl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,6 @@ extern crate std;

pub use digest::{self, Digest};

use digest::generic_array::typenum::{Unsigned, U128, U28, U32, U48, U64};
use digest::generic_array::GenericArray;
use digest::impl_write;
use digest::InvalidOutputSize;
use digest::{BlockInput, FixedOutput, Reset, Update, VariableOutput};

mod consts;
mod groestl;
mod matrix;
Expand All @@ -59,6 +53,10 @@ mod state;
mod macros;

use crate::groestl::Groestl;
use digest::consts::{U128, U28, U32, U48, U64};
use digest::generic_array::typenum::Unsigned;
use digest::impl_write;
use digest::{BlockInput, FixedOutputDirty, InvalidOutputSize, Reset, Update, VariableOutputDirty};

impl_groestl!(Groestl512, U64, U128);
impl_groestl!(Groestl384, U48, U128);
Expand Down
10 changes: 5 additions & 5 deletions groestl/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ macro_rules! impl_groestl {
}
}

impl FixedOutput for $state {
impl FixedOutputDirty for $state {
type OutputSize = $output;

fn finalize_fixed(mut self) -> GenericArray<u8, Self::OutputSize> {
fn finalize_into_dirty(&mut self, out: &mut digest::Output<Self>) {
let block = self.groestl.finalize();
let n = block.len() - Self::OutputSize::to_usize();
GenericArray::clone_from_slice(&block[n..])
out.copy_from_slice(&block[n..])
}
}

Expand Down Expand Up @@ -62,7 +62,7 @@ macro_rules! impl_variable_groestl {
}
}

impl VariableOutput for $state {
impl VariableOutputDirty for $state {
fn new(output_size: usize) -> Result<Self, InvalidOutputSize> {
if output_size == $min || output_size > $max {
return Err(InvalidOutputSize);
Expand All @@ -76,7 +76,7 @@ macro_rules! impl_variable_groestl {
self.groestl.output_size
}

fn finalize_variable<F: FnOnce(&[u8])>(mut self, f: F) {
fn finalize_variable_dirty(&mut self, f: impl FnOnce(&[u8])) {
let block = self.groestl.finalize();
let n = block.len() - self.groestl.output_size;
f(&block[n..]);
Expand Down
2 changes: 1 addition & 1 deletion k12/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ categories = ["cryptography", "no-std"]
digest = { version = "= 0.9.0-pre", features = ["alloc"] }

[dev-dependencies]
digest = { version = "= 0.9.0-pre", features = ["dev"] }
digest = { version = "= 0.9.0-pre", features = ["alloc", "dev"] }
hex-literal = "0.2"

[features]
Expand Down
27 changes: 20 additions & 7 deletions k12/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@

#![no_std]
#![doc(html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")]
#![deny(unsafe_code)]
#![forbid(unsafe_code)]
#![warn(missing_docs, rust_2018_idioms)]

// TODO(tarcieri): eliminate alloc requirement
#[macro_use]
extern crate alloc;

pub use digest;
Expand All @@ -23,8 +24,8 @@ mod lanes;

// TODO(tarcieri): eliminate usage of `Vec`
use alloc::vec::Vec;
use core::{cmp::min, convert::TryInto};
use digest::{ExtendableOutput, Update, XofReader};
use core::{cmp::min, convert::TryInto, mem};
use digest::{ExtendableOutputDirty, Reset, Update, XofReader};

/// The KangarooTwelve extendable-output function (XOF).
#[derive(Debug, Default)]
Expand Down Expand Up @@ -60,18 +61,30 @@ impl Update for KangarooTwelve {
}
}

impl ExtendableOutput for KangarooTwelve {
impl ExtendableOutputDirty for KangarooTwelve {
type Reader = Reader;

fn finalize_xof(self) -> Self::Reader {
fn finalize_xof_dirty(&mut self) -> Self::Reader {
let mut buffer = vec![];
let mut customization = vec![];

mem::swap(&mut self.buffer, &mut buffer);
mem::swap(&mut self.customization, &mut customization);

Reader {
buffer: self.buffer,
customization: self.customization,
buffer,
customization,
finished: false,
}
}
}

impl Reset for KangarooTwelve {
fn reset(&mut self) {
self.buffer.clear();
}
}

/// Extensible output reader.
///
/// NOTE: this presently only supports one invocation and will *panic* if
Expand Down
17 changes: 10 additions & 7 deletions k12/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use k12::{
KangarooTwelve,
};

fn read_bytes<T: AsRef<[u8]>>(s: T) -> Vec<u8> {
fn read_bytes<T: AsRef<[u8]>>(s: T) -> Box<[u8]> {
fn b(c: u8) -> u8 {
match c {
b'0'..=b'9' => c - b'0',
Expand All @@ -13,9 +13,11 @@ fn read_bytes<T: AsRef<[u8]>>(s: T) -> Vec<u8> {
_ => unreachable!(),
}
}

let s = s.as_ref();
let mut i = 0;
let mut v = Vec::new();

while i < s.len() {
if s[i] == b' ' || s[i] == b'\n' {
i += 1;
Expand All @@ -26,22 +28,23 @@ fn read_bytes<T: AsRef<[u8]>>(s: T) -> Vec<u8> {
v.push(n);
i += 2;
}
v

v.into_boxed_slice()
}

#[test]
fn empty() {
// Source: reference paper
assert_eq!(
KangarooTwelve::new().chain(b"").finalize_vec(32),
KangarooTwelve::new().chain(b"").finalize_boxed(32),
read_bytes(
"1a c2 d4 50 fc 3b 42 05 d1 9d a7 bf ca
1b 37 51 3c 08 03 57 7a c7 16 7f 06 fe 2c e1 f0 ef 39 e5"
)
);

assert_eq!(
KangarooTwelve::new().chain(b"").finalize_vec(64),
KangarooTwelve::new().chain(b"").finalize_boxed(64),
read_bytes(
"1a c2 d4 50 fc 3b 42 05 d1 9d a7 bf ca
1b 37 51 3c 08 03 57 7a c7 16 7f 06 fe 2c e1 f0 ef 39 e5 42 69 c0 56 b8 c8 2e
Expand All @@ -50,7 +53,7 @@ fn empty() {
);

assert_eq!(
KangarooTwelve::new().chain(b"").finalize_vec(10032)[10000..],
KangarooTwelve::new().chain(b"").finalize_boxed(10032)[10000..],
read_bytes(
"e8 dc 56 36 42 f7 22 8c 84
68 4c 89 84 05 d3 a8 34 79 91 58 c0 79 b1 28 80 27 7a 1d 28 e2 ff 6d"
Expand Down Expand Up @@ -81,7 +84,7 @@ fn pat_m() {
{
let len = 17usize.pow(i);
let m: Vec<u8> = (0..len).map(|j| (j % 251) as u8).collect();
let result = KangarooTwelve::new().chain(&m).finalize_vec(32);
let result = KangarooTwelve::new().chain(&m).finalize_boxed(32);
assert_eq!(result, read_bytes(expected[i as usize]));
}
}
Expand All @@ -104,7 +107,7 @@ fn pat_c() {
let c: Vec<u8> = (0..len).map(|j| (j % 251) as u8).collect();
let result = KangarooTwelve::new_with_customization(c)
.chain(&m)
.finalize_vec(32);
.finalize_boxed(32);
assert_eq!(result, read_bytes(expected[i as usize]));
}
}
Loading

0 comments on commit 9d48b6d

Please sign in to comment.