wolf_crypto/mac/hmac/
digest.rs1use core::fmt;
2use crate::mac::hmac::algo::{self, Digest as _, HexDigest as _};
3use crate::ct;
4use crate::hex;
5
6#[must_use]
8#[repr(transparent)]
9#[derive(Copy, Clone)]
10pub struct Digest<D: algo::Digest> {
11 raw: D
12}
13
14impl<D: algo::Digest> fmt::Debug for Digest<D> {
15 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
17 f.write_str("Digest { ... }")
18 }
19}
20
21impl<D: algo::Digest + Copy> Digest<D> {
22 pub const fn new(digest: D) -> Self {
24 Self { raw: digest }
25 }
26
27 #[must_use]
37 pub const fn into_inner(self) -> D {
38 self.raw
39 }
40
41 pub fn hex_encode(&self) -> HexDigest<D::Hex> {
43 let mut out = D::Hex::zeroes();
44 hex::encode_into(self.as_ref(), out.as_mut()).unwrap();
45 HexDigest::new(out)
46 }
47}
48
49impl<D: algo::Digest> AsRef<[u8]> for Digest<D> {
50 #[inline]
51 fn as_ref(&self) -> &[u8] { self.raw.as_ref() }
52}
53
54impl<D: algo::Digest> AsRef<D> for Digest<D> {
55 #[inline]
56 fn as_ref(&self) -> &D { &self.raw }
57}
58
59impl<D: algo::Digest> PartialEq for Digest<D> {
60 fn eq(&self, other: &Self) -> bool {
62 ct::ct_eq(self.raw, other.raw)
63 }
64}
65
66impl<D: algo::Digest> Eq for Digest<D> {}
67
68impl<D: algo::Digest> PartialEq<[u8]> for Digest<D> {
69 fn eq(&self, other: &[u8]) -> bool {
71 ct::ct_eq(self.raw, other)
72 }
73}
74
75impl<D: algo::Digest, T> PartialEq<&T> for Digest<D> where Self: PartialEq<T> {
76 #[inline]
78 fn eq(&self, other: &&T) -> bool {
79 self.eq(other)
80 }
81}
82
83impl<D: algo::Digest, T> PartialEq<&mut T> for Digest<D> where Self: PartialEq<T> {
84 #[inline]
86 fn eq(&self, other: &&mut T) -> bool {
87 self.eq(other)
88 }
89}
90
91#[repr(transparent)]
93#[must_use]
94#[derive(Copy, Clone)]
95pub struct HexDigest<D: algo::HexDigest> {
96 raw: D
97}
98
99impl<D: algo::HexDigest> HexDigest<D> {
100 const fn new(digest: D) -> Self {
107 Self { raw: digest }
108 }
109
110 pub fn decode(&self) -> Digest<D::Digest> {
112 let mut output = D::Digest::zeroes();
113 hex::decode_into(self.raw.as_ref(), output.as_mut())
114 .unwrap();
116 Digest::new(output)
117 }
118
119 #[inline]
121 pub fn as_str(&self) -> &str {
122 unsafe { core::str::from_utf8_unchecked(self.raw.as_ref()) }
124 }
125
126 #[must_use]
137 pub const fn into_inner(self) -> D {
138 self.raw
139 }
140}
141
142impl<D: algo::HexDigest> AsRef<[u8]> for HexDigest<D> {
143 #[inline]
144 fn as_ref(&self) -> &[u8] { self.raw.as_ref() }
145}
146
147impl<D: algo::HexDigest> AsRef<D> for HexDigest<D> {
148 #[inline]
149 fn as_ref(&self) -> &D { &self.raw }
150}
151
152impl<D: algo::HexDigest> PartialEq for HexDigest<D> {
153 fn eq(&self, other: &Self) -> bool {
155 ct::ct_eq(self.raw, other.raw)
156 }
157}
158
159impl<D: algo::HexDigest> Eq for HexDigest<D> {}
160
161impl<D: algo::HexDigest> PartialEq<[u8]> for HexDigest<D> {
162 fn eq(&self, other: &[u8]) -> bool {
164 ct::ct_eq(self.raw, other)
165 }
166}
167
168impl<D: algo::HexDigest, T> PartialEq<&T> for HexDigest<D> where Self: PartialEq<T> {
169 #[inline]
171 fn eq(&self, other: &&T) -> bool {
172 self.eq(other)
173 }
174}
175
176impl<D: algo::HexDigest, T> PartialEq<&mut T> for HexDigest<D> where Self: PartialEq<T> {
177 #[inline]
179 fn eq(&self, other: &&mut T) -> bool {
180 self.eq(other)
181 }
182}
183
184impl<D: algo::HexDigest> From<HexDigest<D>> for Digest<D::Digest> {
185 fn from(value: HexDigest<D>) -> Self {
186 value.decode()
187 }
188}
189
190impl<D: algo::Digest> From<Digest<D>> for HexDigest<D::Hex> {
191 fn from(value: Digest<D>) -> Self {
192 value.hex_encode()
193 }
194}