<commit_before>//! Module for the SHA-2 family of hash functions.
use byteorder::{BigEndian, ByteOrder};

/// A trait for hash functions.
pub trait HashFunction: Default {
    /// Digest size in bytes.
    const DIGEST_SIZE: usize;

    /// Feeds input into the hash function to update its state.
    fn update(&mut self, input: &[u8]);

    /// Writes the hash function digest into an output buffer.
    fn write_digest(&mut self, output: &mut [u8]);
}

/// The SHA-512 hash function.
///
/// # Examples
///
/// ```
/// use crypto_pure::sha2::{HashFunction, Sha512};
/// let mut digest = [0; Sha512::DIGEST_SIZE];
/// let mut sha = Sha512::default();
/// sha.update(b"part one");
/// sha.update(b"part two");
/// sha.write_digest(&mut digest);
/// ```
pub struct Sha512(Sha);
/// The SHA-384 hash function.
///
/// # Examples
///
/// ```
/// use crypto_pure::sha2::{HashFunction, Sha384};
/// let mut digest = [0; Sha384::DIGEST_SIZE];
/// let mut sha = Sha384::default();
/// sha.update(b"part one");
/// sha.update(b"part two");
/// sha.write_digest(&mut digest);
/// ```
pub struct Sha384(Sha);

/// Wrapper for obtaining the SHA-512 digest for a complete message.
pub fn sha512(msg: &[u8]) -> [u8; Sha512::DIGEST_SIZE] {
    let mut digest = [0; Sha512::DIGEST_SIZE];
    let mut sha = Sha512::default();
    sha.update(msg);
    sha.write_digest(&mut digest);
    digest
}

/// Wrapper for obtaining the SHA-384 digest for a complete message.
pub fn sha384(msg: &[u8]) -> [u8; Sha384::DIGEST_SIZE] {
    let mut digest = [0; Sha384::DIGEST_SIZE];
    let mut sha = Sha384::default();
    sha.update(msg);
    sha.write_digest(&mut digest);
    digest
}

macro_rules! impl_sha { ($function:ident, $algorithm:expr) => (
    impl Default for $function {
        fn default() -> Self {
            $function(Sha::new(&$algorithm))
        }
    }

    impl HashFunction for $function {
        const DIGEST_SIZE: usize = $algorithm.digest_size;

        fn update(&mut self, input: &[u8]) {
            self.0.update(input);
        }

        fn write_digest(&mut self, output: &mut [u8]) {
            assert_eq!(Self::DIGEST_SIZE, output.len());
            self.0.write_digest(output);
        }
    }
)}

impl_sha!(Sha512, SHA512);
impl_sha!(Sha384, SHA384);

struct HashAlgorithm {
    digest_size: usize,
    initial_state: [u64; 8],
}

const SHA512: HashAlgorithm = HashAlgorithm {
    digest_size: 64,
    initial_state: [<commit_msg>sha2: add panic behavior to documentation<commit_after>//! Module for the SHA-2 family of hash functions.
use byteorder::{BigEndian, ByteOrder};

/// A trait for hash functions.
pub trait HashFunction: Default {
    /// Digest size in bytes.
    const DIGEST_SIZE: usize;

    /// Feeds input into the hash function to update its state.
    fn update(&mut self, input: &[u8]);

    /// Writes the hash function digest into an output buffer.
    fn write_digest(&mut self, output: &mut [u8]);
}

/// The SHA-512 hash function.
///
/// # Examples
///
/// ```
/// use crypto_pure::sha2::{HashFunction, Sha512};
/// let mut digest = [0; Sha512::DIGEST_SIZE];
/// let mut sha = Sha512::default();
/// sha.update(b"part one");
/// sha.update(b"part two");
/// sha.write_digest(&mut digest);
/// ```
pub struct Sha512(Sha);
/// The SHA-384 hash function.
///
/// # Examples
///
/// ```
/// use crypto_pure::sha2::{HashFunction, Sha384};
/// let mut digest = [0; Sha384::DIGEST_SIZE];
/// let mut sha = Sha384::default();
/// sha.update(b"part one");
/// sha.update(b"part two");
/// sha.write_digest(&mut digest);
/// ```
pub struct Sha384(Sha);

/// Wrapper for obtaining the SHA-512 digest for a complete message.
pub fn sha512(msg: &[u8]) -> [u8; Sha512::DIGEST_SIZE] {
    let mut digest = [0; Sha512::DIGEST_SIZE];
    let mut sha = Sha512::default();
    sha.update(msg);
    sha.write_digest(&mut digest);
    digest
}

/// Wrapper for obtaining the SHA-384 digest for a complete message.
pub fn sha384(msg: &[u8]) -> [u8; Sha384::DIGEST_SIZE] {
    let mut digest = [0; Sha384::DIGEST_SIZE];
    let mut sha = Sha384::default();
    sha.update(msg);
    sha.write_digest(&mut digest);
    digest
}

macro_rules! impl_sha { ($function:ident, $algorithm:expr) => (
    impl Default for $function {
        fn default() -> Self {
            $function(Sha::new(&$algorithm))
        }
    }

    impl HashFunction for $function {
        const DIGEST_SIZE: usize = $algorithm.digest_size;

        /// Feeds input into the hash function to update its state.
        ///
        /// # Panics
        ///
        /// Panics if called after `write_digest` has been called.
        fn update(&mut self, input: &[u8]) {
            self.0.update(input);
        }

        /// Writes the hash function digest into an output buffer.
        ///
        /// # Panics
        ///
        /// Panics if `output.len()` is not equal to the digest size.
        fn write_digest(&mut self, output: &mut [u8]) {
            assert_eq!(Self::DIGEST_SIZE, output.len());
            self.0.write_digest(output);
        }
    }
)}

impl_sha!(Sha512, SHA512);
impl_sha!(Sha384, SHA384);

struct HashAlgorithm {
    digest_size: usize,
    initial_state: [u64; 8],
}

const SHA512: HashAlgorithm = HashAlgorithm {
    digest_size: 64,
    initial_state: [
{'fraction_non_alphanumeric': 0.16553030303030303, 'fraction_numerical': 0.036931818181818184, 'mean_word_length': 2.682705718270572, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3334993', 'n_tokens_mistral': 1841, 'n_tokens_neox': 1701, 'n_words': 486}