qudag_crypto/hash.rs
1//! Cryptographic hash functions implementation.
2
3use thiserror::Error;
4
5/// Errors that can occur during hash operations.
6#[derive(Debug, Error)]
7pub enum HashError {
8 /// Input data is too large
9 #[error("Input data is too large")]
10 InputTooLarge,
11
12 /// Hash computation failed
13 #[error("Hash computation failed")]
14 ComputationFailed,
15}
16
17/// Hash function output.
18///
19/// # Examples
20///
21/// ```rust
22/// use qudag_crypto::hash::Digest;
23///
24/// let digest = Digest(vec![0x12, 0x34, 0x56, 0x78]);
25/// let bytes = digest.as_bytes();
26/// assert_eq!(bytes, &[0x12, 0x34, 0x56, 0x78]);
27/// ```
28#[derive(Debug, Clone, PartialEq, Eq)]
29pub struct Digest(Vec<u8>);
30
31impl Digest {
32 /// Get the digest as a byte slice.
33 ///
34 /// # Examples
35 ///
36 /// ```rust
37 /// use qudag_crypto::hash::Digest;
38 ///
39 /// let digest = Digest(vec![0x12, 0x34, 0x56, 0x78]);
40 /// let bytes = digest.as_bytes();
41 /// assert_eq!(bytes, &[0x12, 0x34, 0x56, 0x78]);
42 /// ```
43 pub fn as_bytes(&self) -> &[u8] {
44 &self.0
45 }
46
47 /// Convert the digest into a vector of bytes.
48 ///
49 /// # Examples
50 ///
51 /// ```rust
52 /// use qudag_crypto::hash::Digest;
53 ///
54 /// let digest = Digest(vec![0x12, 0x34, 0x56, 0x78]);
55 /// let bytes = digest.into_bytes();
56 /// assert_eq!(bytes, vec![0x12, 0x34, 0x56, 0x78]);
57 /// ```
58 pub fn into_bytes(self) -> Vec<u8> {
59 self.0
60 }
61}
62
63/// Cryptographic hash function trait.
64///
65/// # Examples
66///
67/// ```rust
68/// use qudag_crypto::hash::{HashFunction, HashError};
69///
70/// // Implement a simple hash function for demonstration
71/// struct SimpleHash {
72/// state: Vec<u8>,
73/// }
74///
75/// impl HashFunction for SimpleHash {
76/// fn new() -> Self {
77/// Self { state: Vec::new() }
78/// }
79///
80/// fn update(&mut self, data: &[u8]) -> Result<(), HashError> {
81/// self.state.extend_from_slice(data);
82/// Ok(())
83/// }
84///
85/// fn finalize(self) -> Result<qudag_crypto::hash::Digest, HashError> {
86/// // Simple checksum for example
87/// let sum = self.state.iter().fold(0u8, |acc, &x| acc.wrapping_add(x));
88/// Ok(qudag_crypto::hash::Digest(vec![sum]))
89/// }
90///
91/// fn hash(data: &[u8]) -> Result<qudag_crypto::hash::Digest, HashError> {
92/// let mut hasher = Self::new();
93/// hasher.update(data)?;
94/// hasher.finalize()
95/// }
96/// }
97///
98/// // Use the hash function
99/// let data = b"hello world";
100/// let digest = SimpleHash::hash(data).unwrap();
101/// ```
102pub trait HashFunction {
103 /// Create a new hash instance.
104 ///
105 /// # Examples
106 ///
107 /// ```rust,ignore
108 /// let mut hasher = Blake3Hash::new();
109 /// ```
110 fn new() -> Self;
111
112 /// Update the hash state with input data.
113 ///
114 /// # Examples
115 ///
116 /// ```rust,ignore
117 /// let mut hasher = Blake3Hash::new();
118 /// hasher.update(b"hello").unwrap();
119 /// hasher.update(b" world").unwrap();
120 /// ```
121 fn update(&mut self, data: &[u8]) -> Result<(), HashError>;
122
123 /// Finalize the hash computation and return the digest.
124 ///
125 /// # Examples
126 ///
127 /// ```rust,ignore
128 /// let mut hasher = Blake3Hash::new();
129 /// hasher.update(b"hello world").unwrap();
130 /// let digest = hasher.finalize().unwrap();
131 /// ```
132 fn finalize(self) -> Result<Digest, HashError>;
133
134 /// Compute hash of input data in one step.
135 ///
136 /// # Examples
137 ///
138 /// ```rust,ignore
139 /// let digest = Blake3Hash::hash(b"hello world").unwrap();
140 /// ```
141 fn hash(data: &[u8]) -> Result<Digest, HashError>;
142}