Streaming hashing is broken #816
Labels
No labels
announcement
bug
build
CI
dependencies
documentation
duplicate
enhancement
experience feedback
feature request
github_actions
help wanted
install
invalid
Long-term
optimization
portability
question
target-specific
test issue
wontfix
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gh-Cyan4973/xxHash#816
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Since
github.com/Cyan4973/xxHash@44bb94ed60, incremental hashing (i.e., the XXH*_update functions) produce a different output than the stateless functions. I tested them in their 64bits variant, here's how to reproduce:The first mismatch happens at 2049 bytes, then they realign after 64 bytes. The the second mismatch is happens at 3073 bytes, so 1024 bytes after the first one. The pattern repeats. In
github.com/Cyan4973/xxHash@3f5c75cc75everything works fine.Hi @smarchini ,
Thanks for the report!
I've also confirmed your issue.
Actually, we have sanity check. But as your test shown, it's length set is incomplete.
Great point indeed,
we should enhance the sanity check with a loop test over a wider range of lengths.
Just verifying that one-shot and streaming variants output the same value could be done very quickly, without even a need to pre-record the expected values.
Then, in a second step, we could also generate the expected values, making the test even more strict.
I copied @smarchini's test as a gist file for testing.
We can use it with the following commands:
Hmmm...looks like an off by one then. I'll take a look.
This is totally my fault sooo 😅
So the error seems to happen when
nbStripes > 16 && nbStripes % 16 == 0.Got it, it should be
while (nbStripes >= nbStripesPerBlock);instead ofwhile (nbStripes > nbStripesPerBlock);. PR is up.yeah we really need this test for QEMU platforms.
Draft version of sanity check for direct vs streaming hash functions.
SANITY_BUFFER_SIZEto ease to detect pattern?XXH*_state_t?Possibly, though note that the current size would have been large enough to detect issue #816.
There must be a limit anyway. I'm slightly concerned about test runtime on weaker systems if the nb of lengths to test becomes really high. So an extended limit should probably stay within the ~ 4 KB range. Maybe
4 KB + 64 + 1for example.Possibly,
this seems like a minor speed optimization,
the more important part is that it would ensure that state reuse works well too.
I mean you say that but you also "conservatively" assume 300 MB/s in the benchmark that this test would presumably run with. If I go to an extreme (my 1.5 GHz Cortex-A53 running s390x -O0 in qemu) I get as low as 10 MB/s. 🤷♀️
I say that we should assume that you are running the test on a competent platform or make the self test separate from xxhsum -b.
Edit: XD
(Also yes for some reason my tablet's kernel is an
aarch64kernel reportingarmv7linunameand it isn't a 32-on-64 userspace 🤨)Also we have
TIMELOOP_MIN, we could setnbh_perIterationlow and let it auto-adjust so we don't take minutes on extreme scenarios like-O0onqemuon a potato processor while still being able to get an accurate result on beefy processors.We should probably set it as a dedicated test program, so that we are free of runtime considerations within
xxhsum.Also, if we start to record all hash values to compare too, this will result in a non-negligible increase of binary size.
So better make it a test program, and make it part of
make check.As a starting point, I wrote dumb (and huge) test vector generator:
https://gist.github.com/t-mat/0c83f0beb83a12ef3f1e16e64891465d
Please let me know we can go ahead this direction or not.
Also, should we separate test vector generator and actual sanity test program?
This is a great start @t-mat !
Probably ?
The test vector generator is only used during development time (possibly only once).
Its outcome is used to update the sanity test program, which is then run every time
make checkis invoked.@Cyan4973 , @easyaspi314
As for sanity test, I opened new issue #821.