Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

replace trait Hashable with fn keccak #6423

Merged
merged 7 commits into from
Aug 31, 2017
Merged

replace trait Hashable with fn keccak #6423

merged 7 commits into from
Aug 31, 2017

Conversation

debris
Copy link
Collaborator

@debris debris commented Aug 31, 2017

part of #6418

changes:

  • renamed const variables SHA3_XXX to KECCAK_XXX
  • TransactionView, BlockView and HeaderView has now pub fn hash() which returns their hash. Usage of it does not require import of Hashable trait
  • removed trait Hashable
  • added fn keccak. Using function is more idiomatic. Also it's more flexible and can be easily used with options and iterators. We can now write:
    fn old_usage(option: Option<H256>, vector: Vec<H256>) {
      let x = option.map(|o| o.sha3());
      // or 
      let x = option.as_ref().map(Hashable::sha3);
    
      let y = vector.into_iter().map(|i| i.sha3()).collect();
      // or
      let y = vector.iter().map(Hashable::sha3).collect();
    }
    
    fn new_usage(option: Option<H256>, vector: Vec<H256>) {
      let x = option.map(keccak);
      // or
      let x = option.as_ref().map(keccak);
    
      let y = vector.into_iter().map(keccak).collect();
      // or
      let y = vector.iter().map(keccak).collect();
    }
  • fn keccak is no longer a part of util. This is a critical step required to make modules independent

@paritytech/core-devs can you please review the code? The sooner we agree on those changes and merge them, the less hassle it will be to keep it up-to-date

@debris debris added A0-pleasereview 🤓 Pull request needs code review. M4-core ⛓ Core client code / Rust. labels Aug 31, 2017
@eira-fransham
Copy link
Contributor

This is just a renaming pass and still uses the C implementation, right? There is unsafe code that relies on the precise semantics of the C SHA3 (specifically, that it uses an internal buffer and so the input and output arrays can be the same/overlapping). I think that it might be better if we don't do that (and use the output buffer directly to reduce memcpy calls) but for now that's the assumption we make.

Copy link
Contributor

@eira-fransham eira-fransham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's some suspicious stuff here but I don't know enough about it to explicitly reject it.

pub fn keccak_into<T: AsRef<[u8]>>(s: T, dest: &mut [u8]) {
let input = s.as_ref();
unsafe {
keccak_256(dest.as_mut_ptr(), dest.len(), input.as_ptr(), input.len());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we ignore the return value of keccak_256? Probably at least worth putting a comment explaining that.

nonce_material.sha3_into(&mut key_material[32..64]);
key_material.sha3().copy_to(&mut key_material[32..64]);
key_material.sha3().copy_to(&mut key_material[32..64]);
keccak_into(&nonce_material, &mut key_material[32..64]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really more ergonomic? What's wrong with using a trait here? I wouldn't have an opinion either way if this was original code but since it's the stated purpose of the PR it deserves analysis.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's one of the purposes :) imo, there is no point in using the trait if simple function is enough

H256(result)
}

pub fn keccak_into<T: AsRef<[u8]>>(s: T, dest: &mut [u8]) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bikeshed: _into implies taking ownership of T's data and transforming it into something rather than writing it to a buffer, this confused me when first reading this code. I recommend write_keccak, but it's a matter of taste. I think it's good to avoid names that already have a common, conflicting use in Rust code.

@debris
Copy link
Collaborator Author

debris commented Aug 31, 2017

This is just a renaming pass and still uses the C implementation, right?

Yes. Cause the C implementation is still ~10% faster than we achieved with rust.

There is unsafe code that relies on the precise semantics of the C SHA3 (specifically, that it uses an internal buffer and so the input and output arrays can be the same/overlapping). I think that it might be better if we don't do that (and use the output buffer directly to reduce memcpy calls) but for now that's the assumption we make.

I'm not sure I understand your point. Do you want to return internal buffer from keccak function? It's not possible with this type of hash function.

@eira-fransham
Copy link
Contributor

Essentially all I'm saying is that some unsafe code relies on the hash function allowing input and output to overlap, so as long as that still holds we're all good. It looks like it does, I just wanted to make certain.

@debris
Copy link
Collaborator Author

debris commented Aug 31, 2017

Yes, nothing has changed internally

@@ -336,7 +336,7 @@ fn hash_compute(light: &Light, full_size: usize, header_hash: &H256, nonce: u64)
);

// compute sha3-512 hash and replicate across mix
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/sha3/keccak ?

Copy link
Contributor

@folsen folsen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In util/rlp/src/common.rs there's some references to SHA3_NULL_RLPand SHA3_EMPTY, I'm guessing they should be changed.

}

fn sha3_512_inplace(input: &mut [u8]) {
fn keccak_512_inplace(input: &mut [u8]) {
// This is safe since `sha3_*` uses an internal buffer and copies the result to the output. This
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/sha3/keccak

@rphmeier rphmeier added A8-looksgood 🦄 Pull request is reviewed well. and removed A0-pleasereview 🤓 Pull request needs code review. labels Aug 31, 2017
@rphmeier
Copy link
Contributor

LGTM now that grumbles have been addressed

@rphmeier rphmeier merged commit 47f7366 into master Aug 31, 2017
@rphmeier rphmeier deleted the keccak_fn branch August 31, 2017 15:20
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
A8-looksgood 🦄 Pull request is reviewed well. M4-core ⛓ Core client code / Rust.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants