chksum_sha2_512/
lib.rs

1//! This crate provides an implementation of the SHA-2 512 hash function with a straightforward interface for computing digests of bytes, files, directories, and more.
2//!
3//! For a low-level interface, you can explore the [`chksum_hash_sha2_512`] crate.
4//!
5//! # Setup
6//!
7//! To use this crate, add the following entry to your `Cargo.toml` file in the `dependencies` section:
8//!
9//! ```toml
10//! [dependencies]
11//! chksum-sha2-512 = "0.1.0"
12//! ```
13//!
14//! Alternatively, you can use the [`cargo add`](https://doc.rust-lang.org/cargo/commands/cargo-add.html) subcommand:
15//!
16//! ```sh
17//! cargo add chksum-sha2-512
18//! ```     
19//!
20//! # Usage
21//!
22//! Use the [`chksum`] function to calculate digest of file, directory and so on.
23//!
24//! ```rust
25//! # use std::path::Path;
26//! use std::fs::File;
27//!
28//! # use chksum_sha2_512::Result;
29//! use chksum_sha2_512 as sha2_512;
30//!
31//! # fn wrapper(path: &Path) -> Result<()> {
32//! let file = File::open(path)?;
33//! let digest = sha2_512::chksum(file)?;
34//! assert_eq!(
35//!     digest.to_hex_lowercase(),
36//!     "ed59c5759a9ece516cec0c0623142d0e9fe70a27d750eee7fd38f4550d50addd873d0fa1a51fc823c1e3d5cada203f4a05d8325caacb7d3e0727a701f3f07e5f"
37//! );
38//! # Ok(())
39//! # }
40//! ```
41//!
42//! ## Asynchronous Runtime
43//!
44//! Use the [`async_chksum`] function to calculate digest of file, directory and so on.
45//!
46//! ```rust
47//! # #[cfg(feature = "async-runtime-tokio")]
48//! # {
49//! # use std::path::Path;
50//! # use chksum_sha2_512::Result;
51//! use chksum_sha2_512 as sha2_512;
52//! use tokio::fs::File;
53//!
54//! # async fn wrapper(path: &Path) -> Result<()> {
55//! let file = File::open(path).await?;
56//! let digest = sha2_512::async_chksum(file).await?;
57//! assert_eq!(
58//!     digest.to_hex_lowercase(),
59//!     "ed59c5759a9ece516cec0c0623142d0e9fe70a27d750eee7fd38f4550d50addd873d0fa1a51fc823c1e3d5cada203f4a05d8325caacb7d3e0727a701f3f07e5f"
60//! );
61//! # Ok(())
62//! # }
63//! # }
64//! ```
65//!
66//! # Input Types
67//!
68//! ## Bytes
69//!
70//! ### Array
71//!
72//! ```rust
73//! # use chksum_sha2_512::Result;
74//! use chksum_sha2_512 as sha2_512;
75//!
76//! # fn wrapper() -> Result<()> {
77//! let data = [0, 1, 2, 3];
78//! let digest = sha2_512::chksum(data)?;
79//! assert_eq!(
80//!     digest.to_hex_lowercase(),
81//!     "ed59c5759a9ece516cec0c0623142d0e9fe70a27d750eee7fd38f4550d50addd873d0fa1a51fc823c1e3d5cada203f4a05d8325caacb7d3e0727a701f3f07e5f"
82//! );
83//! # Ok(())
84//! # }
85//! ```
86//!
87//! ### Vec
88//!
89//! ```rust
90//! # use chksum_sha2_512::Result;
91//! use chksum_sha2_512 as sha2_512;
92//!
93//! # fn wrapper() -> Result<()> {
94//! let data = vec![0, 1, 2, 3];
95//! let digest = sha2_512::chksum(data)?;
96//! assert_eq!(
97//!     digest.to_hex_lowercase(),
98//!     "ed59c5759a9ece516cec0c0623142d0e9fe70a27d750eee7fd38f4550d50addd873d0fa1a51fc823c1e3d5cada203f4a05d8325caacb7d3e0727a701f3f07e5f"
99//! );
100//! # Ok(())
101//! # }
102//! ```
103//!
104//! ### Slice
105//!
106//! ```rust
107//! # use chksum_sha2_512::Result;
108//! use chksum_sha2_512 as sha2_512;
109//!
110//! # fn wrapper() -> Result<()> {
111//! let data = &[0, 1, 2, 3];
112//! let digest = sha2_512::chksum(data)?;
113//! assert_eq!(
114//!     digest.to_hex_lowercase(),
115//!     "ed59c5759a9ece516cec0c0623142d0e9fe70a27d750eee7fd38f4550d50addd873d0fa1a51fc823c1e3d5cada203f4a05d8325caacb7d3e0727a701f3f07e5f"
116//! );
117//! # Ok(())
118//! # }
119//! ```
120//!
121//! ## Strings
122//!
123//! ### str
124//!
125//! ```rust
126//! # use chksum_sha2_512::Result;
127//! use chksum_sha2_512 as sha2_512;
128//!
129//! # fn wrapper() -> Result<()> {
130//! let data = "&str";
131//! let digest = sha2_512::chksum(data)?;
132//! assert_eq!(
133//!     digest.to_hex_lowercase(),
134//!     "ed59c5759a9ece516cec0c0623142d0e9fe70a27d750eee7fd38f4550d50addd873d0fa1a51fc823c1e3d5cada203f4a05d8325caacb7d3e0727a701f3f07e5f"
135//! );
136//! # Ok(())
137//! # }
138//! ```
139//!
140//! ### String
141//!
142//! ```rust
143//! # use chksum_sha2_512::Result;
144//! use chksum_sha2_512 as sha2_512;
145//!
146//! # fn wrapper() -> Result<()> {
147//! let data = String::from("String");
148//! let digest = sha2_512::chksum(data)?;
149//! assert_eq!(
150//!     digest.to_hex_lowercase(),
151//!     "ed59c5759a9ece516cec0c0623142d0e9fe70a27d750eee7fd38f4550d50addd873d0fa1a51fc823c1e3d5cada203f4a05d8325caacb7d3e0727a701f3f07e5f"
152//! );
153//! # Ok(())
154//! # }
155//! ```
156//!
157//! ## File
158//!
159//! ```rust
160//! # use std::path::Path;
161//! use std::fs::File;
162//!
163//! # use chksum_sha2_512::Result;
164//! use chksum_sha2_512 as sha2_512;
165//!
166//! # fn wrapper(path: &Path) -> Result<()> {
167//! let file = File::open(path)?;
168//! let digest = sha2_512::chksum(file)?;
169//! assert_eq!(
170//!     digest.to_hex_lowercase(),
171//!     "ed59c5759a9ece516cec0c0623142d0e9fe70a27d750eee7fd38f4550d50addd873d0fa1a51fc823c1e3d5cada203f4a05d8325caacb7d3e0727a701f3f07e5f"
172//! );
173//! # Ok(())
174//! # }
175//! ```
176//!
177//! ## Directory
178//!
179//! ```rust
180//! # use std::path::Path;
181//! use std::fs::read_dir;
182//!
183//! # use chksum_sha2_512::Result;
184//! use chksum_sha2_512 as sha2_512;
185//!
186//! # fn wrapper(path: &Path) -> Result<()> {
187//! let readdir = read_dir(path)?;
188//! let digest = sha2_512::chksum(readdir)?;
189//! assert_eq!(
190//!     digest.to_hex_lowercase(),
191//!     "ed59c5759a9ece516cec0c0623142d0e9fe70a27d750eee7fd38f4550d50addd873d0fa1a51fc823c1e3d5cada203f4a05d8325caacb7d3e0727a701f3f07e5f"
192//! );
193//! # Ok(())
194//! # }
195//! ```
196//!
197//! ## Path
198//!
199//! ```rust
200//! # use std::path::Path;
201//! use std::path::PathBuf;
202//!
203//! # use chksum_sha2_512::Result;
204//! use chksum_sha2_512 as sha2_512;
205//!
206//! # fn wrapper(path: &Path) -> Result<()> {
207//! let path = PathBuf::from(path);
208//! let digest = sha2_512::chksum(path)?;
209//! assert_eq!(
210//!     digest.to_hex_lowercase(),
211//!     "ed59c5759a9ece516cec0c0623142d0e9fe70a27d750eee7fd38f4550d50addd873d0fa1a51fc823c1e3d5cada203f4a05d8325caacb7d3e0727a701f3f07e5f"
212//! );
213//! # Ok(())
214//! # }
215//! ```
216//!
217//! ## Standard Input
218//!
219//! ```rust
220//! use std::io::stdin;
221//!
222//! # use chksum_sha2_512::Result;
223//! use chksum_sha2_512 as sha2_512;
224//!
225//! # fn wrapper() -> Result<()> {
226//! let stdin = stdin();
227//! let digest = sha2_512::chksum(stdin)?;
228//! assert_eq!(
229//!     digest.to_hex_lowercase(),
230//!     "ed59c5759a9ece516cec0c0623142d0e9fe70a27d750eee7fd38f4550d50addd873d0fa1a51fc823c1e3d5cada203f4a05d8325caacb7d3e0727a701f3f07e5f"
231//! );
232//! # Ok(())
233//! # }
234//! ```
235//!
236//! # Features
237//!
238//! Cargo features are utilized to enable extra options.
239//!
240//! * `reader` enables the [`reader`] module with the [`Reader`] struct.
241//! * `writer` enables the [`writer`] module with the [`Writer`] struct.
242//!
243//! By default, neither of these features is enabled.
244//!
245//! To customize your setup, disable the default features and enable only those that you need in your `Cargo.toml` file:
246//!
247//! ```toml
248//! [dependencies]
249//! chksum-sha2-512 = { version = "0.1.0", features = ["reader", "writer"] }
250//! ```
251//!
252//! Alternatively, you can use the [`cargo add`](https://doc.rust-lang.org/cargo/commands/cargo-add.html) subcommand:
253//!
254//! ```shell
255//! cargo add chksum-sha2-512 --features reader,writer
256//! ```
257//!
258//! ## Asynchronous Runtime
259//!
260//! * `async-runtime-tokio`: Enables async interface for Tokio runtime.
261//!
262//! By default, neither of these features is enabled.
263//!
264//! # License
265//!
266//! This crate is licensed under the MIT License.
267
268#![cfg_attr(docsrs, feature(doc_auto_cfg))]
269#![forbid(unsafe_code)]
270
271#[cfg(feature = "reader")]
272pub mod reader;
273#[cfg(feature = "writer")]
274pub mod writer;
275
276use std::fmt::{self, Display, Formatter, LowerHex, UpperHex};
277
278use chksum_core as core;
279#[cfg(feature = "async-runtime-tokio")]
280#[doc(no_inline)]
281pub use chksum_core::AsyncChksumable;
282#[doc(no_inline)]
283pub use chksum_core::{Chksumable, Error, Hash, Hashable, Result};
284#[doc(no_inline)]
285pub use chksum_hash_sha2_512 as hash;
286
287#[cfg(all(feature = "reader", feature = "async-runtime-tokio"))]
288#[doc(inline)]
289pub use crate::reader::AsyncReader;
290#[cfg(feature = "reader")]
291#[doc(inline)]
292pub use crate::reader::Reader;
293#[cfg(all(feature = "writer", feature = "async-runtime-tokio"))]
294#[doc(inline)]
295pub use crate::writer::AsyncWriter;
296#[cfg(feature = "writer")]
297#[doc(inline)]
298pub use crate::writer::Writer;
299
300/// Creates a new hash.
301///
302/// # Example
303///
304/// ```rust
305/// use chksum_sha2_512 as sha2_512;
306///
307/// let mut hash = sha2_512::new();
308/// hash.update(b"example data");
309/// let digest = hash.digest();
310/// assert_eq!(
311///     digest.to_hex_lowercase(),
312///     "ed59c5759a9ece516cec0c0623142d0e9fe70a27d750eee7fd38f4550d50addd873d0fa1a51fc823c1e3d5cada203f4a05d8325caacb7d3e0727a701f3f07e5f"
313/// );
314/// ```
315#[must_use]
316pub fn new() -> SHA2_512 {
317    SHA2_512::new()
318}
319
320/// Creates a default hash.
321///
322/// # Example
323///
324/// ```rust
325/// use chksum_sha2_512 as sha2_512;
326///
327/// let mut hash = sha2_512::default();
328/// hash.update(b"example data");
329/// let digest = hash.digest();
330/// assert_eq!(
331///     digest.to_hex_lowercase(),
332///     "ed59c5759a9ece516cec0c0623142d0e9fe70a27d750eee7fd38f4550d50addd873d0fa1a51fc823c1e3d5cada203f4a05d8325caacb7d3e0727a701f3f07e5f"
333/// );
334/// ```
335#[must_use]
336pub fn default() -> SHA2_512 {
337    core::default()
338}
339
340/// Computes the hash of the given input.
341///
342/// # Example
343///
344/// ```rust
345/// use chksum_sha2_512 as sha2_512;
346///
347/// let data = b"example data";
348/// let digest = sha2_512::hash(data);
349/// assert_eq!(
350///     digest.to_hex_lowercase(),
351///     "ed59c5759a9ece516cec0c0623142d0e9fe70a27d750eee7fd38f4550d50addd873d0fa1a51fc823c1e3d5cada203f4a05d8325caacb7d3e0727a701f3f07e5f"
352/// );
353/// ```
354pub fn hash(data: impl core::Hashable) -> Digest {
355    core::hash::<SHA2_512>(data)
356}
357
358/// Computes the hash of the given input.
359///
360/// # Example
361///
362/// ```rust
363/// use chksum_sha2_512 as sha2_512;
364///
365/// let data = b"example data";
366/// if let Ok(digest) = sha2_512::chksum(data) {
367///     assert_eq!(
368///         digest.to_hex_lowercase(),
369///         "ed59c5759a9ece516cec0c0623142d0e9fe70a27d750eee7fd38f4550d50addd873d0fa1a51fc823c1e3d5cada203f4a05d8325caacb7d3e0727a701f3f07e5f"
370///     );
371/// }
372/// ```
373pub fn chksum(data: impl core::Chksumable) -> Result<Digest> {
374    core::chksum::<SHA2_512>(data)
375}
376
377/// Computes the hash of the given input.
378///
379/// # Example
380///
381/// ```rust
382/// use chksum_sha2_512 as sha2_512;
383///
384/// # async fn wrapper() {
385/// let data = b"example data";
386/// if let Ok(digest) = sha2_512::async_chksum(data).await {
387///     assert_eq!(
388///         digest.to_hex_lowercase(),
389///         "ed59c5759a9ece516cec0c0623142d0e9fe70a27d750eee7fd38f4550d50addd873d0fa1a51fc823c1e3d5cada203f4a05d8325caacb7d3e0727a701f3f07e5f"
390///     );
391/// }
392/// # }
393/// ```
394#[cfg(feature = "async-runtime-tokio")]
395pub async fn async_chksum(data: impl core::AsyncChksumable) -> Result<Digest> {
396    core::async_chksum::<SHA2_512>(data).await
397}
398
399/// The SHA-2 512 hash instance.
400#[derive(Clone, Debug, Default, PartialEq, Eq)]
401pub struct SHA2_512 {
402    inner: hash::Update,
403}
404
405impl SHA2_512 {
406    /// Calculates the hash digest of an input data.
407    ///
408    /// # Example
409    ///
410    /// ```rust
411    /// use chksum_sha2_512::SHA2_512;
412    ///
413    /// let data = b"example data";
414    /// let digest = SHA2_512::hash(data);
415    /// assert_eq!(
416    ///     digest.to_hex_lowercase(),
417    ///     "ed59c5759a9ece516cec0c0623142d0e9fe70a27d750eee7fd38f4550d50addd873d0fa1a51fc823c1e3d5cada203f4a05d8325caacb7d3e0727a701f3f07e5f"
418    /// );
419    /// ```
420    #[must_use]
421    pub fn hash<T>(data: T) -> Digest
422    where
423        T: AsRef<[u8]>,
424    {
425        let mut hash = Self::new();
426        hash.update(data);
427        hash.digest()
428    }
429
430    /// Creates a new hash.
431    ///
432    /// # Example
433    ///
434    /// ```rust
435    /// use chksum_sha2_512::SHA2_512;
436    ///
437    /// let mut hash = SHA2_512::new();
438    /// hash.update(b"example data");
439    /// let digest = hash.digest();
440    /// assert_eq!(
441    ///     digest.to_hex_lowercase(),
442    ///     "ed59c5759a9ece516cec0c0623142d0e9fe70a27d750eee7fd38f4550d50addd873d0fa1a51fc823c1e3d5cada203f4a05d8325caacb7d3e0727a701f3f07e5f"
443    /// );
444    /// ```
445    #[must_use]
446    pub fn new() -> Self {
447        let inner = hash::Update::new();
448        Self { inner }
449    }
450
451    /// Updates the hash state with an input data.
452    ///
453    /// # Example
454    ///
455    /// ```rust
456    /// use chksum_sha2_512::SHA2_512;
457    ///
458    /// let mut hash = SHA2_512::new();
459    /// hash.update(b"example");
460    /// hash.update(" ");
461    /// hash.update("data");
462    /// let digest = hash.digest();
463    /// assert_eq!(
464    ///     digest.to_hex_lowercase(),
465    ///     "ed59c5759a9ece516cec0c0623142d0e9fe70a27d750eee7fd38f4550d50addd873d0fa1a51fc823c1e3d5cada203f4a05d8325caacb7d3e0727a701f3f07e5f"
466    /// );
467    /// ```
468    pub fn update<T>(&mut self, data: T)
469    where
470        T: AsRef<[u8]>,
471    {
472        self.inner.update(data);
473    }
474
475    /// Resets the hash state to its initial state.
476    ///
477    /// # Example
478    ///
479    /// ```rust
480    /// use chksum_sha2_512::SHA2_512;
481    ///
482    /// let mut hash = SHA2_512::new();
483    /// hash.update(b"example data");
484    /// hash.reset();
485    /// let digest = hash.digest();
486    /// assert_eq!(
487    ///     digest.to_hex_lowercase(),
488    ///     "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e"
489    /// );
490    /// ```
491    pub fn reset(&mut self) {
492        self.inner.reset();
493    }
494
495    /// Produces the hash digest.
496    ///
497    /// # Example
498    ///
499    /// ```
500    /// use chksum_sha2_512::SHA2_512;
501    ///
502    /// let mut hash = SHA2_512::new();
503    /// let digest = hash.digest();
504    /// assert_eq!(
505    ///     digest.to_hex_lowercase(),
506    ///     "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e"
507    /// );
508    /// ```
509    #[must_use]
510    pub fn digest(&self) -> Digest {
511        self.inner.digest().into()
512    }
513}
514
515impl core::Hash for SHA2_512 {
516    type Digest = Digest;
517
518    fn update<T>(&mut self, data: T)
519    where
520        T: AsRef<[u8]>,
521    {
522        self.update(data);
523    }
524
525    fn reset(&mut self) {
526        self.reset();
527    }
528
529    fn digest(&self) -> Self::Digest {
530        self.digest()
531    }
532}
533
534/// A hash digest.
535pub struct Digest(hash::Digest);
536
537impl Digest {
538    /// Creates a new digest.
539    #[must_use]
540    pub const fn new(digest: [u8; hash::DIGEST_LENGTH_BYTES]) -> Self {
541        let inner = hash::Digest::new(digest);
542        Self(inner)
543    }
544
545    /// Returns a byte slice of the digest's contents.
546    #[must_use]
547    pub const fn as_bytes(&self) -> &[u8] {
548        let Self(inner) = self;
549        inner.as_bytes()
550    }
551
552    /// Consumes the digest, returning the digest bytes.
553    #[must_use]
554    pub fn into_inner(self) -> [u8; hash::DIGEST_LENGTH_BYTES] {
555        let Self(inner) = self;
556        inner.into_inner()
557    }
558
559    /// Returns a string in the lowercase hexadecimal representation.
560    ///
561    /// # Example
562    ///
563    /// ```rust
564    /// use chksum_sha2_512 as sha2_512;
565    ///
566    /// #[rustfmt::skip]
567    /// let digest = [
568    ///     0xCF, 0x83, 0xE1, 0x35,
569    ///     0x7E, 0xEF, 0xB8, 0xBD,
570    ///     0xF1, 0x54, 0x28, 0x50,
571    ///     0xD6, 0x6D, 0x80, 0x07,
572    ///     0xD6, 0x20, 0xE4, 0x05,
573    ///     0x0B, 0x57, 0x15, 0xDC,
574    ///     0x83, 0xF4, 0xA9, 0x21,
575    ///     0xD3, 0x6C, 0xE9, 0xCE,
576    ///     0x47, 0xD0, 0xD1, 0x3C,
577    ///     0x5D, 0x85, 0xF2, 0xB0,
578    ///     0xFF, 0x83, 0x18, 0xD2,
579    ///     0x87, 0x7E, 0xEC, 0x2F,
580    ///     0x63, 0xB9, 0x31, 0xBD,
581    ///     0x47, 0x41, 0x7A, 0x81,
582    ///     0xA5, 0x38, 0x32, 0x7A,
583    ///     0xF9, 0x27, 0xDA, 0x3E,
584    /// ];
585    /// let digest = sha2_512::Digest::new(digest);
586    /// assert_eq!(
587    ///     digest.to_hex_lowercase(),
588    ///     "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e"
589    /// );
590    /// ```
591    #[must_use]
592    pub fn to_hex_lowercase(&self) -> String {
593        let Self(inner) = self;
594        inner.to_hex_lowercase()
595    }
596
597    /// Returns a string in the uppercase hexadecimal representation.
598    ///
599    /// # Example
600    ///
601    /// ```rust
602    /// use chksum_sha2_512 as sha2_512;
603    ///
604    /// #[rustfmt::skip]
605    /// let digest = [
606    ///     0xCF, 0x83, 0xE1, 0x35,
607    ///     0x7E, 0xEF, 0xB8, 0xBD,
608    ///     0xF1, 0x54, 0x28, 0x50,
609    ///     0xD6, 0x6D, 0x80, 0x07,
610    ///     0xD6, 0x20, 0xE4, 0x05,
611    ///     0x0B, 0x57, 0x15, 0xDC,
612    ///     0x83, 0xF4, 0xA9, 0x21,
613    ///     0xD3, 0x6C, 0xE9, 0xCE,
614    ///     0x47, 0xD0, 0xD1, 0x3C,
615    ///     0x5D, 0x85, 0xF2, 0xB0,
616    ///     0xFF, 0x83, 0x18, 0xD2,
617    ///     0x87, 0x7E, 0xEC, 0x2F,
618    ///     0x63, 0xB9, 0x31, 0xBD,
619    ///     0x47, 0x41, 0x7A, 0x81,
620    ///     0xA5, 0x38, 0x32, 0x7A,
621    ///     0xF9, 0x27, 0xDA, 0x3E,
622    /// ];
623    /// let digest = sha2_512::Digest::new(digest);
624    /// assert_eq!(
625    ///     digest.to_hex_uppercase(),
626    ///     "CF83E1357EEFB8BDF1542850D66D8007D620E4050B5715DC83F4A921D36CE9CE47D0D13C5D85F2B0FF8318D2877EEC2F63B931BD47417A81A538327AF927DA3E"
627    /// );
628    /// ```
629    #[must_use]
630    pub fn to_hex_uppercase(&self) -> String {
631        let Self(inner) = self;
632        inner.to_hex_uppercase()
633    }
634}
635
636impl core::Digest for Digest {}
637
638impl AsRef<[u8]> for Digest {
639    fn as_ref(&self) -> &[u8] {
640        let Self(inner) = self;
641        inner.as_bytes()
642    }
643}
644
645impl Display for Digest {
646    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
647        let Self(inner) = self;
648        Display::fmt(inner, f)
649    }
650}
651
652impl LowerHex for Digest {
653    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
654        let Self(inner) = self;
655        LowerHex::fmt(inner, f)
656    }
657}
658
659impl UpperHex for Digest {
660    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
661        let Self(inner) = self;
662        UpperHex::fmt(inner, f)
663    }
664}
665
666impl From<[u8; hash::DIGEST_LENGTH_BYTES]> for Digest {
667    fn from(digest: [u8; hash::DIGEST_LENGTH_BYTES]) -> Self {
668        Self::new(digest)
669    }
670}
671
672impl From<hash::Digest> for Digest {
673    fn from(digest: hash::Digest) -> Self {
674        Self(digest)
675    }
676}