Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,4 @@ opt-level = 2
[patch.crates-io]
sha1 = { path = "sha1" }
whirlpool = { path = "whirlpool" }
sponge-cursor = { git = "https://github.com/RustCrypto/utils", branch = "add-sponge-cursor" }
7 changes: 4 additions & 3 deletions ascon-xof128/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,18 @@ categories = ["cryptography", "no-std"]
description = "Implementation of Ascon-XOF128 and Ascon-СXOF128"

[dependencies]
digest = "0.11"
digest = { version = "0.11", default-features = false }
ascon = "0.5"
sponge-cursor = "0.1"

[dev-dependencies]
digest = { version = "0.11", features = ["dev"] }
digest = { version = "0.11", default-features = false, features = ["dev"] }
hex-literal = "1"

[features]
default = ["alloc"]
alloc = ["digest/alloc"]
zeroize = ["digest/zeroize"]
zeroize = ["digest/zeroize", "sponge-cursor/zeroize"]

[package.metadata.docs.rs]
all-features = true
54 changes: 22 additions & 32 deletions ascon-xof128/src/cxof.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use ascon::State;
use digest::{
CollisionResistance, CustomizedInit, ExtendableOutput, HashMarker, OutputSizeUser, Update,
block_api::AlgorithmName,
block_buffer::EagerBuffer,
common::AlgorithmName,
common::hazmat::{DeserializeStateError, SerializableState, SerializedState},
consts::{U8, U16, U32, U48},
consts::{U16, U32, U41},
};
use sponge_cursor::SpongeCursor;

use crate::{AsconXof128Reader, consts::CXOF_INIT_STATE};

Expand All @@ -20,7 +20,7 @@ use crate::{AsconXof128Reader, consts::CXOF_INIT_STATE};
#[derive(Clone, Debug)]
pub struct AsconCxof128 {
state: State,
buffer: EagerBuffer<U8>,
cursor: SpongeCursor<8>,
}

impl CustomizedInit for AsconCxof128 {
Expand Down Expand Up @@ -52,8 +52,8 @@ impl CustomizedInit for AsconCxof128 {

ascon::permute12(&mut state);

let buffer = Default::default();
Self { state, buffer }
let cursor = Default::default();
Self { state, cursor }
}
}

Expand All @@ -71,26 +71,18 @@ impl CollisionResistance for AsconCxof128 {
impl Update for AsconCxof128 {
#[inline]
fn update(&mut self, data: &[u8]) {
self.buffer.digest_blocks(data, |blocks| {
for block in blocks {
self.state[0] ^= u64::from_le_bytes(block.0);
ascon::permute12(&mut self.state);
}
});
self.cursor
.absorb_u64_le(&mut self.state, ascon::permute12, data);
}
}

impl ExtendableOutput for AsconCxof128 {
type Reader = AsconXof128Reader;

fn finalize_xof(mut self) -> Self::Reader {
let Self { state, buffer } = &mut self;
let len = buffer.get_pos();
let last_block = buffer.pad_with_zeros();
let pad = 1u64 << (8 * len);
state[0] ^= u64::from_le_bytes(last_block.0) ^ pad;

AsconXof128Reader::new(state)
let pos = self.cursor.pos();
self.state[0] ^= 1u64 << (8 * pos);
AsconXof128Reader::new(&self.state)
}
}

Expand All @@ -102,37 +94,36 @@ impl AlgorithmName for AsconCxof128 {
}

impl SerializableState for AsconCxof128 {
type SerializedStateSize = U48;
type SerializedStateSize = U41;

#[inline]
fn serialize(&self) -> SerializedState<Self> {
let mut res = SerializedState::<Self>::default();
let (state_dst, buffer_dst) = res.split_at_mut(size_of::<State>());
let (state_dst, cursor_dst) = res.split_at_mut(size_of::<State>());
let mut chunks = state_dst.chunks_exact_mut(size_of::<u64>());
for (src, dst) in self.state.iter().zip(&mut chunks) {
dst.copy_from_slice(&src.to_le_bytes());
}
assert!(chunks.into_remainder().is_empty());
buffer_dst.copy_from_slice(&self.buffer.serialize());
assert_eq!(cursor_dst.len(), 1);
cursor_dst[0] = self.cursor.raw_pos();
res
}

#[inline]
fn deserialize(
serialized_state: &SerializedState<Self>,
) -> Result<Self, DeserializeStateError> {
let (state_src, buffer_src) = serialized_state.split_at(size_of::<State>());
let (state_src, cursor_src) = serialized_state.split_at(size_of::<State>());
let state = core::array::from_fn(|i| {
let n = size_of::<u64>();
let chunk = &state_src[n * i..][..n];
u64::from_le_bytes(chunk.try_into().expect("chunk has correct length"))
});
let buffer_src = buffer_src
.try_into()
.expect("buffer_src has correct length");
EagerBuffer::deserialize(buffer_src)
.map_err(|_| DeserializeStateError)
.map(|buffer| Self { state, buffer })
assert_eq!(cursor_src.len(), 1);
SpongeCursor::new(cursor_src[0])
.ok_or(DeserializeStateError)
.map(|cursor| Self { state, cursor })
}
}

Expand All @@ -141,10 +132,9 @@ impl Drop for AsconCxof128 {
fn drop(&mut self) {
#[cfg(feature = "zeroize")]
{
use digest::zeroize::{Zeroize, ZeroizeOnDrop};
fn assert_zeroize_on_drop<T: ZeroizeOnDrop>(_: &mut T) {}
use digest::zeroize::Zeroize;
self.state.zeroize();
assert_zeroize_on_drop(&mut self.buffer);
self.cursor.zeroize();
}
}
}
Expand Down
29 changes: 22 additions & 7 deletions ascon-xof128/src/reader.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,42 @@
use ascon::State;
use digest::{XofReader, block_buffer::ReadBuffer, consts::U8};
use digest::XofReader;
use sponge_cursor::SpongeCursor;

/// XOF reader used by Ascon-XOF128 and Ascon-CXOF128
#[derive(Clone, Debug)]
pub struct AsconXof128Reader {
state: State,
buffer: ReadBuffer<U8>,
cursor: SpongeCursor<8>,
}

impl AsconXof128Reader {
pub(super) fn new(state: &State) -> Self {
Self {
state: *state,
buffer: Default::default(),
cursor: Default::default(),
}
}
}

impl XofReader for AsconXof128Reader {
#[inline]
fn read(&mut self, buf: &mut [u8]) {
self.buffer.read(buf, |dst| {
ascon::permute12(&mut self.state);
*dst = self.state[0].to_le_bytes().into();
});
self.cursor
.squeeze_read_u64_le(&mut self.state, ascon::permute12, buf);
}
}

impl Drop for AsconXof128Reader {
#[inline]
fn drop(&mut self) {
#[cfg(feature = "zeroize")]
{
use digest::zeroize::Zeroize;
self.state.zeroize();
self.cursor.zeroize();
}
}
}

#[cfg(feature = "zeroize")]
impl digest::zeroize::ZeroizeOnDrop for AsconXof128Reader {}
Loading
Loading