use crate::constants::{
CRYPTO_HASH_SHA256_BYTES, CRYPTO_HASH_SHA512_BYTES, CRYPTO_HASH_SHA3256_BYTES,
CRYPTO_HASH_SHA3512_BYTES,
};
use crate::sha3::{Sha3256, Sha3512};
use crate::sha256::Sha256;
use crate::sha512::*;
pub type Digest = Sha512Digest;
pub type Sha256Digest = [u8; CRYPTO_HASH_SHA256_BYTES];
pub type Sha512Digest = [u8; CRYPTO_HASH_SHA512_BYTES];
pub type Sha3256Digest = [u8; CRYPTO_HASH_SHA3256_BYTES];
pub type Sha3512Digest = [u8; CRYPTO_HASH_SHA3512_BYTES];
pub fn crypto_hash_sha256(output: &mut Sha256Digest, input: &[u8]) {
let mut state = crypto_hash_sha256_init();
crypto_hash_sha256_update(&mut state, input);
crypto_hash_sha256_final(state, output);
}
#[derive(Default)]
pub struct Sha256State {
pub(super) hasher: Sha256,
}
pub fn crypto_hash_sha256_init() -> Sha256State {
Sha256State::default()
}
pub fn crypto_hash_sha256_update(state: &mut Sha256State, input: &[u8]) {
state.hasher.update(input);
}
pub fn crypto_hash_sha256_final(state: Sha256State, output: &mut Sha256Digest) {
state.hasher.finalize_into_bytes(output)
}
pub fn crypto_hash_sha512(output: &mut Digest, input: &[u8]) {
let mut state = crypto_hash_sha512_init();
crypto_hash_sha512_update(&mut state, input);
crypto_hash_sha512_final(state, output);
}
#[derive(Default)]
pub struct Sha512State {
pub(super) hasher: Sha512,
}
pub fn crypto_hash_sha512_init() -> Sha512State {
Sha512State::default()
}
pub fn crypto_hash_sha512_update(state: &mut Sha512State, input: &[u8]) {
state.hasher.update(input);
}
pub fn crypto_hash_sha512_final(state: Sha512State, output: &mut Digest) {
state.hasher.finalize_into_bytes(output)
}
pub fn crypto_hash_sha3256(output: &mut Sha3256Digest, input: &[u8]) {
let mut state = crypto_hash_sha3256_init();
crypto_hash_sha3256_update(&mut state, input);
crypto_hash_sha3256_final(state, output);
}
#[derive(Default)]
pub struct Sha3256State {
pub(super) hasher: Sha3256,
}
pub fn crypto_hash_sha3256_init() -> Sha3256State {
Sha3256State::default()
}
pub fn crypto_hash_sha3256_update(state: &mut Sha3256State, input: &[u8]) {
state.hasher.update(input);
}
pub fn crypto_hash_sha3256_final(state: Sha3256State, output: &mut Sha3256Digest) {
state.hasher.finalize_into_bytes(output)
}
pub fn crypto_hash_sha3512(output: &mut Sha3512Digest, input: &[u8]) {
let mut state = crypto_hash_sha3512_init();
crypto_hash_sha3512_update(&mut state, input);
crypto_hash_sha3512_final(state, output);
}
#[derive(Default)]
pub struct Sha3512State {
pub(super) hasher: Sha3512,
}
pub fn crypto_hash_sha3512_init() -> Sha3512State {
Sha3512State::default()
}
pub fn crypto_hash_sha3512_update(state: &mut Sha3512State, input: &[u8]) {
state.hasher.update(input);
}
pub fn crypto_hash_sha3512_final(state: Sha3512State, output: &mut Sha3512Digest) {
state.hasher.finalize_into_bytes(output)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_crypto_hash_sha256() {
let mut our_digest = [0u8; CRYPTO_HASH_SHA256_BYTES];
crypto_hash_sha256(&mut our_digest, b"abc");
let expected =
hex::decode("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad")
.expect("hex failed");
assert_eq!(our_digest.as_slice(), expected.as_slice());
}
#[test]
fn test_crypto_hash_sha3256() {
let mut our_digest = [0u8; CRYPTO_HASH_SHA3256_BYTES];
crypto_hash_sha3256(&mut our_digest, b"abc");
let expected =
hex::decode("3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532")
.expect("hex failed");
assert_eq!(our_digest.as_slice(), expected.as_slice());
}
#[test]
fn test_crypto_hash_sha3256_update() {
let mut state = crypto_hash_sha3256_init();
crypto_hash_sha3256_update(&mut state, b"a");
crypto_hash_sha3256_update(&mut state, b"b");
crypto_hash_sha3256_update(&mut state, b"c");
let mut our_digest = [0u8; CRYPTO_HASH_SHA3256_BYTES];
crypto_hash_sha3256_final(state, &mut our_digest);
let expected =
hex::decode("3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532")
.expect("hex failed");
assert_eq!(our_digest.as_slice(), expected.as_slice());
}
#[test]
fn test_crypto_hash_sha3512() {
let mut our_digest = [0u8; CRYPTO_HASH_SHA3512_BYTES];
crypto_hash_sha3512(&mut our_digest, b"abc");
let expected = hex::decode(concat!(
"b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e",
"10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0"
))
.expect("hex failed");
assert_eq!(our_digest.as_slice(), expected.as_slice());
}
#[test]
fn test_crypto_hash_sha3512_update() {
let mut state = crypto_hash_sha3512_init();
crypto_hash_sha3512_update(&mut state, b"a");
crypto_hash_sha3512_update(&mut state, b"b");
crypto_hash_sha3512_update(&mut state, b"c");
let mut our_digest = [0u8; CRYPTO_HASH_SHA3512_BYTES];
crypto_hash_sha3512_final(state, &mut our_digest);
let expected = hex::decode(concat!(
"b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e",
"10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0"
))
.expect("hex failed");
assert_eq!(our_digest.as_slice(), expected.as_slice());
}
#[cfg(dryoc_native_tests)]
#[test]
fn test_crypto_hash_sha512() {
use sodiumoxide::crypto::hash;
use crate::rng::randombytes_buf;
let r = randombytes_buf(64);
let their_digest = hash::hash(&r);
let mut our_digest = [0u8; CRYPTO_HASH_SHA512_BYTES];
crypto_hash_sha512(&mut our_digest, &r);
assert_eq!(their_digest.as_ref(), our_digest);
}
#[cfg(dryoc_native_tests)]
#[test]
fn test_crypto_hash_sha512_update() {
use sodiumoxide::crypto::hash;
use crate::rng::randombytes_buf;
let mut their_state = hash::State::new();
let mut our_state = crypto_hash_sha512_init();
for _ in 0..10 {
let r = randombytes_buf(64);
their_state.update(&r);
crypto_hash_sha512_update(&mut our_state, &r);
}
let their_digest = their_state.finalize();
let mut our_digest = [0u8; CRYPTO_HASH_SHA512_BYTES];
crypto_hash_sha512_final(our_state, &mut our_digest);
assert_eq!(their_digest.as_ref(), our_digest);
}
}