Skip to content

[crc64] Fix a subtle bug in CRC64 splice-by-8 implementation #627

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 15, 2020

Conversation

grendello
Copy link
Contributor

Context: 9b88ce7

9b88ce7 implements a splice-by-8 version of the CRC64 algorithm which
processes 8 bytes per loop iteration. However, the code had a subtle bug
which resulted in the same CRC calculated for different strings and made
some of Xamarin.Android tests to fail. The following strings yielded the
same checksum value:

  • obj/Debug/lp/10/jl/bin/classes.jar
  • obj/Debug/lp/11/jl/bin/classes.jar
  • obj/Debug/lp/12/jl/bin/classes.jar

The raeson for this was subtle (a stupid oversight on my part, really):
the loop fetched values from the input array by using an index into the
array:

crc ^= (ulong)aptr[idx];

However, with aptr being declared as byte* aptr the indexing
operation returned a single byte instead of the required 64-bit
word (8 bytes) and, thus, on each iteration of the loop 7 bytes of the
input arrays were ignored in calculation, thus causing the collisions.
The fix is to cast aptr to ulong* and then index it, extracting
the required 8 bytes.

This commit also adds a test to check for this issue.

Context: 9b88ce7

9b88ce7 implements a splice-by-8 version of the CRC64 algorithm which
processes 8 bytes per loop iteration. However, the code had a subtle bug
which resulted in the same CRC calculated for different strings and made
some of Xamarin.Android tests to fail. The following strings yielded the
same checksum value:

  * obj/Debug/lp/10/jl/bin/classes.jar
  * obj/Debug/lp/11/jl/bin/classes.jar
  * obj/Debug/lp/12/jl/bin/classes.jar

The raeson for this was subtle (a stupid oversight on my part, really):
the loop fetched values from the input array by using an index into the
array:

    crc ^= (ulong)aptr[idx];

However, with `aptr` being declared as `byte* aptr` the indexing
operation returned a single **byte** instead of the required 64-bit
word (8 bytes) and, thus, on each iteration of the loop 7 bytes of the
input arrays were ignored in calculation, thus causing the collisions.
The fix is to cast `aptr` to `ulong*` and **then** index it, extracting
the required 8 bytes.

This commit also adds a test to check for this issue.
@jonpryor jonpryor merged commit 7fe3a11 into dotnet:master Apr 15, 2020
@grendello grendello deleted the faster-crc64 branch April 15, 2020 14:34
jonpryor pushed a commit that referenced this pull request Apr 22, 2020
Commit 9b88ce7 implemented a splice-by-8 version of the CRC64
algorithm which processes 8 bytes per loop iteration. However, the
code had a subtle bug which resulted in the same CRC calculated for
different strings and made some of the Xamarin.Android tests to fail.

The following strings yielded the same checksum value:

  * `obj/Debug/lp/10/jl/bin/classes.jar`
  * `obj/Debug/lp/11/jl/bin/classes.jar`
  * `obj/Debug/lp/12/jl/bin/classes.jar`

The reason for this was subtle (a stupid oversight on my part, really):
the loop fetched values from the input array by using an index into
the array:

	crc ^= (ulong)aptr[idx];

However, with `aptr` being declared as `byte* aptr` the indexing
operation returned a single *byte* instead of the required 64-bit word
(8 bytes) and, thus, on each iteration of the loop 7 bytes of the input
arrays were ignored in calculation, thus causing the collisions.

The fix is to cast `aptr` to `ulong*` and *then* index it, extracting
the required 8 bytes.

This commit also adds a test to check for this issue.
@jpobst jpobst added this to the 10.4 (16.7 / 8.7) milestone Apr 23, 2020
@github-actions github-actions bot locked and limited conversation to collaborators Apr 13, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants