Skip to main content

tuwunel_core/utils/hash/
sha256.rs

1use ring::{
2	digest,
3	digest::{Context, SHA256, SHA256_OUTPUT_LEN},
4};
5
6pub type Digest = [u8; SHA256_OUTPUT_LEN];
7
8/// Sha256 hash (input gather joined by 0xFF bytes)
9#[must_use]
10#[tracing::instrument(skip(inputs), level = "trace")]
11pub fn delimited<'a, T, I>(mut inputs: I) -> Digest
12where
13	I: Iterator<Item = T> + 'a,
14	T: AsRef<[u8]> + 'a,
15{
16	let mut ctx = Context::new(&SHA256);
17	if let Some(input) = inputs.next() {
18		ctx.update(input.as_ref());
19		for input in inputs {
20			ctx.update(b"\xFF");
21			ctx.update(input.as_ref());
22		}
23	}
24
25	ctx.finish()
26		.as_ref()
27		.try_into()
28		.expect("failed to return Digest buffer")
29}
30
31/// Sha256 hash (input gather)
32#[must_use]
33#[tracing::instrument(skip(inputs), level = "trace")]
34pub fn concat<'a, T, I>(inputs: I) -> Digest
35where
36	I: Iterator<Item = T> + 'a,
37	T: AsRef<[u8]> + 'a,
38{
39	inputs
40		.fold(Context::new(&SHA256), |mut ctx, input| {
41			ctx.update(input.as_ref());
42			ctx
43		})
44		.finish()
45		.as_ref()
46		.try_into()
47		.expect("failed to return Digest buffer")
48}
49
50/// Sha256 hash
51#[inline]
52#[must_use]
53#[tracing::instrument(skip(input), level = "trace")]
54pub fn hash<T>(input: T) -> Digest
55where
56	T: AsRef<[u8]>,
57{
58	digest::digest(&SHA256, input.as_ref())
59		.as_ref()
60		.try_into()
61		.expect("failed to return Digest buffer")
62}