Skip to main content

tuwunel_core/utils/hash/
sha256.rs

1//! SHA-256 digest helpers.
2//!
3//! The module hashes individual byte slices as well as concatenated or
4//! delimited collections. Results use fixed-size digest byte arrays.
5
6use aws_lc_rs::{
7	digest,
8	digest::{Context, SHA256, SHA256_OUTPUT_LEN},
9};
10
11/// Fixed-size output of a SHA-256 digest operation.
12///
13/// The array contains the algorithm's 32 output bytes in digest order. It can
14/// be encoded or compared without an additional allocation.
15pub type Digest = [u8; SHA256_OUTPUT_LEN];
16
17/// Sha256 hash (input gather joined by 0xFF bytes)
18#[must_use]
19#[tracing::instrument(skip(inputs), level = "trace")]
20pub fn delimited<'a, T, I>(mut inputs: I) -> Digest
21where
22	I: Iterator<Item = T> + 'a,
23	T: AsRef<[u8]> + 'a,
24{
25	let mut ctx = Context::new(&SHA256);
26	if let Some(input) = inputs.next() {
27		ctx.update(input.as_ref());
28		for input in inputs {
29			ctx.update(b"\xFF");
30			ctx.update(input.as_ref());
31		}
32	}
33
34	ctx.finish()
35		.as_ref()
36		.try_into()
37		.expect("failed to return Digest buffer")
38}
39
40/// Sha256 hash (input gather)
41#[must_use]
42#[tracing::instrument(skip(inputs), level = "trace")]
43pub fn concat<'a, T, I>(inputs: I) -> Digest
44where
45	I: Iterator<Item = T> + 'a,
46	T: AsRef<[u8]> + 'a,
47{
48	inputs
49		.fold(Context::new(&SHA256), |mut ctx, input| {
50			ctx.update(input.as_ref());
51			ctx
52		})
53		.finish()
54		.as_ref()
55		.try_into()
56		.expect("failed to return Digest buffer")
57}
58
59/// Sha256 hash
60#[inline]
61#[must_use]
62#[tracing::instrument(skip(input), level = "trace")]
63pub fn hash<T>(input: T) -> Digest
64where
65	T: AsRef<[u8]>,
66{
67	digest::digest(&SHA256, input.as_ref())
68		.as_ref()
69		.try_into()
70		.expect("failed to return Digest buffer")
71}