Skip to content

Commit c094b4c

Browse files
committed
blake2: extract Hash types into modules
Clearing out the `blake2b` and `blake2s` modules in order to add the primary user-facing types there.
1 parent ab8ac0d commit c094b4c

4 files changed

Lines changed: 148 additions & 142 deletions

File tree

blake2/src/blake2b.rs

Lines changed: 2 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,12 @@ pub(crate) mod backend;
2727
pub mod many;
2828
pub(crate) mod state;
2929

30+
mod hash;
3031
mod params;
3132
#[cfg(test)]
3233
mod test;
3334

34-
pub use self::{params::Params, state::State};
35+
pub use self::{hash::Hash, params::Params, state::State};
3536

3637
use core::{fmt, mem::size_of};
3738

@@ -96,76 +97,6 @@ pub fn blake2b(input: &[u8]) -> Hash {
9697
Params::new().hash(input)
9798
}
9899

99-
type HexString = arrayvec::ArrayString<[u8; 2 * OUTBYTES]>;
100-
101-
/// A finalized BLAKE2 hash, with constant-time equality.
102-
#[derive(Clone, Copy)]
103-
pub struct Hash {
104-
pub(crate) bytes: [u8; OUTBYTES],
105-
pub(crate) len: u8,
106-
}
107-
108-
impl Hash {
109-
/// Convert the hash to a byte slice. Note that if you're using BLAKE2 as a MAC, you need
110-
/// constant time equality, which `&[u8]` doesn't provide.
111-
pub fn as_bytes(&self) -> &[u8] {
112-
&self.bytes[..self.len as usize]
113-
}
114-
115-
/// Convert the hash to a byte array. Note that if you're using BLAKE2 as a
116-
/// MAC, you need constant time equality, which arrays don't provide. This
117-
/// panics in debug mode if the length of the hash isn't `OUTBYTES`.
118-
#[inline]
119-
pub fn as_array(&self) -> &[u8; OUTBYTES] {
120-
debug_assert_eq!(self.len as usize, OUTBYTES);
121-
&self.bytes
122-
}
123-
124-
/// Convert the hash to a lowercase hexadecimal
125-
/// [`ArrayString`](https://docs.rs/arrayvec/0.4/arrayvec/struct.ArrayString.html).
126-
pub fn to_hex(self) -> HexString {
127-
bytes_to_hex(self.as_bytes())
128-
}
129-
}
130-
131-
fn bytes_to_hex(bytes: &[u8]) -> HexString {
132-
let mut s = arrayvec::ArrayString::new();
133-
let table = b"0123456789abcdef";
134-
for &b in bytes {
135-
s.push(table[(b >> 4) as usize] as char);
136-
s.push(table[(b & 0xf) as usize] as char);
137-
}
138-
s
139-
}
140-
141-
/// This implementation is constant time, if the two hashes are the same length.
142-
impl PartialEq for Hash {
143-
fn eq(&self, other: &Hash) -> bool {
144-
constant_time_eq::constant_time_eq(self.as_bytes(), other.as_bytes())
145-
}
146-
}
147-
148-
/// This implementation is constant time, if the slice is the same length as the hash.
149-
impl PartialEq<[u8]> for Hash {
150-
fn eq(&self, other: &[u8]) -> bool {
151-
constant_time_eq::constant_time_eq(self.as_bytes(), other)
152-
}
153-
}
154-
155-
impl Eq for Hash {}
156-
157-
impl AsRef<[u8]> for Hash {
158-
fn as_ref(&self) -> &[u8] {
159-
self.as_bytes()
160-
}
161-
}
162-
163-
impl fmt::Debug for Hash {
164-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
165-
write!(f, "Hash(0x{})", self.to_hex())
166-
}
167-
}
168-
169100
// Paint a byte pattern that won't repeat, so that we don't accidentally miss
170101
// buffer offset bugs. This is the same as what Bao uses in its tests.
171102
#[cfg(test)]

blake2/src/blake2b/hash.rs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
use super::OUTBYTES;
2+
use core::fmt;
3+
4+
type HexString = arrayvec::ArrayString<[u8; 2 * OUTBYTES]>;
5+
6+
/// A finalized BLAKE2 hash, with constant-time equality.
7+
#[derive(Clone, Copy)]
8+
pub struct Hash {
9+
pub(crate) bytes: [u8; OUTBYTES],
10+
pub(crate) len: u8,
11+
}
12+
13+
impl Hash {
14+
/// Convert the hash to a byte slice. Note that if you're using BLAKE2 as a MAC, you need
15+
/// constant time equality, which `&[u8]` doesn't provide.
16+
pub fn as_bytes(&self) -> &[u8] {
17+
&self.bytes[..self.len as usize]
18+
}
19+
20+
/// Convert the hash to a byte array. Note that if you're using BLAKE2 as a
21+
/// MAC, you need constant time equality, which arrays don't provide. This
22+
/// panics in debug mode if the length of the hash isn't `OUTBYTES`.
23+
#[inline]
24+
pub fn as_array(&self) -> &[u8; OUTBYTES] {
25+
debug_assert_eq!(self.len as usize, OUTBYTES);
26+
&self.bytes
27+
}
28+
29+
/// Convert the hash to a lowercase hexadecimal
30+
/// [`ArrayString`](https://docs.rs/arrayvec/0.4/arrayvec/struct.ArrayString.html).
31+
pub fn to_hex(self) -> HexString {
32+
bytes_to_hex(self.as_bytes())
33+
}
34+
}
35+
36+
fn bytes_to_hex(bytes: &[u8]) -> HexString {
37+
let mut s = arrayvec::ArrayString::new();
38+
let table = b"0123456789abcdef";
39+
for &b in bytes {
40+
s.push(table[(b >> 4) as usize] as char);
41+
s.push(table[(b & 0xf) as usize] as char);
42+
}
43+
s
44+
}
45+
46+
/// This implementation is constant time, if the two hashes are the same length.
47+
impl PartialEq for Hash {
48+
fn eq(&self, other: &Hash) -> bool {
49+
constant_time_eq::constant_time_eq(self.as_bytes(), other.as_bytes())
50+
}
51+
}
52+
53+
/// This implementation is constant time, if the slice is the same length as the hash.
54+
impl PartialEq<[u8]> for Hash {
55+
fn eq(&self, other: &[u8]) -> bool {
56+
constant_time_eq::constant_time_eq(self.as_bytes(), other)
57+
}
58+
}
59+
60+
impl Eq for Hash {}
61+
62+
impl AsRef<[u8]> for Hash {
63+
fn as_ref(&self) -> &[u8] {
64+
self.as_bytes()
65+
}
66+
}
67+
68+
impl fmt::Debug for Hash {
69+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70+
write!(f, "Hash(0x{})", self.to_hex())
71+
}
72+
}

blake2/src/blake2s.rs

Lines changed: 2 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,12 @@ pub(crate) mod backend;
2626
pub mod many;
2727
pub(crate) mod state;
2828

29+
mod hash;
2930
mod params;
3031
#[cfg(test)]
3132
mod test;
3233

33-
pub use self::{params::Params, state::State};
34+
pub use self::{hash::Hash, params::Params, state::State};
3435

3536
use crate::blake2sp;
3637
use core::{fmt, mem::size_of};
@@ -86,76 +87,6 @@ pub fn blake2s(input: &[u8]) -> Hash {
8687
Params::new().hash(input)
8788
}
8889

89-
type HexString = arrayvec::ArrayString<[u8; 2 * OUTBYTES]>;
90-
91-
/// A finalized BLAKE2 hash, with constant-time equality.
92-
#[derive(Clone, Copy)]
93-
pub struct Hash {
94-
pub(crate) bytes: [u8; OUTBYTES],
95-
pub(crate) len: u8,
96-
}
97-
98-
impl Hash {
99-
/// Convert the hash to a byte slice. Note that if you're using BLAKE2 as a MAC, you need
100-
/// constant time equality, which `&[u8]` doesn't provide.
101-
pub fn as_bytes(&self) -> &[u8] {
102-
&self.bytes[..self.len as usize]
103-
}
104-
105-
/// Convert the hash to a byte array. Note that if you're using BLAKE2 as a
106-
/// MAC, you need constant time equality, which arrays don't provide. This
107-
/// panics in debug mode if the length of the hash isn't `OUTBYTES`.
108-
#[inline]
109-
pub fn as_array(&self) -> &[u8; OUTBYTES] {
110-
debug_assert_eq!(self.len as usize, OUTBYTES);
111-
&self.bytes
112-
}
113-
114-
/// Convert the hash to a lowercase hexadecimal
115-
/// [`ArrayString`](https://docs.rs/arrayvec/0.4/arrayvec/struct.ArrayString.html).
116-
pub fn to_hex(self) -> HexString {
117-
bytes_to_hex(self.as_bytes())
118-
}
119-
}
120-
121-
fn bytes_to_hex(bytes: &[u8]) -> HexString {
122-
let mut s = arrayvec::ArrayString::new();
123-
let table = b"0123456789abcdef";
124-
for &b in bytes {
125-
s.push(table[(b >> 4) as usize] as char);
126-
s.push(table[(b & 0xf) as usize] as char);
127-
}
128-
s
129-
}
130-
131-
/// This implementation is constant time, if the two hashes are the same length.
132-
impl PartialEq for Hash {
133-
fn eq(&self, other: &Hash) -> bool {
134-
constant_time_eq::constant_time_eq(self.as_bytes(), other.as_bytes())
135-
}
136-
}
137-
138-
/// This implementation is constant time, if the slice is the same length as the hash.
139-
impl PartialEq<[u8]> for Hash {
140-
fn eq(&self, other: &[u8]) -> bool {
141-
constant_time_eq::constant_time_eq(self.as_bytes(), other)
142-
}
143-
}
144-
145-
impl Eq for Hash {}
146-
147-
impl AsRef<[u8]> for Hash {
148-
fn as_ref(&self) -> &[u8] {
149-
self.as_bytes()
150-
}
151-
}
152-
153-
impl fmt::Debug for Hash {
154-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
155-
write!(f, "Hash(0x{})", self.to_hex())
156-
}
157-
}
158-
15990
// Paint a byte pattern that won't repeat, so that we don't accidentally miss
16091
// buffer offset bugs. This is the same as what Bao uses in its tests.
16192
#[cfg(test)]

blake2/src/blake2s/hash.rs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
use super::OUTBYTES;
2+
use core::fmt;
3+
4+
type HexString = arrayvec::ArrayString<[u8; 2 * OUTBYTES]>;
5+
6+
/// A finalized BLAKE2 hash, with constant-time equality.
7+
#[derive(Clone, Copy)]
8+
pub struct Hash {
9+
pub(crate) bytes: [u8; OUTBYTES],
10+
pub(crate) len: u8,
11+
}
12+
13+
impl Hash {
14+
/// Convert the hash to a byte slice. Note that if you're using BLAKE2 as a MAC, you need
15+
/// constant time equality, which `&[u8]` doesn't provide.
16+
pub fn as_bytes(&self) -> &[u8] {
17+
&self.bytes[..self.len as usize]
18+
}
19+
20+
/// Convert the hash to a byte array. Note that if you're using BLAKE2 as a
21+
/// MAC, you need constant time equality, which arrays don't provide. This
22+
/// panics in debug mode if the length of the hash isn't `OUTBYTES`.
23+
#[inline]
24+
pub fn as_array(&self) -> &[u8; OUTBYTES] {
25+
debug_assert_eq!(self.len as usize, OUTBYTES);
26+
&self.bytes
27+
}
28+
29+
/// Convert the hash to a lowercase hexadecimal
30+
/// [`ArrayString`](https://docs.rs/arrayvec/0.4/arrayvec/struct.ArrayString.html).
31+
pub fn to_hex(self) -> HexString {
32+
bytes_to_hex(self.as_bytes())
33+
}
34+
}
35+
36+
fn bytes_to_hex(bytes: &[u8]) -> HexString {
37+
let mut s = arrayvec::ArrayString::new();
38+
let table = b"0123456789abcdef";
39+
for &b in bytes {
40+
s.push(table[(b >> 4) as usize] as char);
41+
s.push(table[(b & 0xf) as usize] as char);
42+
}
43+
s
44+
}
45+
46+
/// This implementation is constant time, if the two hashes are the same length.
47+
impl PartialEq for Hash {
48+
fn eq(&self, other: &Hash) -> bool {
49+
constant_time_eq::constant_time_eq(self.as_bytes(), other.as_bytes())
50+
}
51+
}
52+
53+
/// This implementation is constant time, if the slice is the same length as the hash.
54+
impl PartialEq<[u8]> for Hash {
55+
fn eq(&self, other: &[u8]) -> bool {
56+
constant_time_eq::constant_time_eq(self.as_bytes(), other)
57+
}
58+
}
59+
60+
impl Eq for Hash {}
61+
62+
impl AsRef<[u8]> for Hash {
63+
fn as_ref(&self) -> &[u8] {
64+
self.as_bytes()
65+
}
66+
}
67+
68+
impl fmt::Debug for Hash {
69+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70+
write!(f, "Hash(0x{})", self.to_hex())
71+
}
72+
}

0 commit comments

Comments
 (0)