Search code examples
c#macoscrccommoncryptocrc64

No CRC64 implementation equal to CommonCrypto?


I am porting some code from C on OSX to C# that uses CommonCrypto with the kCN_CRC_64_ECMA_182 CRC64 implementation. For example, using CommonCrypto the CRC would be computed with:

CNCRC(kCN_CRC_64_ECMA_182, bytes, bytesLen, &crcResult)

This outputs the correct value. When using the C# library HashLib (or any other code), the output is completely different, for example, the equivalent to the above using HashLib would be:

var checksum = HashFactory.Checksum.CreateCRC64(0x42F0E1EBA9EA3693UL); // ECMA 182 var result = checksum.ComputeBytes(bytes);

Any ideas? Is there an implementation in C# that is equivalent to Apple's CommonCrypto in terms of output?


Solution

  • Here is some simple C code to compute the ECMA-182 CRC:

    #include <stddef.h>
    #include <stdint.h>
    
    #define POLY UINT64_C(0x42f0e1eba9ea3693)
    #define TOP UINT64_C(0x8000000000000000)
    
    /* Return crc updated with buf[0..len-1].  If buf is NULL, return the initial
       crc.  So, initialize with crc = crc64_ecma182(0, NULL, 0); and follow with
       one or more applications of crc = crc64_ecma182(crc, buf, len); */
    int64_t crc64_ecma182(int64_t crc, unsigned char *buf, size_t len)
    {
        int k;
    
        if (buf == NULL)
            return 0;
        while (len--) {
            crc ^= (uint64_t)(*buf++) << 56;
            for (k = 0; k < 8; k++)
                crc = crc & TOP ? (crc << 1) ^ POLY : crc << 1;
        }
        return crc;
    }
    

    I think HashLib is simply wrong, judging by what I found on github. It is doing the CRC reflected, whereas the CRC64 defined in ECMA-182 is not reflected.