From ce2abe697bf10c47f2ad2d9c467e2a7c5801607a Mon Sep 17 00:00:00 2001 From: Victor <56770457+victor-wei126@users.noreply.github.com> Date: Sat, 22 Jan 2022 15:35:50 -0600 Subject: [PATCH] modify tests to conform to content keys test vectors spec (#229) --- Cargo.lock | 7 + trin-core/Cargo.toml | 1 + trin-core/src/portalnet/types/content_keys.rs | 333 +++++++----------- trin-core/src/utils/content_key.rs | 41 ++- 4 files changed, 156 insertions(+), 226 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6e20725cd..b9e6767a2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1213,6 +1213,12 @@ dependencies = [ "sha1", ] +[[package]] +name = "hmac-sha256" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bf358bbbbf03cbe18c2bc53c34b9f1dc212d2ce5cc56bf95ce34cec4359613b" + [[package]] name = "http" version = "0.2.6" @@ -3298,6 +3304,7 @@ dependencies = [ "eth2_ssz_types", "futures 0.3.19", "hex", + "hmac-sha256", "httparse", "interfaces", "ipconfig", diff --git a/trin-core/Cargo.toml b/trin-core/Cargo.toml index 40f380cc2..e27a5954c 100644 --- a/trin-core/Cargo.toml +++ b/trin-core/Cargo.toml @@ -29,6 +29,7 @@ serde_json = "1.0.59" stunclient = "0.1.2" structopt = "0.3" sha3 = "0.9.1" +hmac-sha256 = "1.1.1" thiserror = "1.0.29" threadpool = "1.8.1" tokio = {version = "1.8.0", features = ["full"]} diff --git a/trin-core/src/portalnet/types/content_keys.rs b/trin-core/src/portalnet/types/content_keys.rs index 287d0e0e1..f37a550b0 100644 --- a/trin-core/src/portalnet/types/content_keys.rs +++ b/trin-core/src/portalnet/types/content_keys.rs @@ -164,7 +164,7 @@ impl StateContentKey { let mut input = vec![]; input.append(&mut path.to_vec()); input.append(&mut node_hash.to_vec()); - Ok(keccak(&hex::encode(input))?) + Ok(sha256(&input)) } StateContentKey::ContractStorageTrieNodeKey(ContractStorageTrieNode { address, @@ -176,18 +176,20 @@ impl StateContentKey { input.append(&mut address.to_vec()); input.append(&mut path.to_vec()); input.append(&mut node_hash.to_vec()); - Ok(keccak(&hex::encode(input))?) + Ok(sha256(&input)) } StateContentKey::AccountTrieProofKey(AccountTrieProof { address, .. }) => { - Ok(keccak(&hex::encode(address.to_vec()))?) + Ok(keccak256(address)) } StateContentKey::ContractStorageTrieProofKey(ContractStorageTrieProof { address, slot, .. }) => { - let address_hash = keccak(&hex::encode(address.to_vec()))?; - let slot_hash = keccak(&slot.to_string())?; + let address_hash = keccak256(address); + let mut slot_as_be_bytes: [u8; 32] = [0; 32]; + slot.to_big_endian(&mut slot_as_be_bytes); + let slot_hash = keccak256(&slot_as_be_bytes); let final_hash = U512::from(address_hash) + U512::from(slot_hash); let modulus: U512 = U512::from(2).pow(U512::from(256)); @@ -198,7 +200,7 @@ impl StateContentKey { let mut input = vec![]; input.append(&mut address.to_vec()); input.append(&mut code_hash.to_vec()); - Ok(keccak(&hex::encode(input))?) + Ok(sha256(&input)) } } } @@ -216,9 +218,9 @@ impl HistoryContentKey { /// Returns the content-type of a HistoryContentKey pub fn content_type(&self) -> u8 { match self { - HistoryContentKey::HeaderKey(_) => 0x01, - HistoryContentKey::BodyKey(_) => 0x02, - HistoryContentKey::ReceiptsKey(_) => 0x03, + HistoryContentKey::HeaderKey(_) => 0x00, + HistoryContentKey::BodyKey(_) => 0x01, + HistoryContentKey::ReceiptsKey(_) => 0x02, } } @@ -226,15 +228,15 @@ impl HistoryContentKey { pub fn from_bytes(bytes: &[u8]) -> Result { if let Some(content_type) = bytes.first() { match content_type { - 0x01 => Ok(HistoryContentKey::HeaderKey( + 0x00 => Ok(HistoryContentKey::HeaderKey( HeaderKey::from_ssz_bytes(&bytes[1..]) .map_err(|e| ContentKeyError::ssz(e, String::from("HeaderKey")))?, )), - 0x02 => Ok(HistoryContentKey::BodyKey( + 0x01 => Ok(HistoryContentKey::BodyKey( BodyKey::from_ssz_bytes(&bytes[1..]) .map_err(|e| ContentKeyError::ssz(e, String::from("BodyKey")))?, )), - 0x03 => Ok(HistoryContentKey::ReceiptsKey( + 0x02 => Ok(HistoryContentKey::ReceiptsKey( ReceiptsKey::from_ssz_bytes(&bytes[1..]) .map_err(|e| ContentKeyError::ssz(e, String::from("ReceiptsKey")))?, )), @@ -249,23 +251,27 @@ impl HistoryContentKey { /// Derives the proper content-id for a given HistoryContentKey pub fn derive_content_id(&self) -> Result { - let (chain_id, block_hash) = match self { + let (content_type, chain_id, block_hash) = match self { HistoryContentKey::HeaderKey(HeaderKey { chain_id, block_hash, - }) => (chain_id, block_hash), + }) => (0u8, chain_id, block_hash), HistoryContentKey::BodyKey(BodyKey { chain_id, block_hash, - }) => (chain_id, block_hash), + }) => (1u8, chain_id, block_hash), HistoryContentKey::ReceiptsKey(ReceiptsKey { chain_id, block_hash, - }) => (chain_id, block_hash), + }) => (2u8, chain_id, block_hash), }; - let input = U256::from(chain_id.to_owned()).to_string() + &hex::encode(block_hash); - Ok(keccak(&input)?) + let mut input = vec![]; + // NOTE: uses LE + input.extend_from_slice(&content_type.to_le_bytes()); + input.extend_from_slice(&chain_id.to_le_bytes()); + input.extend_from_slice(block_hash); + Ok(sha256(&input)) } } @@ -332,9 +338,8 @@ mod test { const RANDOM_HASH_3: &str = "3e190b68719aecbcb28ed2271014dd25f2aa633184988eb414189ce0899cade5"; const RANDOM_ADDRESS: &str = "829bd824b016326a401d083b33d092293333a830"; - // Tests for the decoding of StateContentKeys #[test] - fn test_account_trie_node_key_decode() { + fn test_vector_account_trie_node() { let node_hash = vec_to_array(hex::decode(RANDOM_HASH).unwrap()).unwrap(); let state_root = vec_to_array(hex::decode(RANDOM_HASH_2).unwrap()).unwrap(); @@ -346,9 +351,11 @@ mod test { let test_key = ContentKey::StateContentKey(StateContentKey::AccountTrieNodeKey(container.clone())); + let expected = "0044000000b8be7903aee73b8f6a59cd44a1f52c62148e1f376c0dfa1f5f773a98666efc2bd1c390624d3bd4e409a61a858e5dcc5517729a9170d014a6c96530d64dd8621d01020001"; let ssz_bytes = test_key.to_bytes(); - let decoded = StateContentKey::from_bytes(&ssz_bytes).unwrap(); + assert_eq!(hex::encode(test_key.to_bytes()), expected); + let decoded = StateContentKey::from_bytes(&ssz_bytes).unwrap(); if let StateContentKey::AccountTrieNodeKey(k) = decoded { assert_eq!(container, k); assert_eq!(container.path, k.path); @@ -357,10 +364,17 @@ mod test { } else { panic!("Assertions not tested. Check if proper decoding occurred") } + + // TESTING CONTENT-ID DERIVATION + let actual_id = test_key.to_content_id().unwrap().to_string(); + let expected_id = + "41237096982860596884042712109427867048220765019203857308279863638242761605893" + .to_string(); + assert_eq!(expected_id, actual_id); } #[test] - fn test_contract_storage_trie_node_key_decode() { + fn test_vector_contract_storage_trie_node() { let address = hex::decode(RANDOM_ADDRESS).unwrap(); let node_hash = vec_to_array(hex::decode(RANDOM_HASH_3).unwrap()).unwrap(); let state_root = vec_to_array(hex::decode(RANDOM_HASH_2).unwrap()).unwrap(); @@ -374,9 +388,12 @@ mod test { let test_key = ContentKey::StateContentKey(StateContentKey::ContractStorageTrieNodeKey( container.clone(), )); + + let expected = "01829bd824b016326a401d083b33d092293333a830580000003e190b68719aecbcb28ed2271014dd25f2aa633184988eb414189ce0899cade5d1c390624d3bd4e409a61a858e5dcc5517729a9170d014a6c96530d64dd8621d01000f0e0c00"; let ssz_bytes = test_key.to_bytes(); - let decoded = StateContentKey::from_bytes(&ssz_bytes).unwrap(); + assert_eq!(hex::encode(test_key.to_bytes()), expected); + let decoded = StateContentKey::from_bytes(&ssz_bytes).unwrap(); if let StateContentKey::ContractStorageTrieNodeKey(k) = decoded { assert_eq!(container, k); assert_eq!(container.address, k.address); @@ -386,10 +403,17 @@ mod test { } else { panic!("Assertions not tested. Check if proper decoding occurred") } + + // TESTING CONTENT-ID DERIVATION + let actual_id = test_key.to_content_id().unwrap().to_string(); + let expected_id = + "43529358882110548041037387588279806363134301284609868141745095118932570363585" + .to_string(); + assert_eq!(expected_id, actual_id); } #[test] - fn test_account_trie_proof_key_decode() { + fn test_vector_account_trie_proof() { let address = hex::decode(RANDOM_ADDRESS).unwrap(); let state_root = vec_to_array(hex::decode(RANDOM_HASH_2).unwrap()).unwrap(); let container = AccountTrieProof { @@ -398,9 +422,12 @@ mod test { }; let test_key = ContentKey::StateContentKey(StateContentKey::AccountTrieProofKey(container.clone())); + + let expected = "02829bd824b016326a401d083b33d092293333a830d1c390624d3bd4e409a61a858e5dcc5517729a9170d014a6c96530d64dd8621d"; let ssz_bytes = test_key.to_bytes(); - let decoded = StateContentKey::from_bytes(&ssz_bytes).unwrap(); + assert_eq!(hex::encode(test_key.to_bytes()), expected); + let decoded = StateContentKey::from_bytes(&ssz_bytes).unwrap(); if let StateContentKey::AccountTrieProofKey(k) = decoded { assert_eq!(container, k); assert_eq!(container.address, k.address); @@ -408,10 +435,17 @@ mod test { } else { panic!("Assertions not tested. Check if proper decoding occurred") } + + // TESTING CONTENT-ID DERIVATION + let actual_id = test_key.to_content_id().unwrap().to_string(); + let expected_id = + "45301550050471302973396879294932122279426162994178563319590607565171451545101" + .to_string(); + assert_eq!(expected_id, actual_id); } #[test] - fn test_contract_storage_trie_proof_key_decode() { + fn test_vector_contract_storage_trie_proof() { let address = hex::decode(RANDOM_ADDRESS).unwrap(); let state_root = vec_to_array(hex::decode(RANDOM_HASH_2).unwrap()).unwrap(); @@ -424,9 +458,12 @@ mod test { let test_key = ContentKey::StateContentKey(StateContentKey::ContractStorageTrieProofKey( container.clone(), )); + + let expected = "03829bd824b016326a401d083b33d092293333a830c8a6030000000000000000000000000000000000000000000000000000000000d1c390624d3bd4e409a61a858e5dcc5517729a9170d014a6c96530d64dd8621d"; let ssz_bytes = test_key.to_bytes(); - let decoded = StateContentKey::from_bytes(&ssz_bytes).unwrap(); + assert_eq!(hex::encode(test_key.to_bytes()), expected); + let decoded = StateContentKey::from_bytes(&ssz_bytes).unwrap(); if let StateContentKey::ContractStorageTrieProofKey(k) = decoded { assert_eq!(container, k); assert_eq!(container.address, k.address); @@ -435,10 +472,17 @@ mod test { } else { panic!("Assertions not tested. Check if proper decoding occurred") } + + // TESTING CONTENT-ID DERIVATION + let actual_id = test_key.to_content_id().unwrap().to_string(); + let expected_id = + "80413803151602881485894828440259195604313253842905231566803078625935967002376" + .to_string(); + assert_eq!(expected_id, actual_id); } #[test] - fn test_contract_bytecode_key_decode() { + fn test_vector_contract_bytecode() { let address = hex::decode(RANDOM_ADDRESS).unwrap(); let code_hash = vec_to_array(hex::decode(RANDOM_HASH_2).unwrap()).unwrap(); let container = ContractBytecode { @@ -447,9 +491,12 @@ mod test { }; let test_key = ContentKey::StateContentKey(StateContentKey::ContractBytecodeKey(container.clone())); + + let expected = "04829bd824b016326a401d083b33d092293333a830d1c390624d3bd4e409a61a858e5dcc5517729a9170d014a6c96530d64dd8621d"; let ssz_bytes = test_key.to_bytes(); - let decoded = StateContentKey::from_bytes(&ssz_bytes).unwrap(); + assert_eq!(hex::encode(test_key.to_bytes()), expected); + let decoded = StateContentKey::from_bytes(&ssz_bytes).unwrap(); if let StateContentKey::ContractBytecodeKey(k) = decoded { assert_eq!(container, k); assert_eq!(container.address, k.address); @@ -457,11 +504,18 @@ mod test { } else { panic!("Assertions not tested. Check if proper decoding occurred") } + + // TESTING CONTENT-ID DERIVATION + let actual_id = test_key.to_content_id().unwrap().to_string(); + let expected_id = + "9243655320250466575533858917172702581481192615849913473767356296630272634800" + .to_string(); + assert_eq!(expected_id, actual_id); } - // Tests for the decoding of HistoryContentKeys + // Tests for HistoryContentKeys #[test] - fn test_header_key_decode() { + fn test_vector_header_key() { let chain_id = 15; let block_hash = vec_to_array(hex::decode(RANDOM_HASH_2).unwrap()).unwrap(); let container = HeaderKey { @@ -470,9 +524,12 @@ mod test { }; let test_key = ContentKey::HistoryContentKey(HistoryContentKey::HeaderKey(container.clone())); + + let expected = "000f00d1c390624d3bd4e409a61a858e5dcc5517729a9170d014a6c96530d64dd8621d"; let ssz_bytes = test_key.to_bytes(); - let decoded = HistoryContentKey::from_bytes(&ssz_bytes).unwrap(); + assert_eq!(hex::encode(test_key.to_bytes()), expected); + let decoded = HistoryContentKey::from_bytes(&ssz_bytes).unwrap(); if let HistoryContentKey::HeaderKey(k) = decoded { assert_eq!(container, k); assert_eq!(container.chain_id, k.chain_id); @@ -480,10 +537,17 @@ mod test { } else { panic!("Assertions not tested. Check if proper decoding occurred") } + + // TESTING CONTENT-ID DERIVATION + let actual_id = test_key.to_content_id().unwrap().to_string(); + let expected_id = + "15025167517633317571792618561170587584740338038067807801482118109695980329625" + .to_string(); + assert_eq!(actual_id, expected_id); } #[test] - fn test_body_key_decode() { + fn test_vector_body_key() { let chain_id = 20; let block_hash = vec_to_array(hex::decode(RANDOM_HASH_2).unwrap()).unwrap(); let container = BodyKey { @@ -491,9 +555,12 @@ mod test { block_hash, }; let test_key = ContentKey::HistoryContentKey(HistoryContentKey::BodyKey(container.clone())); + + let expected = "011400d1c390624d3bd4e409a61a858e5dcc5517729a9170d014a6c96530d64dd8621d"; let ssz_bytes = test_key.to_bytes(); - let decoded = HistoryContentKey::from_bytes(&ssz_bytes).unwrap(); + assert_eq!(hex::encode(test_key.to_bytes()), expected); + let decoded = HistoryContentKey::from_bytes(&ssz_bytes).unwrap(); if let HistoryContentKey::BodyKey(k) = decoded { assert_eq!(container, k); assert_eq!(container.chain_id, k.chain_id); @@ -501,10 +568,17 @@ mod test { } else { panic!("Assertions not tested. Check if proper decoding occurred") } + + // TESTING CONTENT-ID DERIVATION + let actual_id = test_key.to_content_id().unwrap().to_string(); + let expected_id = + "12834862124958403129911294156243112356210437741210740000860318140844473844426" + .to_string(); + assert_eq!(actual_id, expected_id); } #[test] - fn test_receipts_key_decode() { + fn test_vector_receipts_key() { let chain_id = 4; let block_hash = vec_to_array(hex::decode(RANDOM_HASH_2).unwrap()).unwrap(); let container = ReceiptsKey { @@ -513,9 +587,12 @@ mod test { }; let test_key = ContentKey::HistoryContentKey(HistoryContentKey::ReceiptsKey(container.clone())); + + let expected = "020400d1c390624d3bd4e409a61a858e5dcc5517729a9170d014a6c96530d64dd8621d"; let ssz_bytes = test_key.to_bytes(); - let decoded = HistoryContentKey::from_bytes(&ssz_bytes).unwrap(); + assert_eq!(hex::encode(test_key.to_bytes()), expected); + let decoded = HistoryContentKey::from_bytes(&ssz_bytes).unwrap(); if let HistoryContentKey::ReceiptsKey(k) = decoded { assert_eq!(container, k); assert_eq!(container.chain_id, k.chain_id); @@ -523,6 +600,13 @@ mod test { } else { panic!("Assertions not tested. Check if proper decoding occurred") } + + // TESTING CONTENT-ID DERIVATION + let actual_id = test_key.to_content_id().unwrap().to_string(); + let expected_id = + "76995449220721979583200368506411933662679656077191192504502358532083948020658" + .to_string(); + assert_eq!(actual_id, expected_id); } // Tests of possible FAILURES during decoding of StateContentKeys. @@ -570,181 +654,4 @@ mod test { let ssz_bytes = vec![1, 5, 4, 3, 10]; HistoryContentKey::from_bytes(&ssz_bytes).unwrap(); } - - // Test derivations of content-ids from StateContentKeys - #[test] - fn test_account_trie_node_key_derive() { - // the test input - let node_hash = vec_to_array(hex::decode(RANDOM_HASH).unwrap()).unwrap(); - let state_root = vec_to_array(hex::decode(RANDOM_HASH_2).unwrap()).unwrap(); - let container = AccountTrieNode { - path: VariableList::from(vec![1, 2, 0, 1]), - node_hash, - state_root, - }; - - // create test-key and encode - let test_key = - ContentKey::StateContentKey(StateContentKey::AccountTrieNodeKey(container.clone())); - - // derive the content_id from encoded key - let result = test_key.to_content_id().unwrap(); - - // create hash - let mut vecs = vec![]; - vecs.append(&mut container.path.to_vec()); - vecs.append(&mut node_hash.to_vec()); - let actual = keccak(&hex::encode(vecs)).unwrap(); - - assert_eq!(actual, result); - } - - #[test] - fn test_contract_storage_trie_node_key_derive() { - let address = hex::decode(RANDOM_ADDRESS).unwrap(); - let node_hash = vec_to_array(hex::decode(RANDOM_HASH_3).unwrap()).unwrap(); - let state_root = vec_to_array(hex::decode(RANDOM_HASH_2).unwrap()).unwrap(); - let container = ContractStorageTrieNode { - address: FixedVector::from(address), - path: VariableList::from(vec![1, 0, 15, 14, 12, 0]), - node_hash, - state_root, - }; - - let test_key = ContentKey::StateContentKey(StateContentKey::ContractStorageTrieNodeKey( - container.clone(), - )); - let result = test_key.to_content_id().unwrap(); - - // create hash - let mut vecs = vec![]; - vecs.append(&mut container.address.to_vec()); - vecs.append(&mut container.path.to_vec()); - vecs.append(&mut node_hash.to_vec()); - let actual = keccak(&hex::encode(vecs)).unwrap(); - - assert_eq!(actual, result); - } - - #[test] - fn test_account_trie_proof_key_derive() { - let address = hex::decode(RANDOM_ADDRESS).unwrap(); - let state_root = vec_to_array(hex::decode(RANDOM_HASH_2).unwrap()).unwrap(); - let container = AccountTrieProof { - address: FixedVector::from(address), - state_root, - }; - let test_key = - ContentKey::StateContentKey(StateContentKey::AccountTrieProofKey(container.clone())); - let result = test_key.to_content_id().unwrap(); - - // create hash - let input = hex::encode(container.address.to_vec()); - let actual = keccak(&input).unwrap(); - - assert_eq!(actual, result); - } - - #[test] - fn test_contract_storage_trie_proof_key_derive() { - let address = hex::decode(RANDOM_ADDRESS).unwrap(); - let state_root = vec_to_array(hex::decode(RANDOM_HASH_2).unwrap()).unwrap(); - let container = ContractStorageTrieProof { - address: FixedVector::from(address), - slot: U256::from(239304), - state_root, - }; - - let test_key = ContentKey::StateContentKey(StateContentKey::ContractStorageTrieProofKey( - container.clone(), - )); - let result = test_key.to_content_id().unwrap(); - - // create hash - let address_hash = keccak(&hex::encode(container.address.to_vec())).unwrap(); - let slot_hash = keccak(&container.slot.to_string()).unwrap(); - let actual: U256 = ((U512::from(address_hash) + U512::from(slot_hash)) - % U512::from(2).pow(U512::from(256))) - .try_into() - .unwrap(); - - assert_eq!(actual, result); - } - - #[test] - fn test_contract_bytecode_key_derive() { - let address = hex::decode(RANDOM_ADDRESS).unwrap(); - let code_hash = vec_to_array(hex::decode(RANDOM_HASH_2).unwrap()).unwrap(); - let container = ContractBytecode { - address: FixedVector::from(address), - code_hash, - }; - let test_key = - ContentKey::StateContentKey(StateContentKey::ContractBytecodeKey(container.clone())); - let result = test_key.to_content_id().unwrap(); - - // create hash - let mut input = hex::encode(container.address.to_vec()); - input.push_str(&hex::encode(container.code_hash)); - let actual = keccak(&input).unwrap(); - - assert_eq!(actual, result); - } - - // Test derivations of content-ids from HistoryContentKeys - #[test] - fn test_header_key_derive() { - let chain_id = 20; - let block_hash = vec_to_array(hex::decode(RANDOM_HASH_2).unwrap()).unwrap(); - let container = BodyKey { - chain_id, - block_hash, - }; - let test_key = ContentKey::HistoryContentKey(HistoryContentKey::BodyKey(container.clone())); - let result = test_key.to_content_id().unwrap(); - - // create hash - let input = U256::from(chain_id).to_string() + &hex::encode(block_hash); - let actual = keccak(&input).unwrap(); - - assert_eq!(actual, result); - } - - #[test] - fn test_body_key_derive() { - let chain_id = 4; - let block_hash = vec_to_array(hex::decode(RANDOM_HASH_2).unwrap()).unwrap(); - let container = ReceiptsKey { - chain_id, - block_hash, - }; - let test_key = - ContentKey::HistoryContentKey(HistoryContentKey::ReceiptsKey(container.clone())); - let result = test_key.to_content_id().unwrap(); - - // create hash - let input = U256::from(chain_id).to_string() + &hex::encode(block_hash); - let actual = keccak(&input).unwrap(); - - assert_eq!(actual, result); - } - - #[test] - fn test_receipts_key_derive() { - let chain_id = 4; - let block_hash = vec_to_array(hex::decode(RANDOM_HASH_2).unwrap()).unwrap(); - let container = ReceiptsKey { - chain_id, - block_hash, - }; - let test_key = - ContentKey::HistoryContentKey(HistoryContentKey::ReceiptsKey(container.clone())); - let result = test_key.to_content_id().unwrap(); - - // create hash - let input = U256::from(chain_id).to_string() + &hex::encode(block_hash); - let actual = keccak(&input).unwrap(); - - assert_eq!(actual, result); - } } diff --git a/trin-core/src/utils/content_key.rs b/trin-core/src/utils/content_key.rs index 4ed568d29..a26e110fc 100644 --- a/trin-core/src/utils/content_key.rs +++ b/trin-core/src/utils/content_key.rs @@ -1,4 +1,5 @@ use crate::portalnet::types::uint::U256; +use hmac_sha256::Hash; use sha3::{Digest, Keccak256}; use std::convert::TryInto; use thiserror::Error; @@ -21,12 +22,16 @@ impl VecToArrayError { } } -pub fn keccak(key: &str) -> Result { +pub fn keccak256(key: &[u8]) -> U256 { let mut hasher = Keccak256::new(); hasher.update(key); - let result = hasher.finalize().to_vec(); - // if the underlying hash library is secure, then a 32 len vector will always be returned, so no error should ever occur - Ok(U256::from(vec_to_array::(result)?)) + let result = &hasher.finalize()[..]; + U256::from(result) +} + +pub fn sha256(key: &[u8]) -> U256 { + let output = Hash::hash(key); + U256::from(output) } pub fn vec_to_array(v: Vec) -> Result<[T; N], VecToArrayError> { @@ -39,21 +44,31 @@ mod test { use super::*; #[test] - fn test_keccak() { - let test_input = "302938402a9f"; - let result = keccak(test_input).unwrap(); - let inter = hex::decode("3fea4dacec93ff6fd6a7462d1a2cc656f7a13361bb36abf0dde7c27a3ca7606d") + fn test_keccak256() { + let test_input = hex::decode("302938402a9f").unwrap(); + let actual = keccak256(&test_input); + let bytes = hex::decode("924fd25eb4fdce477517e48f6e4d25d2fe53139c7ebcd7a1ac102577a465e4ca") + .unwrap(); + let expected = U256::from(vec_to_array(bytes).unwrap()); + assert_eq!(actual, expected); + } + + #[test] + fn test_sha256() { + let test_input = hex::decode("302938402a9f").unwrap(); + let actual = sha256(&test_input); + let inter = hex::decode("20b2e507035deae9513e0622890508a27c8f79648aa5d7dcce0fe34fea6893df") .unwrap(); - let actual = U256::from(vec_to_array(inter).unwrap()); - assert_eq!(actual, result); + let expected = U256::from(vec_to_array(inter).unwrap()); + assert_eq!(actual, expected); } #[test] fn test_vec_to_array() { let input = vec![4, 2, 5, 6]; - let result = vec_to_array(input).unwrap(); - let actual = [4, 2, 5, 6]; - assert_eq!(result, actual); + let actual = vec_to_array(input).unwrap(); + let expected = [4, 2, 5, 6]; + assert_eq!(actual, expected); } #[test]