Skip to content

Commit bc3f9bb

Browse files
committed
fix: use Code instead of a raw integer
It is still posible to use your own custom code, which isn't part of the already implemented codecs.
1 parent aa54ac9 commit bc3f9bb

File tree

3 files changed

+119
-55
lines changed

3 files changed

+119
-55
lines changed

src/digests.rs

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
use std::convert::TryFrom;
1010

1111
use bytes::{BufMut, Bytes, BytesMut};
12-
use num_traits::cast::FromPrimitive;
1312
use unsigned_varint::{decode as varint_decode, encode as varint_encode};
1413

1514
use crate::errors::{DecodeError, DecodeOwnedError};
@@ -112,18 +111,18 @@ impl<'a> MultihashRef<'a> {
112111

113112
/// Returns which hashing algorithm is used in this multihash.
114113
pub fn algorithm(&self) -> Code {
115-
let code = varint_decode::u64(&self.bytes)
116-
.expect("multihash is known to be valid algorithm")
117-
.0;
118-
Code::from_u64(code).expect("multihash is known to be valid")
114+
let (code, _bytes) =
115+
varint_decode::u64(&self.bytes).expect("multihash is known to be valid algorithm");
116+
Code::from_u64(code)
119117
}
120118

121119
/// Returns the hashed data.
122120
pub fn digest(&self) -> &'a [u8] {
123-
let bytes = varint_decode::u16(&self.bytes)
124-
.expect("multihash is known to be valid digest")
125-
.1;
126-
&bytes[1..]
121+
let (_code, bytes) =
122+
varint_decode::u64(&self.bytes).expect("multihash is known to be valid digest");
123+
let (_hash_len, bytes) =
124+
varint_decode::u64(&bytes).expect("multihash is known to be a valid digest");
125+
&bytes[..]
127126
}
128127

129128
/// Builds a `Multihash` that owns the data.
@@ -150,7 +149,7 @@ impl<'a> PartialEq<Multihash> for MultihashRef<'a> {
150149
/// The `MultihashDigest` trait specifies an interface common for all multihash functions.
151150
pub trait MultihashDigest {
152151
/// The Mutlihash byte value.
153-
const CODE: u64;
152+
const CODE: Code;
154153

155154
/// Hash some input and return the digest.
156155
///
@@ -168,7 +167,7 @@ pub trait MultihashDigest {
168167
/// object.
169168
pub trait DynMultihashDigest {
170169
/// The Mutlihash byte value.
171-
fn code(&self) -> u64;
170+
fn code(&self) -> Code;
172171

173172
/// Hash some input and return the digest.
174173
///
@@ -179,7 +178,7 @@ pub trait DynMultihashDigest {
179178
}
180179

181180
impl<T: MultihashDigest + ?Sized> DynMultihashDigest for T {
182-
fn code(&self) -> u64 {
181+
fn code(&self) -> Code {
183182
Self::CODE
184183
}
185184
fn digest(&self, data: &[u8]) -> Multihash {
@@ -191,9 +190,9 @@ impl<T: MultihashDigest + ?Sized> DynMultihashDigest for T {
191190
///
192191
/// The size of the hash is determoned by the size of the input hash. If it should be truncated
193192
/// the input data must already be the truncated hash.
194-
pub fn wrap(code: u64, data: &[u8]) -> Multihash {
193+
pub fn wrap(code: &Code, data: &[u8]) -> Multihash {
195194
let mut code_buf = varint_encode::u64_buffer();
196-
let code_varint = varint_encode::u64(code, &mut code_buf);
195+
let code_varint = varint_encode::u64(code.to_u64(), &mut code_buf);
197196

198197
let mut size_buf = varint_encode::u64_buffer();
199198
let size_varint = varint_encode::u64(data.len() as u64, &mut size_buf);

src/hashes.rs

Lines changed: 76 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,22 @@
11
use blake2b_simd::Params as Blake2b;
22
use blake2s_simd::Params as Blake2s;
33
use digest::Digest;
4-
use enum_primitive_derive::Primitive;
54
use sha1::Sha1 as Sha1Hasher;
65
use sha2::{Sha256, Sha512};
76
use tiny_keccak::{Hasher, Keccak, Sha3};
87

98
use crate::digests::{wrap, Multihash, MultihashDigest};
109

11-
#[derive(Clone, Debug, PartialEq, Primitive)]
10+
#[derive(Clone, Debug, PartialEq)]
1211
pub enum Code {
12+
/// Make it possible to use a custom code that is not part of the enum yet
13+
Custom(u64),
14+
/// Hashes that are immplemented in this crate
15+
Implemented(ImplementedCode),
16+
}
17+
18+
#[derive(Clone, Copy, Debug, PartialEq)]
19+
pub enum ImplementedCode {
1320
/// Identity (Raw binary )
1421
Identity = 0x00,
1522
/// SHA-1 (20-byte hash size)
@@ -44,220 +51,255 @@ pub enum Code {
4451
Blake2s256 = 0xb260,
4552
}
4653

54+
impl Code {
55+
/// Return the code as integer value.
56+
pub fn to_u64(&self) -> u64 {
57+
match *self {
58+
Self::Custom(code) => code,
59+
Self::Implemented(code) => code as _,
60+
}
61+
}
62+
63+
/// Return the `Code` based on the integer value. If the code is unknown/not implemented yet
64+
/// then it returns a `Code::Custom`.
65+
/// implementes with that value.
66+
pub fn from_u64(code: u64) -> Self {
67+
match code {
68+
0x00 => Code::Implemented(ImplementedCode::Identity),
69+
0x11 => Code::Implemented(ImplementedCode::Sha1),
70+
0x12 => Code::Implemented(ImplementedCode::Sha2_256),
71+
0x13 => Code::Implemented(ImplementedCode::Sha2_512),
72+
0x14 => Code::Implemented(ImplementedCode::Sha3_512),
73+
0x15 => Code::Implemented(ImplementedCode::Sha3_384),
74+
0x16 => Code::Implemented(ImplementedCode::Sha3_256),
75+
0x17 => Code::Implemented(ImplementedCode::Sha3_224),
76+
0x1A => Code::Implemented(ImplementedCode::Keccak224),
77+
0x1B => Code::Implemented(ImplementedCode::Keccak256),
78+
0x1C => Code::Implemented(ImplementedCode::Keccak384),
79+
0x1D => Code::Implemented(ImplementedCode::Keccak512),
80+
0xB220 => Code::Implemented(ImplementedCode::Blake2b256),
81+
0xB240 => Code::Implemented(ImplementedCode::Blake2b512),
82+
0xB250 => Code::Implemented(ImplementedCode::Blake2s128),
83+
0xB260 => Code::Implemented(ImplementedCode::Blake2s256),
84+
_ => Code::Custom(code),
85+
}
86+
}
87+
}
88+
4789
#[derive(Clone, Debug)]
4890
pub struct Identity;
4991
impl MultihashDigest for Identity {
50-
const CODE: u64 = Code::Identity as _;
92+
const CODE: Code = Code::Implemented(ImplementedCode::Identity);
5193

5294
fn digest(data: &[u8]) -> Multihash {
5395
if (data.len() as u64) >= u64::from(std::u32::MAX) {
5496
panic!("Input data for identity hash is too large, it needs to be less the 2^32.")
5597
}
56-
wrap(Self::CODE, &data)
98+
wrap(&Self::CODE, &data)
5799
}
58100
}
59101

60102
#[derive(Clone, Debug)]
61103
pub struct Sha1;
62104
impl MultihashDigest for Sha1 {
63-
const CODE: u64 = Code::Sha1 as _;
105+
const CODE: Code = Code::Implemented(ImplementedCode::Sha1);
64106

65107
fn digest(data: &[u8]) -> Multihash {
66108
let digest = Sha1Hasher::from(&data).digest().bytes();
67-
wrap(Self::CODE, &digest)
109+
wrap(&Self::CODE, &digest)
68110
}
69111
}
70112

71113
#[derive(Clone, Debug)]
72114
pub struct Sha2_256;
73115
impl MultihashDigest for Sha2_256 {
74-
const CODE: u64 = Code::Sha2_256 as _;
116+
const CODE: Code = Code::Implemented(ImplementedCode::Sha2_256);
75117

76118
fn digest(data: &[u8]) -> Multihash {
77119
let digest = Sha256::digest(&data);
78-
wrap(Self::CODE, &digest)
120+
wrap(&Self::CODE, &digest)
79121
}
80122
}
81123

82124
#[derive(Clone, Debug)]
83125
pub struct Sha2_512;
84126
impl MultihashDigest for Sha2_512 {
85-
const CODE: u64 = Code::Sha2_512 as _;
127+
const CODE: Code = Code::Implemented(ImplementedCode::Sha2_512);
86128

87129
fn digest(data: &[u8]) -> Multihash {
88130
let digest = Sha512::digest(&data);
89-
wrap(Self::CODE, &digest)
131+
wrap(&Self::CODE, &digest)
90132
}
91133
}
92134

93135
#[derive(Clone, Debug)]
94136
pub struct Sha3_224;
95137
impl MultihashDigest for Sha3_224 {
96-
const CODE: u64 = Code::Sha3_224 as _;
138+
const CODE: Code = Code::Implemented(ImplementedCode::Sha3_224);
97139

98140
fn digest(data: &[u8]) -> Multihash {
99141
let mut digest = [0; 28];
100142
let mut sha3 = Sha3::v224();
101143
sha3.update(&data);
102144
sha3.finalize(&mut digest);
103-
wrap(Self::CODE, &digest)
145+
wrap(&Self::CODE, &digest)
104146
}
105147
}
106148

107149
#[derive(Clone, Debug)]
108150
pub struct Sha3_256;
109151
impl MultihashDigest for Sha3_256 {
110-
const CODE: u64 = Code::Sha3_256 as _;
152+
const CODE: Code = Code::Implemented(ImplementedCode::Sha3_256);
111153

112154
fn digest(data: &[u8]) -> Multihash {
113155
let mut digest = [0; 32];
114156
let mut sha3 = Sha3::v256();
115157
sha3.update(&data);
116158
sha3.finalize(&mut digest);
117-
wrap(Self::CODE, &digest)
159+
wrap(&Self::CODE, &digest)
118160
}
119161
}
120162

121163
#[derive(Clone, Debug)]
122164
pub struct Sha3_384;
123165
impl MultihashDigest for Sha3_384 {
124-
const CODE: u64 = Code::Sha3_384 as _;
166+
const CODE: Code = Code::Implemented(ImplementedCode::Sha3_384);
125167

126168
fn digest(data: &[u8]) -> Multihash {
127169
let mut digest = [0; 48];
128170
let mut sha3 = Sha3::v384();
129171
sha3.update(&data);
130172
sha3.finalize(&mut digest);
131-
wrap(Self::CODE, &digest)
173+
wrap(&Self::CODE, &digest)
132174
}
133175
}
134176

135177
#[derive(Clone, Debug)]
136178
pub struct Sha3_512;
137179
impl MultihashDigest for Sha3_512 {
138-
const CODE: u64 = Code::Sha3_512 as _;
180+
const CODE: Code = Code::Implemented(ImplementedCode::Sha3_512);
139181

140182
fn digest(data: &[u8]) -> Multihash {
141183
let mut digest = [0; 64];
142184
let mut sha3 = Sha3::v512();
143185
sha3.update(&data);
144186
sha3.finalize(&mut digest);
145-
wrap(Self::CODE, &digest)
187+
wrap(&Self::CODE, &digest)
146188
}
147189
}
148190

149191
#[derive(Clone, Debug)]
150192
pub struct Keccak224;
151193
impl MultihashDigest for Keccak224 {
152-
const CODE: u64 = Code::Keccak224 as _;
194+
const CODE: Code = Code::Implemented(ImplementedCode::Keccak224);
153195

154196
fn digest(data: &[u8]) -> Multihash {
155197
let mut digest = [0; 28];
156198
let mut keccak = Keccak::v224();
157199
keccak.update(&data);
158200
keccak.finalize(&mut digest);
159-
wrap(Self::CODE, &digest)
201+
wrap(&Self::CODE, &digest)
160202
}
161203
}
162204

163205
#[derive(Clone, Debug)]
164206
pub struct Keccak256;
165207
impl MultihashDigest for Keccak256 {
166-
const CODE: u64 = Code::Keccak256 as _;
208+
const CODE: Code = Code::Implemented(ImplementedCode::Keccak256);
167209

168210
fn digest(data: &[u8]) -> Multihash {
169211
let mut digest = [0; 32];
170212
let mut keccak = Keccak::v256();
171213
keccak.update(&data);
172214
keccak.finalize(&mut digest);
173-
wrap(Self::CODE, &digest)
215+
wrap(&Self::CODE, &digest)
174216
}
175217
}
176218

177219
#[derive(Clone, Debug)]
178220
pub struct Keccak384;
179221
impl MultihashDigest for Keccak384 {
180-
const CODE: u64 = Code::Keccak384 as _;
222+
const CODE: Code = Code::Implemented(ImplementedCode::Keccak384);
181223

182224
fn digest(data: &[u8]) -> Multihash {
183225
let mut digest = [0; 48];
184226
let mut keccak = Keccak::v384();
185227
keccak.update(&data);
186228
keccak.finalize(&mut digest);
187-
wrap(Self::CODE, &digest)
229+
wrap(&Self::CODE, &digest)
188230
}
189231
}
190232

191233
#[derive(Clone, Debug)]
192234
pub struct Keccak512;
193235
impl MultihashDigest for Keccak512 {
194-
const CODE: u64 = Code::Keccak512 as _;
236+
const CODE: Code = Code::Implemented(ImplementedCode::Keccak512);
195237

196238
fn digest(data: &[u8]) -> Multihash {
197239
let mut digest = [0; 64];
198240
let mut keccak = Keccak::v512();
199241
keccak.update(&data);
200242
keccak.finalize(&mut digest);
201-
wrap(Self::CODE, &digest)
243+
wrap(&Self::CODE, &digest)
202244
}
203245
}
204246

205247
#[derive(Clone, Debug)]
206248
pub struct Blake2b256;
207249
impl MultihashDigest for Blake2b256 {
208-
const CODE: u64 = Code::Blake2b256 as _;
250+
const CODE: Code = Code::Implemented(ImplementedCode::Blake2b256);
209251

210252
fn digest(data: &[u8]) -> Multihash {
211253
let digest = Blake2b::new()
212254
.hash_length(32)
213255
.to_state()
214256
.update(&data)
215257
.finalize();
216-
wrap(Self::CODE, &digest.as_bytes())
258+
wrap(&Self::CODE, &digest.as_bytes())
217259
}
218260
}
219261

220262
#[derive(Clone, Debug)]
221263
pub struct Blake2b512;
222264
impl MultihashDigest for Blake2b512 {
223-
const CODE: u64 = Code::Blake2b512 as _;
265+
const CODE: Code = Code::Implemented(ImplementedCode::Blake2b512);
224266

225267
fn digest(data: &[u8]) -> Multihash {
226268
let digest = Blake2b::new()
227269
.hash_length(64)
228270
.to_state()
229271
.update(&data)
230272
.finalize();
231-
wrap(Self::CODE, &digest.as_bytes())
273+
wrap(&Self::CODE, &digest.as_bytes())
232274
}
233275
}
234276

235277
#[derive(Clone, Debug)]
236278
pub struct Blake2s128;
237279
impl MultihashDigest for Blake2s128 {
238-
const CODE: u64 = Code::Blake2s128 as _;
280+
const CODE: Code = Code::Implemented(ImplementedCode::Blake2s128);
239281

240282
fn digest(data: &[u8]) -> Multihash {
241283
let digest = Blake2s::new()
242284
.hash_length(16)
243285
.to_state()
244286
.update(&data)
245287
.finalize();
246-
wrap(Self::CODE, &digest.as_bytes())
288+
wrap(&Self::CODE, &digest.as_bytes())
247289
}
248290
}
249291

250292
#[derive(Clone, Debug)]
251293
pub struct Blake2s256;
252294
impl MultihashDigest for Blake2s256 {
253-
const CODE: u64 = Code::Blake2s256 as _;
295+
const CODE: Code = Code::Implemented(ImplementedCode::Blake2s256);
254296

255297
fn digest(data: &[u8]) -> Multihash {
256298
let digest = Blake2s::new()
257299
.hash_length(32)
258300
.to_state()
259301
.update(&data)
260302
.finalize();
261-
wrap(Self::CODE, &digest.as_bytes())
303+
wrap(&Self::CODE, &digest.as_bytes())
262304
}
263305
}

0 commit comments

Comments
 (0)