Skip to content

Commit

Permalink
Add f1600x{2, 4, 8}
Browse files Browse the repository at this point in the history
  • Loading branch information
aewag committed Jan 13, 2022
1 parent 89d4bda commit 6a20262
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 64 deletions.
3 changes: 2 additions & 1 deletion keccak/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ keywords = ["crypto", "sponge", "keccak", "keccak-f", "keccak-p"]
categories = ["cryptography", "no-std"]

[dependencies]
num-traits = { version = "0.2.14", default-features = false }
packed_simd = { version = "0.3.6", package = "packed_simd_2", optional = true }

[features]
no_unroll = []
simd = ["packed_simd"]
38 changes: 20 additions & 18 deletions keccak/benches/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,28 @@
extern crate keccak;
extern crate test;

#[bench]
fn f200(b: &mut test::Bencher) {
let mut data = [0u8; 25];
b.iter(|| keccak::f200(&mut data));
}
use keccak::{f1600, f200, f400, f800};

#[bench]
fn f400(b: &mut test::Bencher) {
let mut data = [0u16; 25];
b.iter(|| keccak::f400(&mut data));
macro_rules! impl_bench {
($name:ident, $fn:ident, $type:expr) => {
#[bench]
fn $name(b: &mut test::Bencher) {
let mut data = [$type; 25];
b.iter(|| $fn(&mut data));
}
};
}

#[bench]
fn f800(b: &mut test::Bencher) {
let mut data = [0u32; 25];
b.iter(|| keccak::f800(&mut data));
}
impl_bench!(b_f200, f200, 0u8);
impl_bench!(b_f400, f400, 0u16);
impl_bench!(b_f800, f800, 0u32);
impl_bench!(b_f1600, f1600, 0u64);

#[cfg(feature = "simd")]
mod simd {
use keccak::simd::{f1600x2, f1600x4, f1600x8, u64x2, u64x4, u64x8};

#[bench]
fn f1600(b: &mut test::Bencher) {
let mut data = [0u64; 25];
b.iter(|| keccak::f1600(&mut data));
impl_bench!(b_f1600x2, f1600x2, u64x2::splat(0));
impl_bench!(b_f1600x4, f1600x4, u64x4::splat(0));
impl_bench!(b_f1600x8, f1600x8, u64x8::splat(0));
}
196 changes: 151 additions & 45 deletions keccak/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,15 @@
#![no_std]
#![allow(non_upper_case_globals)]

extern crate num_traits;
#[cfg(feature = "simd")]
extern crate packed_simd;

use core::{
convert::TryInto,
fmt::Debug,
mem::size_of,
ops::{BitXor, BitXorAssign},
ops::{BitAnd, BitAndAssign, BitXor, BitXorAssign, Not},
};
use num_traits::PrimInt;

#[rustfmt::skip]
mod unroll;
Expand Down Expand Up @@ -88,64 +88,94 @@ const RC: [u64; 24] = [
0x8000000080008008,
];

pub trait LaneSize: Debug + Default + PrimInt + BitXorAssign + BitXor<Output = Self> {
pub trait LaneSize:
Copy
+ Clone
+ Debug
+ Default
+ PartialEq
+ BitAndAssign
+ BitAnd<Output = Self>
+ BitXorAssign
+ BitXor<Output = Self>
+ Not<Output = Self>
{
const KECCAK_F_ROUND_COUNT: usize;

fn truncate_rc(rc: u64) -> Self;
fn rotate_left(self, n: u32) -> Self;
}

impl LaneSize for u8 {
const KECCAK_F_ROUND_COUNT: usize = 18;
macro_rules! impl_lanesize {
($type:ty, $round:expr, $truncate:expr) => {
impl LaneSize for $type {
const KECCAK_F_ROUND_COUNT: usize = $round;

fn truncate_rc(rc: u64) -> Self {
rc.to_le_bytes()[0]
}
}
fn truncate_rc(rc: u64) -> Self {
$truncate(rc)
}

impl LaneSize for u16 {
const KECCAK_F_ROUND_COUNT: usize = 20;

fn truncate_rc(rc: u64) -> Self {
let tmp = rc.to_le_bytes();
Self::from_le_bytes(tmp[..size_of::<Self>()].try_into().unwrap())
}
fn rotate_left(self, n: u32) -> Self {
self.rotate_left(n)
}
}
};
}

impl LaneSize for u32 {
const KECCAK_F_ROUND_COUNT: usize = 22;

fn truncate_rc(rc: u64) -> Self {
let tmp = rc.to_le_bytes();
Self::from_le_bytes(tmp[..size_of::<Self>()].try_into().unwrap())
}
impl_lanesize!(u8, 18, |rc: u64| { rc.to_le_bytes()[0] });
impl_lanesize!(u16, 20, |rc: u64| {
let tmp = rc.to_le_bytes();
Self::from_le_bytes(tmp[..size_of::<Self>()].try_into().unwrap())
});
impl_lanesize!(u32, 22, |rc: u64| {
let tmp = rc.to_le_bytes();
Self::from_le_bytes(tmp[..size_of::<Self>()].try_into().unwrap())
});
impl_lanesize!(u64, 24, |rc: u64| { rc });

macro_rules! impl_keccak {
($name:ident, $type:ty) => {
/// Keccak-$name sponge function
pub fn $name(state: &mut [$type; PLEN]) {
keccak_p(state, <$type>::KECCAK_F_ROUND_COUNT);
}
};
}

impl LaneSize for u64 {
const KECCAK_F_ROUND_COUNT: usize = 24;
impl_keccak!(f200, u8);
impl_keccak!(f400, u16);
impl_keccak!(f800, u32);
impl_keccak!(f1600, u64);

fn truncate_rc(rc: u64) -> Self {
rc
}
}
#[cfg(feature = "simd")]
pub mod simd {
#[cfg(feature = "simd")]
pub use packed_simd::{u64x2, u64x4, u64x8};
use {keccak_p, LaneSize, PLEN};

/// Keccak-f[200] sponge function
pub fn f200(state: &mut [u8; PLEN]) {
keccak_p(state, u8::KECCAK_F_ROUND_COUNT);
}
macro_rules! impl_lanesize_simd_u64xn {
($type:ty) => {
impl LaneSize for $type {
const KECCAK_F_ROUND_COUNT: usize = 24;

/// Keccak-f[400] sponge function
pub fn f400(state: &mut [u16; PLEN]) {
keccak_p(state, u16::KECCAK_F_ROUND_COUNT);
}
fn truncate_rc(rc: u64) -> Self {
Self::splat(rc)
}

/// Keccak-f[800] sponge function
pub fn f800(state: &mut [u32; PLEN]) {
keccak_p(state, u32::KECCAK_F_ROUND_COUNT);
}
fn rotate_left(self, n: u32) -> Self {
self.rotate_left(Self::splat(n.into()))
}
}
};
}

impl_lanesize_simd_u64xn!(u64x2);
impl_lanesize_simd_u64xn!(u64x4);
impl_lanesize_simd_u64xn!(u64x8);

/// Keccak-f[1600] sponge function
pub fn f1600(state: &mut [u64; PLEN]) {
keccak_p(state, u64::KECCAK_F_ROUND_COUNT);
impl_keccak!(f1600x2, u64x2);
impl_keccak!(f1600x4, u64x4);
impl_keccak!(f1600x8, u64x8);
}

#[allow(unused_assignments)]
Expand Down Expand Up @@ -336,4 +366,80 @@ mod tests {

keccak_f::<u64>(state_first, state_second);
}

#[cfg(feature = "simd")]
mod simd {
use simd::{u64x2, u64x4, u64x8};
use tests::keccak_f;

macro_rules! impl_keccak_f1600xn {
($name:ident, $type:ty) => {
#[test]
fn $name() {
// Test vectors are copied from XKCP (eXtended Keccak Code Package)
// https://github.com/XKCP/XKCP/blob/master/tests/TestVectors/KeccakF-1600-IntermediateValues.txt
let state_first = [
<$type>::splat(0xF1258F7940E1DDE7),
<$type>::splat(0x84D5CCF933C0478A),
<$type>::splat(0xD598261EA65AA9EE),
<$type>::splat(0xBD1547306F80494D),
<$type>::splat(0x8B284E056253D057),
<$type>::splat(0xFF97A42D7F8E6FD4),
<$type>::splat(0x90FEE5A0A44647C4),
<$type>::splat(0x8C5BDA0CD6192E76),
<$type>::splat(0xAD30A6F71B19059C),
<$type>::splat(0x30935AB7D08FFC64),
<$type>::splat(0xEB5AA93F2317D635),
<$type>::splat(0xA9A6E6260D712103),
<$type>::splat(0x81A57C16DBCF555F),
<$type>::splat(0x43B831CD0347C826),
<$type>::splat(0x01F22F1A11A5569F),
<$type>::splat(0x05E5635A21D9AE61),
<$type>::splat(0x64BEFEF28CC970F2),
<$type>::splat(0x613670957BC46611),
<$type>::splat(0xB87C5A554FD00ECB),
<$type>::splat(0x8C3EE88A1CCF32C8),
<$type>::splat(0x940C7922AE3A2614),
<$type>::splat(0x1841F924A2C509E4),
<$type>::splat(0x16F53526E70465C2),
<$type>::splat(0x75F644E97F30A13B),
<$type>::splat(0xEAF1FF7B5CECA249),
];
let state_second = [
<$type>::splat(0x2D5C954DF96ECB3C),
<$type>::splat(0x6A332CD07057B56D),
<$type>::splat(0x093D8D1270D76B6C),
<$type>::splat(0x8A20D9B25569D094),
<$type>::splat(0x4F9C4F99E5E7F156),
<$type>::splat(0xF957B9A2DA65FB38),
<$type>::splat(0x85773DAE1275AF0D),
<$type>::splat(0xFAF4F247C3D810F7),
<$type>::splat(0x1F1B9EE6F79A8759),
<$type>::splat(0xE4FECC0FEE98B425),
<$type>::splat(0x68CE61B6B9CE68A1),
<$type>::splat(0xDEEA66C4BA8F974F),
<$type>::splat(0x33C43D836EAFB1F5),
<$type>::splat(0xE00654042719DBD9),
<$type>::splat(0x7CF8A9F009831265),
<$type>::splat(0xFD5449A6BF174743),
<$type>::splat(0x97DDAD33D8994B40),
<$type>::splat(0x48EAD5FC5D0BE774),
<$type>::splat(0xE3B8C8EE55B7B03C),
<$type>::splat(0x91A0226E649E42E9),
<$type>::splat(0x900E3129E7BADD7B),
<$type>::splat(0x202A9EC5FAA3CCE8),
<$type>::splat(0x5B3402464E1C3DB6),
<$type>::splat(0x609F4E62A44C1059),
<$type>::splat(0x20D06CD26A8FBF5C),
];

keccak_f::<$type>(state_first, state_second);
}
};
}

impl_keccak_f1600xn!(keccak_f1600x2, u64x2);
impl_keccak_f1600xn!(keccak_f1600x4, u64x4);
impl_keccak_f1600xn!(keccak_f1600x8, u64x8);
}
}

0 comments on commit 6a20262

Please sign in to comment.