ethcore_bigint/
hash.rs

1// Copyright 2015-2017 Parity Technologies
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9//! General hash types, a fixed-size raw-data type used as the output of hash functions.
10
11use std::{ops, fmt, cmp, str};
12use std::cmp::{min, Ordering};
13use std::ops::{Deref, DerefMut, BitXor, BitAnd, BitOr, IndexMut, Index};
14use std::hash::{Hash, Hasher, BuildHasherDefault};
15use std::collections::{HashMap, HashSet};
16use rand::{Rand, Rng};
17use rand::os::OsRng;
18use rustc_hex::{FromHex, FromHexError};
19use plain_hasher::PlainHasher;
20use uint::U256;
21use libc::{c_void, memcmp};
22
23/// Return `s` without the `0x` at the beginning of it, if any.
24pub fn clean_0x(s: &str) -> &str {
25	if s.starts_with("0x") {
26		&s[2..]
27	} else {
28		s
29	}
30}
31
32macro_rules! impl_hash {
33	($from: ident, $size: expr) => {
34		#[repr(C)]
35		/// Unformatted binary data of fixed length.
36		pub struct $from (pub [u8; $size]);
37
38
39		impl From<[u8; $size]> for $from {
40			fn from(bytes: [u8; $size]) -> Self {
41				$from(bytes)
42			}
43		}
44
45		impl From<$from> for [u8; $size] {
46			fn from(s: $from) -> Self {
47				s.0
48			}
49		}
50
51		impl Deref for $from {
52			type Target = [u8];
53
54			#[inline]
55			fn deref(&self) -> &[u8] {
56				&self.0
57			}
58		}
59
60		impl AsRef<[u8]> for $from {
61			#[inline]
62			fn as_ref(&self) -> &[u8] {
63				&self.0
64			}
65		}
66
67		impl DerefMut for $from {
68			#[inline]
69			fn deref_mut(&mut self) -> &mut [u8] {
70				&mut self.0
71			}
72		}
73
74		impl $from {
75			/// Create a new, zero-initialised, instance.
76			pub fn new() -> $from {
77				$from([0; $size])
78			}
79
80			/// Synonym for `new()`. Prefer to new as it's more readable.
81			pub fn zero() -> $from {
82				$from([0; $size])
83			}
84
85			/// Create a new, cryptographically random, instance.
86			pub fn random() -> $from {
87				let mut hash = $from::new();
88				hash.randomize();
89				hash
90			}
91
92			/// Assign self have a cryptographically random value.
93			pub fn randomize(&mut self) {
94				let mut rng = OsRng::new().unwrap();
95				*self= $from::rand(&mut rng);
96			}
97
98			/// Get the size of this object in bytes.
99			pub fn len() -> usize {
100				$size
101			}
102
103			#[inline]
104			/// Assign self to be of the same value as a slice of bytes of length `len()`.
105			pub fn clone_from_slice(&mut self, src: &[u8]) -> usize {
106				let min = cmp::min($size, src.len());
107				self.0[..min].copy_from_slice(&src[..min]);
108				min
109			}
110
111			/// Convert a slice of bytes of length `len()` to an instance of this type.
112			pub fn from_slice(src: &[u8]) -> Self {
113				let mut r = Self::new();
114				r.clone_from_slice(src);
115				r
116			}
117
118			/// Copy the data of this object into some mutable slice of length `len()`.
119			pub fn copy_to(&self, dest: &mut[u8]) {
120				let min = cmp::min($size, dest.len());
121				dest[..min].copy_from_slice(&self.0[..min]);
122			}
123
124			/// Returns `true` if all bits set in `b` are also set in `self`.
125			pub fn contains<'a>(&'a self, b: &'a Self) -> bool {
126				&(b & self) == b
127			}
128
129			/// Returns `true` if no bits are set.
130			pub fn is_zero(&self) -> bool {
131				self.eq(&Self::new())
132			}
133
134			/// Returns the lowest 8 bytes interpreted as a BigEndian integer.
135			pub fn low_u64(&self) -> u64 {
136				let mut ret = 0u64;
137				for i in 0..min($size, 8) {
138					ret |= (self.0[$size - 1 - i] as u64) << (i * 8);
139				}
140				ret
141			}
142		}
143
144		impl str::FromStr for $from {
145			type Err = FromHexError;
146
147			fn from_str(s: &str) -> Result<$from, FromHexError> {
148				let a = s.from_hex()?;
149				if a.len() != $size {
150					return Err(FromHexError::InvalidHexLength);
151				}
152
153				let mut ret = [0;$size];
154				ret.copy_from_slice(&a);
155				Ok($from(ret))
156			}
157		}
158
159		impl fmt::Debug for $from {
160			fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
161				for i in &self.0[..] {
162					write!(f, "{:02x}", i)?;
163				}
164				Ok(())
165			}
166		}
167
168		impl fmt::Display for $from {
169			fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
170				for i in &self.0[0..2] {
171					write!(f, "{:02x}", i)?;
172				}
173				write!(f, "…")?;
174				for i in &self.0[$size - 2..$size] {
175					write!(f, "{:02x}", i)?;
176				}
177				Ok(())
178			}
179		}
180
181		impl Copy for $from {}
182		#[cfg_attr(feature="dev", allow(expl_impl_clone_on_copy))]
183		impl Clone for $from {
184			fn clone(&self) -> $from {
185				let mut ret = $from::new();
186				ret.0.copy_from_slice(&self.0);
187				ret
188			}
189		}
190
191		impl Eq for $from {}
192
193		impl PartialEq for $from {
194			fn eq(&self, other: &Self) -> bool {
195				unsafe { memcmp(self.0.as_ptr() as *const c_void, other.0.as_ptr() as *const c_void, $size) == 0 }
196			}
197		}
198
199		impl Ord for $from {
200			fn cmp(&self, other: &Self) -> Ordering {
201				let r = unsafe { memcmp(self.0.as_ptr() as *const c_void, other.0.as_ptr() as *const c_void, $size) };
202				if r < 0 { return Ordering::Less }
203				if r > 0 { return Ordering::Greater }
204				return Ordering::Equal;
205			}
206		}
207
208		impl PartialOrd for $from {
209			fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
210				Some(self.cmp(other))
211			}
212		}
213
214		impl Hash for $from {
215			fn hash<H>(&self, state: &mut H) where H: Hasher {
216				state.write(&self.0);
217				state.finish();
218			}
219		}
220
221		impl Index<usize> for $from {
222			type Output = u8;
223
224			fn index(&self, index: usize) -> &u8 {
225				&self.0[index]
226			}
227		}
228		impl IndexMut<usize> for $from {
229			fn index_mut(&mut self, index: usize) -> &mut u8 {
230				&mut self.0[index]
231			}
232		}
233		impl Index<ops::Range<usize>> for $from {
234			type Output = [u8];
235
236			fn index(&self, index: ops::Range<usize>) -> &[u8] {
237				&self.0[index]
238			}
239		}
240		impl IndexMut<ops::Range<usize>> for $from {
241			fn index_mut(&mut self, index: ops::Range<usize>) -> &mut [u8] {
242				&mut self.0[index]
243			}
244		}
245		impl Index<ops::RangeFull> for $from {
246			type Output = [u8];
247
248			fn index(&self, _index: ops::RangeFull) -> &[u8] {
249				&self.0
250			}
251		}
252		impl IndexMut<ops::RangeFull> for $from {
253			fn index_mut(&mut self, _index: ops::RangeFull) -> &mut [u8] {
254				&mut self.0
255			}
256		}
257
258		/// `BitOr` on references
259		impl<'a> BitOr for &'a $from {
260			type Output = $from;
261
262			fn bitor(self, rhs: Self) -> Self::Output {
263				let mut ret: $from = $from::default();
264				for i in 0..$size {
265					ret.0[i] = self.0[i] | rhs.0[i];
266				}
267				ret
268			}
269		}
270
271		/// Moving `BitOr`
272		impl BitOr for $from {
273			type Output = $from;
274
275			fn bitor(self, rhs: Self) -> Self::Output {
276				&self | &rhs
277			}
278		}
279
280		/// `BitAnd` on references
281		impl <'a> BitAnd for &'a $from {
282			type Output = $from;
283
284			fn bitand(self, rhs: Self) -> Self::Output {
285				let mut ret: $from = $from::default();
286				for i in 0..$size {
287					ret.0[i] = self.0[i] & rhs.0[i];
288				}
289				ret
290			}
291		}
292
293		/// Moving `BitAnd`
294		impl BitAnd for $from {
295			type Output = $from;
296
297			fn bitand(self, rhs: Self) -> Self::Output {
298				&self & &rhs
299			}
300		}
301
302		/// `BitXor` on references
303		impl <'a> BitXor for &'a $from {
304			type Output = $from;
305
306			fn bitxor(self, rhs: Self) -> Self::Output {
307				let mut ret: $from = $from::default();
308				for i in 0..$size {
309					ret.0[i] = self.0[i] ^ rhs.0[i];
310				}
311				ret
312			}
313		}
314
315		/// Moving `BitXor`
316		impl BitXor for $from {
317			type Output = $from;
318
319			fn bitxor(self, rhs: Self) -> Self::Output {
320				&self ^ &rhs
321			}
322		}
323
324		impl $from {
325			/// Get a hex representation.
326			pub fn hex(&self) -> String {
327				format!("{:?}", self)
328			}
329		}
330
331		impl Default for $from {
332			fn default() -> Self { $from::new() }
333		}
334
335		impl From<u64> for $from {
336			fn from(mut value: u64) -> $from {
337				let mut ret = $from::new();
338				for i in 0..8 {
339					if i < $size {
340						ret.0[$size - i - 1] = (value & 0xff) as u8;
341						value >>= 8;
342					}
343				}
344				ret
345			}
346		}
347
348		impl From<&'static str> for $from {
349			fn from(s: &'static str) -> $from {
350				let s = clean_0x(s);
351				if s.len() % 2 == 1 {
352					("0".to_owned() + s).parse().unwrap()
353				} else {
354					s.parse().unwrap()
355				}
356			}
357		}
358
359		impl<'a> From<&'a [u8]> for $from {
360			fn from(s: &'a [u8]) -> $from {
361				$from::from_slice(s)
362			}
363		}
364
365		impl Rand for $from {
366			fn rand<R: Rng>(r: &mut R) -> Self {
367				let mut hash = $from::new();
368				r.fill_bytes(&mut hash.0);
369				hash
370			}
371		}
372	}
373}
374
375impl From<U256> for H256 {
376	fn from(value: U256) -> H256 {
377		let mut ret = H256::new();
378		value.to_big_endian(&mut ret);
379		ret
380	}
381}
382
383impl<'a> From<&'a U256> for H256 {
384	fn from(value: &'a U256) -> H256 {
385		let mut ret: H256 = H256::new();
386		value.to_big_endian(&mut ret);
387		ret
388	}
389}
390
391impl From<H256> for U256 {
392	fn from(value: H256) -> U256 {
393		U256::from(&value)
394	}
395}
396
397impl<'a> From<&'a H256> for U256 {
398	fn from(value: &'a H256) -> U256 {
399		U256::from(value.as_ref() as &[u8])
400	}
401}
402
403impl From<H256> for H160 {
404	fn from(value: H256) -> H160 {
405		let mut ret = H160::new();
406		ret.0.copy_from_slice(&value[12..32]);
407		ret
408	}
409}
410
411impl From<H256> for H64 {
412	fn from(value: H256) -> H64 {
413		let mut ret = H64::new();
414		ret.0.copy_from_slice(&value[20..28]);
415		ret
416	}
417}
418
419impl From<H160> for H256 {
420	fn from(value: H160) -> H256 {
421		let mut ret = H256::new();
422		ret.0[12..32].copy_from_slice(&value);
423		ret
424	}
425}
426
427impl<'a> From<&'a H160> for H256 {
428	fn from(value: &'a H160) -> H256 {
429		let mut ret = H256::new();
430		ret.0[12..32].copy_from_slice(value);
431		ret
432	}
433}
434
435impl_hash!(H32, 4);
436impl_hash!(H64, 8);
437impl_hash!(H128, 16);
438impl_hash!(H160, 20);
439impl_hash!(H256, 32);
440impl_hash!(H264, 33);
441impl_hash!(H512, 64);
442impl_hash!(H520, 65);
443impl_hash!(H1024, 128);
444impl_hash!(H2048, 256);
445
446#[cfg(feature="heapsizeof")]
447known_heap_size!(0, H32, H64, H128, H160, H256, H264, H512, H520, H1024, H2048);
448// Specialized HashMap and HashSet
449
450/// Specialized version of `HashMap` with H256 keys and fast hashing function.
451pub type H256FastMap<T> = HashMap<H256, T, BuildHasherDefault<PlainHasher>>;
452/// Specialized version of `HashSet` with H256 keys and fast hashing function.
453pub type H256FastSet = HashSet<H256, BuildHasherDefault<PlainHasher>>;
454
455#[cfg(test)]
456mod tests {
457	use hash::*;
458	use std::str::FromStr;
459
460	#[test]
461	fn hasher_alignment() {
462		use std::mem::align_of;
463		assert_eq!(align_of::<u64>(), align_of::<PlainHasher>());
464	}
465
466	#[test]
467	#[cfg_attr(feature="dev", allow(eq_op))]
468	fn hash() {
469		let h = H64([0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]);
470		assert_eq!(H64::from_str("0123456789abcdef").unwrap(), h);
471		assert_eq!(format!("{}", h), "0123…cdef");
472		assert_eq!(format!("{:?}", h), "0123456789abcdef");
473		assert_eq!(h.hex(), "0123456789abcdef");
474		assert!(h == h);
475		assert!(h != H64([0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xee]));
476		assert!(h != H64([0; 8]));
477	}
478
479	#[test]
480	fn hash_bitor() {
481		let a = H64([1; 8]);
482		let b = H64([2; 8]);
483		let c = H64([3; 8]);
484
485		// borrow
486		assert_eq!(&a | &b, c);
487
488		// move
489		assert_eq!(a | b, c);
490	}
491
492	#[test]
493	fn from_and_to_address() {
494		let address: H160 = "ef2d6d194084c2de36e0dabfce45d046b37d1106".into();
495		let h = H256::from(address.clone());
496		let a = H160::from(h);
497		assert_eq!(address, a);
498	}
499
500	#[test]
501	fn from_u64() {
502		assert_eq!(H128::from(0x1234567890abcdef), H128::from_str("00000000000000001234567890abcdef").unwrap());
503		assert_eq!(H64::from(0x1234567890abcdef), H64::from_str("1234567890abcdef").unwrap());
504		assert_eq!(H32::from(0x1234567890abcdef), H32::from_str("90abcdef").unwrap());
505	}
506
507	#[test]
508	fn from_str() {
509		assert_eq!(H64::from(0x1234567890abcdef), H64::from("0x1234567890abcdef"));
510		assert_eq!(H64::from(0x1234567890abcdef), H64::from("1234567890abcdef"));
511		assert_eq!(H64::from(0x234567890abcdef), H64::from("0x234567890abcdef"));
512	}
513
514	#[test]
515	fn from_and_to_u256() {
516		let u: U256 = 0x123456789abcdef0u64.into();
517		let h = H256::from(u);
518		assert_eq!(H256::from(u), H256::from("000000000000000000000000000000000000000000000000123456789abcdef0"));
519		let h_ref = H256::from(&u);
520		assert_eq!(h, h_ref);
521		let r_ref: U256 = From::from(&h);
522		assert_eq!(r_ref, u);
523		let r: U256 = From::from(h);
524		assert_eq!(r, u);
525	}
526}