1 //! This crate provides traits which describe functionality of cryptographic hash
2 //! functions.
3 //!
4 //! Traits in this repository are organized into high-level convenience traits,
5 //! mid-level traits which expose more fine-grained functionality, and
6 //! low-level traits intended to only be used by algorithm implementations:
7 //!
8 //! - **High-level convenience traits**: [`Digest`], [`DynDigest`]. They are wrappers
9 //!   around lower-level traits for most common hash-function use-cases.
10 //! - **Mid-level traits**: [`Update`], [`BlockInput`], [`Reset`], [`FixedOutput`],
11 //!   [`VariableOutput`], [`ExtendableOutput`]. These traits atomically describe
12 //!   available functionality of hash function implementations.
13 //! - **Low-level traits**: [`FixedOutputDirty`], [`VariableOutputDirty`],
14 //!   [`ExtendableOutputDirty`]. These traits are intended to be implemented by
15 //!   low-level algorithm providers only and simplify the amount of work
16 //!   implementers need to do and therefore shouldn't be used in
17 //!   application-level code.
18 //!
19 //! Additionally hash functions implement traits from the standard library:
20 //! `Default`, `Clone`, `Write`. The latter is feature-gated behind `std` feature,
21 //! which is usually enabled by default by hash implementation crates.
22 //!
23 //! The [`Digest`] trait is the most commonly used trait.
24 
25 #![no_std]
26 #![cfg_attr(docsrs, feature(doc_cfg))]
27 #![forbid(unsafe_code)]
28 #![doc(html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")]
29 #![warn(missing_docs, rust_2018_idioms)]
30 
31 #[cfg(feature = "alloc")]
32 #[macro_use]
33 extern crate alloc;
34 
35 #[cfg(feature = "std")]
36 extern crate std;
37 
38 #[cfg(feature = "dev")]
39 #[cfg_attr(docsrs, doc(cfg(feature = "dev")))]
40 pub mod dev;
41 
42 mod digest;
43 mod dyn_digest;
44 mod errors;
45 mod fixed;
46 mod variable;
47 mod xof;
48 
49 pub use crate::digest::{Digest, Output};
50 pub use crate::errors::InvalidOutputSize;
51 pub use crate::fixed::{FixedOutput, FixedOutputDirty};
52 pub use crate::variable::{VariableOutput, VariableOutputDirty};
53 pub use crate::xof::{ExtendableOutput, ExtendableOutputDirty, XofReader};
54 pub use generic_array::{self, typenum::consts};
55 
56 #[cfg(feature = "alloc")]
57 pub use dyn_digest::DynDigest;
58 
59 use generic_array::ArrayLength;
60 
61 /// Trait for updating digest state with input data.
62 pub trait Update {
63     /// Digest input data.
64     ///
65     /// This method can be called repeatedly, e.g. for processing streaming
66     /// messages.
update(&mut self, data: impl AsRef<[u8]>)67     fn update(&mut self, data: impl AsRef<[u8]>);
68 
69     /// Digest input data in a chained manner.
chain(mut self, data: impl AsRef<[u8]>) -> Self where Self: Sized,70     fn chain(mut self, data: impl AsRef<[u8]>) -> Self
71     where
72         Self: Sized,
73     {
74         self.update(data);
75         self
76     }
77 }
78 
79 /// Trait to indicate that digest function processes data in blocks of size
80 /// `BlockSize`.
81 ///
82 /// The main usage of this trait is for implementing HMAC generically.
83 pub trait BlockInput {
84     /// Block size
85     type BlockSize: ArrayLength<u8>;
86 }
87 
88 /// Trait for resetting hash instances
89 pub trait Reset {
90     /// Reset hasher instance to its initial state and return current state.
reset(&mut self)91     fn reset(&mut self);
92 }
93 
94 #[macro_export]
95 /// Implements `std::io::Write` trait for implementer of [`Update`]
96 macro_rules! impl_write {
97     ($hasher:ident) => {
98         #[cfg(feature = "std")]
99         impl std::io::Write for $hasher {
100             fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
101                 Update::update(self, buf);
102                 Ok(buf.len())
103             }
104 
105             fn flush(&mut self) -> std::io::Result<()> {
106                 Ok(())
107             }
108         }
109     };
110 }
111