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