Skip to content

Conversation

sjaeckel
Copy link
Member

@sjaeckel sjaeckel commented Mar 9, 2017

in crc32_test we have:

{
   const void* in = "libtomcrypt";
   const unsigned char crc32[] = { 0xef, 0x76, 0x73, 0xb3 };
   ....
}

However the correct CRC32 from "libtomcrypt" string is IMHO b37376ef not ef7673b3.

By which I mean the actual CRC32 implementation seems to be somehow incorrect not crc32_test.

@rofl0r
Copy link

rofl0r commented Jul 3, 2016

b37376ef vs ef7673b3 is endian swapped

@karel-m
Copy link
Member Author

karel-m commented Feb 21, 2017

@sjaeckel what do you think about this?

In my perl bindings I have implemented a fix like this: DCIT/perl-CryptX@b8bf151

I can prepare the same fix as a pull request if you agree.

karel-m added a commit that referenced this pull request Feb 21, 2017
@sjaeckel sjaeckel modified the milestone: v2.0.0 Feb 21, 2017
@sjaeckel
Copy link
Member

... unsigned char crc32[] = { 0xef, 0x76, 0x73, 0xb3 }; is the same as uint32_t crc32 = 0xb37376ef; on a little endian CPU (memory-wise).

c.f. #109 and I'm pretty certain that the original implementation is correct.

@karel-m
Copy link
Member Author

karel-m commented Feb 21, 2017

If the implementation is correct than the interface must be wrong:

void crc32_finish(crc32_state *ctx, void *hash, unsigned long size)

I believed (but now I am in doubts) that void *hash is meant to be a pointer to unsigned char[4] (see crc32_test and unsigned char out[4]).

I do not see any reason for using void * instead I prefer explicitly declare it as unlong32 *hash or unsigned char *hash.

Other thing is that the test case (crc32_test) should be a proof-of-concept correct implementation (as it was a place where people will look to see how to use/call it).

@rofl0r
Copy link

rofl0r commented Feb 21, 2017

there's http://reveng.sourceforge.net/crc-catalogue/17plus.htm#crc.cat.crc-32 which lists check=0xcbf43926 as the checksum for the test string 123456789. i suppose that should match. more info here https://www.lammertbies.nl/comm/info/crc-calculation.html
i personally would assume a crc32 function giving me an uint32_t, not an array of 4bytes, however that's not what i see for example here: https://github.com/rofl0r/libulz/blob/master/src/crc32/crc32c.c#L143 . here the output seems to be arranged to produce an endian-independent value, however that is a CRC32-C impl (castagnoli variant).

@karel-m
Copy link
Member Author

karel-m commented Feb 21, 2017

Other thing is consistency between interfaces for crc32 and adler32

Both have pretty similar:

void adler32_finish(adler32_state *ctx, void *hash, unsigned long size)
void crc32_finish(crc32_state *ctx, void *hash, unsigned long size)

but the interpretation of hash output is different

//crc32_test - expected HEX value "B37376EF"
const unsigned char crc32[] = { 0xef, 0x76, 0x73, 0xb3 };

//adler32_test - expected HEX value "1BE804BA"
const unsigned char adler32[] = { 0x1b, 0xe8, 0x04, 0xba };

for test vectors try:

@sjaeckel
Copy link
Member

but the interpretation of hash output is different...

oh yeah, that's pretty bad...

nonetheless I think we should keep the crc implementation and adjust the adler implementation, okay?

@karel-m
Copy link
Member Author

karel-m commented Feb 22, 2017 via email

@karel-m
Copy link
Member Author

karel-m commented Mar 1, 2017

I will try to reword the problem which should be perhaps named adler32 vs. crc32 inconsistency:

1/ the API

We have:

void adler32_finish(adler32_state *ctx, void *hash, unsigned long size)
void crc32_finish(crc32_state *ctx, void *hash, unsigned long size)

which is not what one can see on other places in libtomcrypt. My proposal:

void adler32_finish(adler32_state *ctx, unsigned char *out, unsigned long *outlen)
void crc32_finish(crc32_state *ctx, unsigned char *out, unsigned long *outlen)

2/ the byte order

Both functions adler32_finish and crc32_finish return 4 bytes (the implementation guarantees the same result on all platforms independant on endianness), however:

  • adler32_finish returns 4 bytes in big endian order AKA network byte order
  • crc32_finish returns 4 bytes in little endian order

My proposal: change crc32_finish to return network byte order

@karel-m karel-m changed the title crc32_test incorrect (I guess) adler32 vs. crc32 inconsistency Mar 1, 2017
@sjaeckel
Copy link
Member

sjaeckel commented Mar 1, 2017

1/ the API

These API's didn't fit anywhere, that's why I broke with the old concepts. (Yes I know, I could've integrated them in the existing "hashing framework"... I can't exactly remember why I didn't do that, but I somehow still don't like the idea to have them in there... why didn't I integrate them there again...?)

TBH I don't care if we write the written length back, but we definitely have to stop with that unsigned char* craziness for opaque data at one point. Therefor 👎 for unsigned char* out

...and 👍 for a PR "change all in- and output data pointers to void*" (just kiddin'!)

I also thought about something like the following, but apparently that's not an option if you think about integrating other checksum/nc-hashing algorithms with bigger output.

ulong32 X_finish(X_state *ctx);

2/ the byte order

👍

@karel-m karel-m self-assigned this Mar 1, 2017
@karel-m
Copy link
Member Author

karel-m commented Mar 2, 2017

Ad 2/
For "libtomcrypt" the correct values are IMO:

  • crc32: B37376EF
  • adler32: 1BE804BA

So in our test suit we need:

  • const unsigned char crc32[] = { 0xb3, 0x73, 0x76, 0xef };
  • const unsigned char adler32[] = { 0x1b, 0xe8, 0x04, 0xba };

Which can be achieved by b3109cb (== merging fix/122)

Ad 1/
let's keep the current API

@coveralls
Copy link

Coverage Status

Coverage remained the same at 87.319% when pulling b3109cb on fix/122 into 456908e on develop.

@sjaeckel
Copy link
Member

sjaeckel commented Mar 9, 2017

fine to rebase&merge

@karel-m karel-m merged commit 78e9b0f into develop Mar 9, 2017
@karel-m karel-m deleted the fix/122 branch March 9, 2017 19:33
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

Successfully merging this pull request may close these issues.

4 participants