Great. But keep in mind that this is not a keyed hash function.
This is mentioned in the documentation: "Warning! This is not a cryptographic function, and it certainly should not be used as one. If you want a good cryptograhic hash function, you should use SHA-3 (Keccak) or BLAKE2."
SeaHash: A fast, portable hash function in Rust
21–30 of 116 posts
Re: SeaHash: A fast, portable hash function in Rust
#22This is is not a knock against SeaHash, but I was looking at buffer.rs [0] and noticed pretty much all the code is wrapped in unsafe {} blocks. How much advantage is there to rust implementation vs c++ if unsafe is used so liberally? I ask this in ernest. [0] https://docs.rs/crate/seahash/2.0.0/source/src/buffer.rs
I think this code could potentially be refactored with smaller unsafe blocks, if that were a goal.
The benefit in general is present for many reasons, among which is that you still have to opt-in to unsafe{} and SeaHash consumers wouldn't need to in order to leverage these features.
The benefit for SeaHash specifically is that Rust isn't merely a safer language, it's also one with arguably newer/better language features than C++. And it's one that has support for several targets today.
Re: SeaHash: A fast, portable hash function in Rust
#23This is is not a knock against SeaHash, but I was looking at buffer.rs [0] and noticed pretty much all the code is wrapped in unsafe {} blocks. How much advantage is there to rust implementation vs c++ if unsafe is used so liberally? I ask this in ernest. [0] https://docs.rs/crate/seahash/2.0.0/source/src/buffer.rs
Re: SeaHash: A fast, portable hash function in Rust
#24Earlier quoted context omitted.
The claim is that it is a blazingly fast hash function compared with other hash functions , and it is also written in Rust. Rust is an enabling technology, but not able to be dramatically faster than a comparable C/C++ implementation, as a general rule.
The title is confusing. If it tries to compete with other hash functions, why does the title have to bear "in Rust"?
I predict Rust will also begin to find use as a backend server language, and begin to eat into Java, Go, Python, and Ruby mindshare. Though there's a learning curve with Rust, it doesn't take too long to become productive. I'm also excited to see how Rust makes inroads in game development.
I think we're all going to start seeing more Rust in our headlines. It's a great language, and the people I know that use it are in love with it (myself included).
Re: SeaHash: A fast, portable hash function in Rust
#25The first line, "x ← x ≫ 32", might have a typo? It's actually assigning (x XOR (x >> 32)).
With "x ← px", p is a fixed prime number being multiplied by x.
Re: SeaHash: A fast, portable hash function in Rust
#26I was trying to figure out how this is so much faster than FNV https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo... Is it only because of the parallelism? Or are the operations really that much cheaper somehow?
The pseudocode for FNV looks like this:
hash = FNV_offset_value
for each byte_of_data to be hashed
{
hash = hash XOR byte_of_data
hash = hash × FNV_prime
}
return hash
The pseudocode for seahash looks like this (with '×' as the wrapping multplier operator, and some simplification for padding if the data length in bytes is not a multiple of 8 bytes per word × 4 words in the hash state): hash = {offset_1, offset_2, offset_3, offset_4}
for (int data_index = 0;
data_index
FNV is operating on bytes of data, while seahash is operating on 64-bit words. A modern processor will be able to handle 64 bits at once. True, it can probably handle 8 bits independently in one instruction without having to create a temporary value, but it still needs to do more operations.FNV is completely sequential. Until the first byte is hashed, no work can be done on the second byte. In seahash, as you observed, parallelism can be exploited. The second, third, and fourth bytes are all completely independent of the first byte, as bytes 6, 7, and 8 are independent of byte 5, and so on. You can have four independent threads each do a quarter of the work, and then put the result back together at the end.
Re: SeaHash: A fast, portable hash function in Rust
#27This is is not a knock against SeaHash, but I was looking at buffer.rs [0] and noticed pretty much all the code is wrapped in unsafe {} blocks. How much advantage is there to rust implementation vs c++ if unsafe is used so liberally? I ask this in ernest. [0] https://docs.rs/crate/seahash/2.0.0/source/src/buffer.rs
None. But once you're out of the buffer code, it's safe.
Re: SeaHash: A fast, portable hash function in Rust
#28I wonder how the Rust version compares with plain-jane C.
-Austin (murmurhash guy).
Re: SeaHash: A fast, portable hash function in Rust
#29Earlier quoted context omitted.
None. But once you're out of the buffer code, it's safe.
It's safe as long as the unsafe code didn't mess with pointers in unexpected ways. Your unsafe code still needs to behave in a sane way for any safety guarantees to hold.
Re: SeaHash: A fast, portable hash function in Rust
#30Looks like a pretty straightforward 64-bit block hash unrolled 4 times. I'd prefer a bit more assymetry in the diffuse() method, but since it passes SMHasher it's probably OK. I wonder how the Rust version compares with plain-jane C. -Austin (murmurhash guy).
For example, if IV1 and IV2 match and the block pattern is ABCDABCDABCD, then BACDBACDBACD will produce the same hash value.
A minor finalizer change would fix it for any IV (pseudocode as I don't actually know Rust) -
vec[0] ^= diffuse(vec[1]); vec[1] ^= diffuse(vec[0]); vec[2] ^= diffuse(vec[3]); vec[3] ^= diffuse(vec[2]);
u64 result = diffuse(vec[1] ^ diffuse(vec[3]));
that's probably overkill but should work.