Skip to content
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

errors in constants and descriptions in crc/crc64_..._refl_by8.asm #88

Open
jeffareid opened this issue Sep 20, 2019 · 2 comments
Open

Comments

@jeffareid
Copy link

jeffareid commented Sep 20, 2019

The constant descriptions in crc/crc64_ecma_refl_by8.asm and crc/crc64_iso_refl_by8.asm, are off by a factor of 2. Since pclmulqdq generates a product in bits 126 to 0, the reflected product is effectively multiplied by 2. This is compensated for in the constants, but the comments describing these constants missed how these constants are compensated. Specifically:

; rk7 = floor(2^128/Q) should be ; rk7 = floor(2^127/(reflected(65 bit polynomial)))
Note that this also means that rk7 is a 64 bit number, without an implied x^64 term.

; rk8 = Q should be ; rk8 = reflected ((65 bit polynomial)>>1 )-1

The rk8 constants will work as is, since only the left most 64 bits are returned for the CRC, but to be technically correct rk8 should be reflected ((65 bit polynomial)>>1 ) (without the -1).
For ecma_refl: rk8 dq 0x92d8af2baf0e1e84 should be rk8 dq 0x92d8af2baf0e1e85
For iso_refl: rk8 dq 0xb000000000000000 should be 0xb000000000000001
For jones_refl: rk8 dq 0x2b5926535897936a should be 0x2b5926535897936b
This will result in the right half of xmm7 == 0 after computing CRC, but since only the left half is returned, the missing 1 in the right most bit (which corresponds to x^64) in rk8 does not affect the returned CRC, but it can be confusing.

The 64 bit rk8 constant has an implied but missing left most bit, which corresponds to a 1. The code computes (q * rk8) + (q * 1) = (q * (65 bit polynomial)) to compensate for the missing left most bit. This isn't documented either.

The other constants are not documented. To deal with pclmulqdq with reflected products, the exponents are (e * 64) - 1:

; rk1 = reflected (2^127 % (65 bit polynomial))
; rk2 = reflected (2^191 % (65 bit polynomial))

@gbtucker
Copy link
Contributor

gbtucker commented Oct 3, 2019

Sorry about the confusion. Thanks for the clarification.

@jeffareid
Copy link
Author

jeffareid commented Oct 4, 2019

You might want to consider adding the source code for the program used to generate the rk.. constants into the ...\crc directory.

If interested, here are the reflected iso rk.. constants with comments. Note I changed rk1 to rk01, rk2 to rk02, ... . I also added the 1 back to rk08. P(x) is the 65 bit reflected polynomial. As commented above, rk08 is missing the left most (65th) bit, which corresponds to a 1 (for a non-reflected polynomial, the missing left most bit corresponds to x^64).

rk01 dq 0f500000000000001h ;2^((64 x 2)-1) mod P(x)
rk02 dq 06b70000000000001h ;2^((64 x 3)-1) mod P(x)
rk03 dq 0b001000000010000h ;2^((64 x 16)-1) mod P(x)
rk04 dq 0f501b0000001b000h ;2^((64 x 17)-1) mod P(x)
rk05 dq 0f500000000000001h ;2^((64 x 2)-1) mod P(x)
rk06 dq 00000000000000000h ;2^((64 x 1)-1) mod P(x)
rk07 dq 0b000000000000001h ;floor((2^127)/(P(x))
rk08 dq 0b000000000000001h ;P(x) - 1
rk09 dq 0e014514514501501h ;2^((64 x 14)-1) mod P(x)
rk10 dq 0771db6db6db71c71h ;2^((64 x 15)-1) mod P(x)
rk11 dq 0a101101101110001h ;2^((64 x 12)-1) mod P(x)
rk12 dq 01ab1ab1ab1aab001h ;2^((64 x 13)-1) mod P(x)
rk13 dq 0f445014445000001h ;2^((64 x 10)-1) mod P(x)
rk14 dq 06aab71daab700001h ;2^((64 x 11)-1) mod P(x)
rk15 dq 0b100010100000001h ;2^((64 x 8)-1) mod P(x)
rk16 dq 001b001b1b0000001h ;2^((64 x 9)-1) mod P(x)
rk17 dq 0e145150000000001h ;2^((64 x 6)-1) mod P(x)
rk18 dq 076db6c7000000001h ;2^((64 x 7)-1) mod P(x)
rk19 dq 0a011000000000001h ;2^((64 x 4)-1) mod P(x)
rk20 dq 01b1ab00000000001h ;2^((64 x 5)-1) mod P(x)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants