crc

Cannot verify residue parameter for few CRC models from the catalogue


This question is related to the question I've already asked about the residue parameter:

CRC residue verification fails

With instructions provided in the answer I managed to verify the residue parameter for almost all CRC models from the catalogue: https://reveng.sourceforge.io/crc-catalogue/all.htm

However, for the following models, I cannot get the specified residue:

To simplify, I am using the RevEng tool to calculate the CRC:

https://sourceforge.net/projects/reveng/files/

Here is the procedure for CRC-12/CDMA2000:

reveng.exe -m crc-12/cdma2000 -c 313233343536373839
0d4d # Check: PASS

reveng.exe -m crc-12/cdma2000 -c 0313233343536373839d4d -x 0
0edc # Residue: FAIL (expected: 0000)

I first calculate CRC for the standard test message b'123456789' which is 313233343536373839 in hex. The resulting CRC is 0d4d which equals the check parameter. Then I append this 12-bit CRC to the original message in the big-endian mode (because refin=False): 0313233343536373839d4d, for which I calculate the CRC without the final XOR (notice the -x 0 flag). For all other models from the catalogue, the result equals the residue parameter. However, for the above-mentioned 10 models, it does not. I also tried using different starting messages just to test if I would get consistent residue; the residue changes for different message+CRC inputs.

What am I doing wrong?

Here is the Python function of how I append a CRC to a message:

def append(buffer: bytes, crc: int, width: int, refin: bool) -> bytes:
    # Number of bytes in the buffer and the CRC
    b_buf: int = len(buffer)
    b_crc: int = -(width // -8) # ceil

    if refin:
        message = (crc << (b_buf * 8)) | int.from_bytes(buffer, byteorder := 'little')
    else: # not refin
        message = (int.from_bytes(buffer, byteorder := 'big') << width) | crc

    return message.to_bytes(b_buf + b_crc, byteorder)

Solution

  • I don't see a way to provide reveng a non-multiple-of-eight bits to compute the CRC over. Given that, you cannot in general reproduce the residue for CRC's whose width is not a multiple of eight using reveng. You would need to write your own CRC code that can operate on a given number of bits, as opposed to a given number of bytes.

    The CRCs that you are not able to get to work are those that have a width that is not a multiple of eight, and that have a non-zero initial value. It looks like you are trying to compensate for the number of bits by prepending zero bits at the start of the message. That only works if the initial value is zero.

    There are two CRCs that meet those criteria that you did not list: CRC-3/ROHC and CRC-7/ROHC. I am guessing that your calculation accidentally matched the expected residue for those.