Add a `Sha256dChecksum` type for truncated double SHA256.

This commit is contained in:
Henry de Valence 2019-09-12 03:46:39 -07:00 committed by Deirdre Connolly
parent b9af047a09
commit 42cb9c1ff9
2 changed files with 30 additions and 0 deletions

View File

@ -7,3 +7,4 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
sha2 = "0.8"

View File

@ -1,5 +1,20 @@
//! Newtype wrappers for primitive data types with semantic meaning. //! Newtype wrappers for primitive data types with semantic meaning.
/// A 4-byte checksum using truncated double SHA256.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub struct Sha256dChecksum(pub [u8; 4]);
impl<'a> From<&'a [u8]> for Sha256dChecksum {
fn from(bytes: &'a [u8]) -> Self {
use sha2::{Sha256, Digest};
let hash1 = Sha256::digest(bytes);
let hash2 = Sha256::digest(&hash1);
let mut checksum = [0u8; 4];
checksum[0..4].copy_from_slice(&hash2[0..4]);
Self(checksum)
}
}
/// A u32 which represents a block height value. /// A u32 which represents a block height value.
pub struct BlockHeight(pub u32); pub struct BlockHeight(pub u32);
@ -34,3 +49,17 @@ pub enum InventoryType {
/// Inventory Vector /// Inventory Vector
pub struct InventoryVector(pub InventoryType, pub [u8; 32]); pub struct InventoryVector(pub InventoryType, pub [u8; 32]);
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn sha256d_checksum() {
// https://en.bitcoin.it/wiki/Protocol_documentation#Hashes
let input = b"hello";
let checksum = Sha256dChecksum::from(&input[..]);
let expected = Sha256dChecksum([0x95, 0x95, 0xc9, 0xdf]);
assert_eq!(checksum, expected);
}
}