Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JH #74

Closed
wants to merge 26 commits into from
Closed

JH #74

Changes from 19 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
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
target/
*/target/
*/*/target/
Cargo.lock
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@ members = [
"blake2",
"gost94",
"groestl",
"jh",
"md2",
"md4",
"md5",
24 changes: 24 additions & 0 deletions jh/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[package]
name = "jh"
version = "0.2.1"
authors = ["RustCryptoDevelopers", "Kaz Wesley <kaz@lambdaverse.org>"]
license = "MIT/Apache-2.0"
description = "Portable JH with optimizations for x86-64"
documentation = "https://docs.rs/jh"
keywords = ["crypto", "jh", "hash", "digest"]
categories = ["cryptography", "no-std"]
repository = "https://github.com/RustCrypto/hashes"
edition = "2018"

[dependencies]
block-buffer = "0.7"
digest = "0.8"
hex-literal = "0.1"

[dev-dependencies]
digest = { version = "0.8", features = ["dev"] }

[features]
default = ["std"]
std = []
avx2 = []
7 changes: 7 additions & 0 deletions jh/benches/jh.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#![no_std]
#![feature(test)]
#[macro_use]
extern crate digest;
extern crate jh;

bench!(jh::Jh256);
460 changes: 460 additions & 0 deletions jh/src/compressor.rs

Large diffs are not rendered by default.

19 changes: 19 additions & 0 deletions jh/src/consts.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
pub const JH224_H0: [u8; 128] = hex!("
2dfedd62f99a98acae7cacd619d634e7a4831005bc301216b86038c6c966149466d9899f2580706fce9ea31b1d9b1adc11e8325f7b366e10f994857f02fa06c1
1b4f1b5cd8c840b397f6a17f6e738099dcdf93a5adeaa3d3a431e8dec9539a6822b4a98aec86a1e4d574ac959ce56cf015960deab5ab2bbf9611dcf0dd64ea6e
");

pub const JH256_H0: [u8; 128] = hex!("
eb98a3412c20d3eb92cdbe7b9cb245c11c93519160d4c7fa260082d67e508a03a4239e267726b945e0fb1a48d41a9477cdb5ab26026b177a56f024420fff2fa8
71a396897f2e4d751d144908f77de262277695f776248f9487d5b6574780296c5c5e272dac8e0d6c518450c657057a0f7be4d367702412ea89e3ab13d31cd769
");

pub const JH384_H0: [u8; 128] = hex!("
481e3bc6d813398a6d3b5e894ade879b63faea68d480ad2e332ccb21480f826798aec84d9082b928d455ea304111424936f555b2924847ecc7250a93baf43ce1
569b7f8a27db454c9efcbd496397af0e589fc27d26aa80cd80c08b8c9deb2eda8a7981e8f8d5373af43967adddd17a71a9b4d3bda475d394976c3fba9842737f
");

pub const JH512_H0: [u8; 128] = hex!("
6fd14b963e00aa17636a2e057a15d5438a225e8d0c97ef0be9341259f2b3c361891da0c1536f801e2aa9056bea2b6d80588eccdb2075baa6a90f3a76baf83bf7
0169e60541e34a6946b58a8e2e6fe65a1047a7d0c1843c243b6e71b12d5ac199cf57f6ec9db1f856a706887c5716b156e3c2fcdfe68517fb545a4678cc8cdd4b
");
123 changes: 123 additions & 0 deletions jh/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
// copyright 2017 Kaz Wesley

//! Optimized implementation of JH for x86-64 systems.
#![cfg_attr(not(features = "std"), no_std)]

pub extern crate digest;
#[macro_use]
extern crate hex_literal;

pub use digest::Digest;

use block_buffer::byteorder::BigEndian;
use block_buffer::generic_array::GenericArray as BBGenericArray;
use block_buffer::BlockBuffer;
use compressor::f8;
use digest::generic_array::typenum::{Unsigned, U28, U32, U48, U64};
use digest::generic_array::GenericArray as DGenericArray;

mod compressor;
mod consts;

#[derive(Clone)]
#[repr(C, align(16))]
struct State([u8; 128]);

impl State {
fn process_block(&mut self, block: &BBGenericArray<u8, U64>) {
unsafe {
f8(core::mem::transmute(self), block.as_ptr() as *const _);
}
}
}

impl core::fmt::Debug for State {
fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
f.debug_tuple("State").field(&"(array)").finish()
}
}

macro_rules! define_hasher {
($name:ident, $init:path, $OutputBytes:ident) => {
#[derive(Clone)]
pub struct $name {
state: State,
buffer: BlockBuffer<U64>,
datalen: usize,
}

impl core::fmt::Debug for $name {
fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
f.debug_struct("Jh")
.field("state", &self.state)
.field("buffer", &"(BlockBuffer<U64>)")
.field("datalen", &self.datalen)
.finish()
}
}

impl Default for $name {
fn default() -> Self {
Self {
state: State($init),
buffer: BlockBuffer::default(),
datalen: 0,
}
}
}

impl digest::BlockInput for $name {
type BlockSize = U64;
}

impl digest::Input for $name {
fn input<T: AsRef<[u8]>>(&mut self, data: T) {
let data = data.as_ref();
self.datalen += data.len();
let state = &mut self.state;
self.buffer.input(data, |b| state.process_block(b))
}
}

impl digest::FixedOutput for $name {
type OutputSize = $OutputBytes;

fn fixed_result(mut self) -> DGenericArray<u8, $OutputBytes> {
let state = &mut self.state;
let buffer = &mut self.buffer;
let len = self.datalen as u64 * 8;
if buffer.position() == 0 {
buffer.len64_padding::<BigEndian, _>(len, |b| state.process_block(b));
} else {
use block_buffer::block_padding::Iso7816;
state.process_block(buffer.pad_with::<Iso7816>().unwrap());
let mut last = BBGenericArray::default();
last[56] = (len >> 56) as u8;
last[57] = (len >> 48) as u8;
last[58] = (len >> 40) as u8;
last[59] = (len >> 32) as u8;
last[60] = (len >> 24) as u8;
last[61] = (len >> 16) as u8;
last[62] = (len >> 8) as u8;
last[63] = len as u8;
state.process_block(&last);
}
let mut out = DGenericArray::default();
out.copy_from_slice(&state.0[(128 - $OutputBytes::to_usize())..]);
out
}
}

impl digest::Reset for $name {
fn reset(&mut self) {
*self = Self::default();
}
}
};
}

define_hasher!(Jh224, consts::JH224_H0, U28);
define_hasher!(Jh256, consts::JH256_H0, U32);
define_hasher!(Jh384, consts::JH384_H0, U48);
define_hasher!(Jh512, consts::JH512_H0, U64);
Binary file added jh/tests/data/LongMsgKAT_224.blb
Binary file not shown.
Binary file added jh/tests/data/LongMsgKAT_256.blb
Binary file not shown.
Binary file added jh/tests/data/LongMsgKAT_384.blb
Binary file not shown.
Binary file added jh/tests/data/LongMsgKAT_512.blb
Binary file not shown.
Binary file added jh/tests/data/ShortMsgKAT_224.blb
Binary file not shown.
Binary file added jh/tests/data/ShortMsgKAT_256.blb
Binary file not shown.
Binary file added jh/tests/data/ShortMsgKAT_384.blb
Binary file not shown.
Binary file added jh/tests/data/ShortMsgKAT_512.blb
Binary file not shown.
16 changes: 16 additions & 0 deletions jh/tests/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#![no_std]
#[macro_use]
extern crate digest;
extern crate jh;

use digest::dev::digest_test;

new_test!(long_224, "LongMsgKAT_224", jh::Jh224, digest_test);
new_test!(long_256, "LongMsgKAT_256", jh::Jh256, digest_test);
new_test!(long_384, "LongMsgKAT_384", jh::Jh384, digest_test);
new_test!(long_512, "LongMsgKAT_512", jh::Jh512, digest_test);

new_test!(short_224, "ShortMsgKAT_224", jh::Jh224, digest_test);
new_test!(short_256, "ShortMsgKAT_256", jh::Jh256, digest_test);
new_test!(short_384, "ShortMsgKAT_384", jh::Jh384, digest_test);
new_test!(short_512, "ShortMsgKAT_512", jh::Jh512, digest_test);