hashlib_prelude/
algorithm.rs

1// Copyright (C) 2018 Boyu Yang
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9/// Generic options for hash algorithm.
10pub trait HashOption: ::std::default::Default {}
11
12/// Unify all hash errors.
13pub enum HashError {
14    GenericError,
15}
16
17/// Kernel of hash algorithms.
18pub trait HashAlgoKernel {
19    type Option: HashOption;
20
21    type Error: ::std::convert::Into<HashError> + ::std::fmt::Debug;
22
23    /// The message digest of hash algorithms.
24    type Output: ::std::cmp::Eq
25        + ::std::convert::AsRef<[u8]>
26        + ::std::fmt::LowerHex
27        + ::std::fmt::UpperHex;
28
29    /// The name of hash algorithm.
30    fn name() -> &'static str;
31
32    /// The size of the output in bytes.
33    fn digest_size() -> usize;
34
35    /// Create a new hash algorithm.
36    fn new(opt: Self::Option) -> Self;
37
38    /// Append bytes to compute the digest.
39    fn update<T>(&mut self, data: T) -> Result<(), Self::Error>
40    where
41        T: ::std::convert::AsRef<[u8]>;
42
43    /// Finalize and return the digest.
44    fn finalize(self) -> Result<Self::Output, Self::Error>;
45}
46
47/// A hash algorithm.
48pub trait HashAlgo: ::std::default::Default {
49    type Kernel: HashAlgoKernel;
50
51    fn setup() -> <<Self as HashAlgo>::Kernel as HashAlgoKernel>::Option {
52        ::std::default::Default::default()
53    }
54
55    /// Input the complete bytes to compute the digest.
56    fn hash(
57        input: &[u8],
58    ) -> Result<
59        <<Self as HashAlgo>::Kernel as HashAlgoKernel>::Output,
60        <<Self as HashAlgo>::Kernel as HashAlgoKernel>::Error,
61    > {
62        let opt = Self::setup();
63        let mut algo = Self::Kernel::new(opt);
64        algo.update(input)?;
65        algo.finalize()
66    }
67}