cryptohash/
blake2b.rs

1use std::mem;
2use std::fmt;
3
4use blake2_rfc::blake2b;
5
6use {CryptoHash, State};
7
8/// Wraps Blake2b in the `CryptoHash` trait
9#[derive(Clone, Debug)]
10pub struct Blake2b {}
11
12impl CryptoHash for Blake2b {
13    type State = blake2b::Blake2b;
14    type Digest = BlakeDigestWrap;
15    const NULL: Self::Digest = BlakeDigestWrap([
16        0,
17        0,
18        0,
19        0,
20        0,
21        0,
22        0,
23        0,
24        0,
25        0,
26        0,
27        0,
28        0,
29        0,
30        0,
31        0,
32        0,
33        0,
34        0,
35        0,
36        0,
37        0,
38        0,
39        0,
40        0,
41        0,
42        0,
43        0,
44        0,
45        0,
46        0,
47        0,
48    ]);
49
50    fn state() -> Self::State {
51        blake2b::Blake2b::new(32)
52    }
53}
54
55#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)]
56pub struct BlakeDigestWrap([u8; 32]);
57
58impl State<BlakeDigestWrap> for blake2b::Blake2b {
59    fn fin(self) -> BlakeDigestWrap {
60        let mut bytes: [u8; 32];
61
62        let fin = self.finalize();
63        let resultbytes = fin.as_bytes();
64
65        // this is safe since we always fill the buffer completely.
66        unsafe { bytes = mem::uninitialized() }
67        for i in 0..bytes.len() {
68            bytes[i] = resultbytes[i]
69        }
70        BlakeDigestWrap(bytes)
71    }
72}
73
74impl AsRef<[u8]> for BlakeDigestWrap {
75    fn as_ref<'a>(&'a self) -> &'a [u8] {
76        &self.0
77    }
78}
79
80impl AsMut<[u8]> for BlakeDigestWrap {
81    fn as_mut<'a>(&'a mut self) -> &'a mut [u8] {
82        &mut self.0
83    }
84}
85
86impl fmt::Display for BlakeDigestWrap {
87    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
88        for i in self.as_ref() {
89            write!(f, "{:02x}", i)?;
90        }
91        Ok(())
92    }
93}
94
95impl fmt::Debug for BlakeDigestWrap {
96    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
97        for i in self.as_ref().iter().take(3) {
98            write!(f, "{:02x}", i)?;
99        }
100        Ok(())
101    }
102}