You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@nuttx.apache.org by Karel Kočí <cy...@email.cz> on 2022/07/15 12:09:44 UTC

CRC32 what gives?

Hi

I hit an issue with crc32 implementation in NuttX's LibC and it took me some 
time to figure out that crc32 is implemented differently in NuttX than I was 
expecting. Let me explain...

Common implementations are using same precomputed table as there is in the 
NuttX, but the initial value is all ones and not zero as in case of the NuttX 
(0xffffffff vs 0x0) and the result is negated while that is not true in the 
NuttX.
In other words the call `crc32(msg, msgsiz)` gives "unexpected" result while 
`~crc32part(msg, msgsiz, 0xffffffff)` gives the "correct" one.

I can see the idea behind not performing negation twice (`crc32part` would have 
to negate `crc32val` at the start and then return it negated again) but using 
the same precomputed table gives then different results.

I am not sure if this weakens the crc32 in some way or just has no side effect 
except of not matching with common implementations. Either way this discrepancy 
should be at least documented with suggestion to use `~crc32part(msg, msgsiz, 
0xffffffff)`. What do you think?

With regards
Karel Kočí

Re: CRC32 what gives?

Posted by Nimish Telang <ni...@telang.net.INVALID>.
https://github.com/madler/crcany is what I have been using to make one off CRC implementations. Consolidating the various ones into a single library might be useful.

From: Alan Carvalho de Assis <ac...@gmail.com>
Date: Friday, July 15, 2022 at 7:31 PM
To: dev@nuttx.apache.org <de...@nuttx.apache.org>
Subject: Re: CRC32 what gives?
We also have CRC4 used by MS5611 barometer sensor. It should be nice to
have all available in the kernel

On Friday, July 15, 2022, Nimish Telang <ni...@telang.net.invalid> wrote:

> Whichever one is chosen, there should be a table-free implementation for
> code size reasons. FWIW there are more crc implementations in the zmodem
> app: https://github.com/apache/incubator-nuttx-apps/blob/
> master/system/zmodem/host/crc16.c
>
>
>
> From: Sebastien Lorquet <se...@lorquet.fr>
> Date: Friday, July 15, 2022 at 4:13 PM
> To: dev@nuttx.apache.org <de...@nuttx.apache.org>
> Subject: Re: CRC32 what gives?
> @Nathan:
>
> Yes, of course.
>
> @Alan:
>
> Of course not, the structure passed to init can be set up to describe
> the required algorithm.
>
> But the partial update situation can be useful for protocols where the
> message is fragmented (eg radio transceivers with short FIFOs), or where
> only some fields enter the crc (I have seen this happen several times).
> you cant call the global crc() function on several buffers in sequence
> if bits are inverted on crc output.
>
> Sebastien
>
> On 7/15/22 20:21, Nathan Hartman wrote:
> > On Fri, Jul 15, 2022 at 1:40 PM Alan Carvalho de Assis
> > <ac...@gmail.com> wrote:
> >> Hi Sebastien, I think we don't need these three functions for each
> >> CRC, just one like in the Linux kernel is enough:
> >>
> >> https://www.kernel.org/doc/htmldocs/kernel-api/API-crc-ccitt.html
> >>
> >> BR,
> >>
> >> Alan
> >
> > Could have one generic function and then thin wrappers that call it
> > with the correct parameters for different uses.
> >
> > Cheers,
> > Nathan
>

Re: CRC32 what gives?

Posted by Alan Carvalho de Assis <ac...@gmail.com>.
We also have CRC4 used by MS5611 barometer sensor. It should be nice to
have all available in the kernel

On Friday, July 15, 2022, Nimish Telang <ni...@telang.net.invalid> wrote:

> Whichever one is chosen, there should be a table-free implementation for
> code size reasons. FWIW there are more crc implementations in the zmodem
> app: https://github.com/apache/incubator-nuttx-apps/blob/
> master/system/zmodem/host/crc16.c
>
>
>
> From: Sebastien Lorquet <se...@lorquet.fr>
> Date: Friday, July 15, 2022 at 4:13 PM
> To: dev@nuttx.apache.org <de...@nuttx.apache.org>
> Subject: Re: CRC32 what gives?
> @Nathan:
>
> Yes, of course.
>
> @Alan:
>
> Of course not, the structure passed to init can be set up to describe
> the required algorithm.
>
> But the partial update situation can be useful for protocols where the
> message is fragmented (eg radio transceivers with short FIFOs), or where
> only some fields enter the crc (I have seen this happen several times).
> you cant call the global crc() function on several buffers in sequence
> if bits are inverted on crc output.
>
> Sebastien
>
> On 7/15/22 20:21, Nathan Hartman wrote:
> > On Fri, Jul 15, 2022 at 1:40 PM Alan Carvalho de Assis
> > <ac...@gmail.com> wrote:
> >> Hi Sebastien, I think we don't need these three functions for each
> >> CRC, just one like in the Linux kernel is enough:
> >>
> >> https://www.kernel.org/doc/htmldocs/kernel-api/API-crc-ccitt.html
> >>
> >> BR,
> >>
> >> Alan
> >
> > Could have one generic function and then thin wrappers that call it
> > with the correct parameters for different uses.
> >
> > Cheers,
> > Nathan
>

Re: CRC32 what gives?

Posted by Nimish Telang <ni...@telang.net.INVALID>.
Whichever one is chosen, there should be a table-free implementation for code size reasons. FWIW there are more crc implementations in the zmodem app: https://github.com/apache/incubator-nuttx-apps/blob/master/system/zmodem/host/crc16.c



From: Sebastien Lorquet <se...@lorquet.fr>
Date: Friday, July 15, 2022 at 4:13 PM
To: dev@nuttx.apache.org <de...@nuttx.apache.org>
Subject: Re: CRC32 what gives?
@Nathan:

Yes, of course.

@Alan:

Of course not, the structure passed to init can be set up to describe
the required algorithm.

But the partial update situation can be useful for protocols where the
message is fragmented (eg radio transceivers with short FIFOs), or where
only some fields enter the crc (I have seen this happen several times).
you cant call the global crc() function on several buffers in sequence
if bits are inverted on crc output.

Sebastien

On 7/15/22 20:21, Nathan Hartman wrote:
> On Fri, Jul 15, 2022 at 1:40 PM Alan Carvalho de Assis
> <ac...@gmail.com> wrote:
>> Hi Sebastien, I think we don't need these three functions for each
>> CRC, just one like in the Linux kernel is enough:
>>
>> https://www.kernel.org/doc/htmldocs/kernel-api/API-crc-ccitt.html
>>
>> BR,
>>
>> Alan
>
> Could have one generic function and then thin wrappers that call it
> with the correct parameters for different uses.
>
> Cheers,
> Nathan

Re: CRC32 what gives?

Posted by Sebastien Lorquet <se...@lorquet.fr>.
@Nathan:

Yes, of course.

@Alan:

Of course not, the structure passed to init can be set up to describe 
the required algorithm.

But the partial update situation can be useful for protocols where the 
message is fragmented (eg radio transceivers with short FIFOs), or where 
only some fields enter the crc (I have seen this happen several times). 
you cant call the global crc() function on several buffers in sequence 
if bits are inverted on crc output.

Sebastien

On 7/15/22 20:21, Nathan Hartman wrote:
> On Fri, Jul 15, 2022 at 1:40 PM Alan Carvalho de Assis
> <ac...@gmail.com> wrote:
>> Hi Sebastien, I think we don't need these three functions for each
>> CRC, just one like in the Linux kernel is enough:
>>
>> https://www.kernel.org/doc/htmldocs/kernel-api/API-crc-ccitt.html
>>
>> BR,
>>
>> Alan
>
> Could have one generic function and then thin wrappers that call it
> with the correct parameters for different uses.
>
> Cheers,
> Nathan

Re: CRC32 what gives?

Posted by Nathan Hartman <ha...@gmail.com>.
On Fri, Jul 15, 2022 at 1:40 PM Alan Carvalho de Assis
<ac...@gmail.com> wrote:
>
> Hi Sebastien, I think we don't need these three functions for each
> CRC, just one like in the Linux kernel is enough:
>
> https://www.kernel.org/doc/htmldocs/kernel-api/API-crc-ccitt.html
>
> BR,
>
> Alan


Could have one generic function and then thin wrappers that call it
with the correct parameters for different uses.

Cheers,
Nathan

Re: CRC32 what gives?

Posted by Alan Carvalho de Assis <ac...@gmail.com>.
Hi Sebastien, I think we don't need these three functions for each
CRC, just one like in the Linux kernel is enough:

https://www.kernel.org/doc/htmldocs/kernel-api/API-crc-ccitt.html

BR,

Alan

On 7/15/22, Sebastien Lorquet <se...@lorquet.fr> wrote:
> Hi,
>
> Sorry to throw a rock in the pond but having a single function named
> "crc32" is very wrong and is not sufficient.
>
> As you have discussed the polynomial length is just not enough to
> describe a crc, the initial value, bit orders of input and output, and
> bit inversion on input and output are all used to derive actual crc
> functions.
>
> A proper API for an evolved project like nuttx should have a set of
> functions like crc_init, crc_update and crc_final, all acting on a crc
> context, just like sha and md5.
>
> This would also allow specific implementations to use the hardware crc
> resources provided by specific circuits.
>
> This would allow each use of the crc routines to define and use its own
> version of the crc, without interfering on other uses.
>
> For example I agree it would be very unwise to change the CRC kind used
> by file systems as it would break so many systems.
>
> Sebastien
>
> On 7/15/22 18:54, Karel Kočí wrote:
>> Excerpts from Nathan Hartman's message of July 15, 2022 6:47 pm:
>>> On Fri, Jul 15, 2022 at 12:45 PM Karel Kočí <cy...@email.cz> wrote:
>>>> The impact might be pretty significant from my search and that is also
>>>> why I
>>>> rather discuss instead of suggesting changes.
>>>>
>>>> The significant place where the current crc32 implementation is used is
>>>> in
>>>> file systems (such as smartfs or nxffs). The change would break any
>>>> existing
>>>> formating of those FSs. Thus I also do not think it should be done.
>>>
>>> Are these file systems readable by other operating systems besides
>>> NuttX?
>> Those are NuttX only up to my knowledge. The change would break old
>> formated
>> device on NuttX version update which sounds bad to me and "fix" (or rather
>> let's
>> say change to some other crc32 algorithm) won't fix compatibility with
>> some
>> other systems...
>

Re: CRC32 what gives?

Posted by Sebastien Lorquet <se...@lorquet.fr>.
Hi,

Sorry to throw a rock in the pond but having a single function named 
"crc32" is very wrong and is not sufficient.

As you have discussed the polynomial length is just not enough to 
describe a crc, the initial value, bit orders of input and output, and 
bit inversion on input and output are all used to derive actual crc 
functions.

A proper API for an evolved project like nuttx should have a set of 
functions like crc_init, crc_update and crc_final, all acting on a crc 
context, just like sha and md5.

This would also allow specific implementations to use the hardware crc 
resources provided by specific circuits.

This would allow each use of the crc routines to define and use its own 
version of the crc, without interfering on other uses.

For example I agree it would be very unwise to change the CRC kind used 
by file systems as it would break so many systems.

Sebastien

On 7/15/22 18:54, Karel Kočí wrote:
> Excerpts from Nathan Hartman's message of July 15, 2022 6:47 pm:
>> On Fri, Jul 15, 2022 at 12:45 PM Karel Kočí <cy...@email.cz> wrote:
>>> The impact might be pretty significant from my search and that is also why I
>>> rather discuss instead of suggesting changes.
>>>
>>> The significant place where the current crc32 implementation is used is in
>>> file systems (such as smartfs or nxffs). The change would break any existing
>>> formating of those FSs. Thus I also do not think it should be done.
>>
>> Are these file systems readable by other operating systems besides NuttX?
> Those are NuttX only up to my knowledge. The change would break old formated
> device on NuttX version update which sounds bad to me and "fix" (or rather let's
> say change to some other crc32 algorithm) won't fix compatibility with some
> other systems...

Re: CRC32 what gives?

Posted by Karel Kočí <cy...@email.cz>.
Excerpts from Nathan Hartman's message of July 15, 2022 6:47 pm:
> On Fri, Jul 15, 2022 at 12:45 PM Karel Kočí <cy...@email.cz> wrote:
>>
>> The impact might be pretty significant from my search and that is also why I
>> rather discuss instead of suggesting changes.
>>
>> The significant place where the current crc32 implementation is used is in
>> file systems (such as smartfs or nxffs). The change would break any existing
>> formating of those FSs. Thus I also do not think it should be done.
> 
> 
> Are these file systems readable by other operating systems besides NuttX?

Those are NuttX only up to my knowledge. The change would break old formated 
device on NuttX version update which sounds bad to me and "fix" (or rather let's 
say change to some other crc32 algorithm) won't fix compatibility with some 
other systems...

Re: CRC32 what gives?

Posted by Nathan Hartman <ha...@gmail.com>.
On Fri, Jul 15, 2022 at 12:45 PM Karel Kočí <cy...@email.cz> wrote:
>
> The impact might be pretty significant from my search and that is also why I
> rather discuss instead of suggesting changes.
>
> The significant place where the current crc32 implementation is used is in
> file systems (such as smartfs or nxffs). The change would break any existing
> formating of those FSs. Thus I also do not think it should be done.


Are these file systems readable by other operating systems besides NuttX?

Nathan

Re: CRC32 what gives?

Posted by Karel Kočí <cy...@email.cz>.
Excerpts from Nathan Hartman's message of July 20, 2022 4:32 pm:
> On Wed, Jul 20, 2022 at 10:24 AM Karel Kočí <cy...@email.cz> wrote:
>>
>> Sorry for the late response.. I was busy with life.
>>
>> No, NuttX's crc32 is returning 0x2DFD2D88!
>> My modified code with missing negation returns that 0x340BC6D9 but that is now
>> probably no longer relevant. We should now probably only consider what is the
>> NuttX's crc32 implementation at the moment so its usage would be clear. I
>> dragged there originally my requirement of the algorithm and in the end that got
>> confusing.
>>
>> The parameters that give me same test value from NuttX code as on crc_js.html:
>>
>>   Input reflected: yes
>>   Result reflected: yes
>>   Polynomial: 0x4C11DB7
>>   Initial Value: 0x0
>>   Final Xor Value: 0x0
> 
> snip
> 
>> The NuttX's implementation should be probably something like `crc32_posixlike`
>> as it is not even POSIX compliant implementation due to the input and output not
>> being reflected and output not being negated. Thus possibly `crc32_nuttx`.
> 
> To clarify, you're saying that:
> 
> In POSIX the input and output are NOT reflected and the output is NOT
> negated, and:
That is what http://www.sunshine2k.de/coding/javascript/crc/crc_js.html and 
https://reveng.sourceforge.io/crc-catalogue/all.htm state as POSIX (haven't 
check posix standard for that).

> In NuttX the input and output ARE reflected and the output IS negated?
That is what gives me the same value on crc_js.html as I get from simple code 
run in NuttX application (SAMV7):

  printf("crc: %x\n", crc32("123456789", 9));

Previously I tested the code also on amd64 and MIPS and it gave the same result 
as the code on NuttX (I just took the crc32 calculation code as it is in NuttX 
and dropped it to the very simple C file to test it).

K.K.

Re: CRC32 what gives?

Posted by Nathan Hartman <ha...@gmail.com>.
On Wed, Jul 20, 2022 at 10:24 AM Karel Kočí <cy...@email.cz> wrote:
>
> Sorry for the late response.. I was busy with life.
>
> No, NuttX's crc32 is returning 0x2DFD2D88!
> My modified code with missing negation returns that 0x340BC6D9 but that is now
> probably no longer relevant. We should now probably only consider what is the
> NuttX's crc32 implementation at the moment so its usage would be clear. I
> dragged there originally my requirement of the algorithm and in the end that got
> confusing.
>
> The parameters that give me same test value from NuttX code as on crc_js.html:
>
>   Input reflected: yes
>   Result reflected: yes
>   Polynomial: 0x4C11DB7
>   Initial Value: 0x0
>   Final Xor Value: 0x0

snip

> The NuttX's implementation should be probably something like `crc32_posixlike`
> as it is not even POSIX compliant implementation due to the input and output not
> being reflected and output not being negated. Thus possibly `crc32_nuttx`.

To clarify, you're saying that:

In POSIX the input and output are NOT reflected and the output is NOT
negated, and:

In NuttX the input and output ARE reflected and the output IS negated?

Thanks,
Nathan

Re: CRC32 what gives?

Posted by Karel Kočí <cy...@email.cz>.
Sorry for the late response.. I was busy with life.

Excerpts from Alan Carvalho de Assis's message of July 15, 2022 7:36 pm:
> On 7/15/22, Karel Kočí <cy...@email.cz> wrote:
>> The impact might be pretty significant from my search and that is also why I
>>
>> rather discuss instead of suggesting changes.
>>
>> The significant place where the current crc32 implementation is used is in
>> file systems (such as smartfs or nxffs). The change would break any existing
>>
>> formating of those FSs. Thus I also do not think it should be done.
>>
>> I think that only documentation should be updated to prevent confusion as
>> right
>> now I would consider crc32 using the "non-starndard" (well it is not the ISO
>>
>> one) implementation.
>>
>> (I am now using here terms from that javascript page)
>>
>> Well.. it is not CRC32_JAMCRC. That is just CRC32 but without final "~".
>> The closes to the current crc32 implementation in NuttX seems to be
>> CRC32_POSIX,
>> but with "Input reflected" and "Result reflected" set to true compared to
>> the
>> CRC32_POSIX.
>>
> 
> These are the results:
> CRC32: 0xCBF43926
> CRC32_JAMCRC: 0x340BC6D9
> CRC_POSIX:  0x765E7680
> CRC_POSIX w/ Input and Output Reflected:  0xD202D277
> 
> So, according with your original comment, NuttX is returning
> 0x340BC6D9, correct?
No, NuttX's crc32 is returning 0x2DFD2D88!
My modified code with missing negation returns that 0x340BC6D9 but that is now 
probably no longer relevant. We should now probably only consider what is the 
NuttX's crc32 implementation at the moment so its usage would be clear. I 
dragged there originally my requirement of the algorithm and in the end that got 
confusing.

The parameters that give me same test value from NuttX code as on crc_js.html:

  Input reflected: yes
  Result reflected: yes
  Polynomial: 0x4C11DB7
  Initial Value: 0x0
  Final Xor Value: 0x0

>> I think that just adding these parameters to the documentation of crc32
>> function
>> should be enough.. possibly with warning that this implementation is unique
>> to
>> NuttX and probably should not be used for external communication. What do
>> you
>> think?
>>
> 
> I think we can rename the current crc32() to crc32_jamcrc(), or other
> name we realize is correct to it, and use this name on FS code that
> are using crc32() to avoid the issue.
The NuttX's implementation should be probably something like `crc32_posixlike` 
as it is not even POSIX compliant implementation due to the input and output not 
being reflected and output not being negated. Thus possibly `crc32_nuttx`.

With regards
Karel Kočí

Re: CRC32 what gives?

Posted by Alan Carvalho de Assis <ac...@gmail.com>.
On 7/15/22, Karel Kočí <cy...@email.cz> wrote:
> The impact might be pretty significant from my search and that is also why I
>
> rather discuss instead of suggesting changes.
>
> The significant place where the current crc32 implementation is used is in
> file systems (such as smartfs or nxffs). The change would break any existing
>
> formating of those FSs. Thus I also do not think it should be done.
>
> I think that only documentation should be updated to prevent confusion as
> right
> now I would consider crc32 using the "non-starndard" (well it is not the ISO
>
> one) implementation.
>
> (I am now using here terms from that javascript page)
>
> Well.. it is not CRC32_JAMCRC. That is just CRC32 but without final "~".
> The closes to the current crc32 implementation in NuttX seems to be
> CRC32_POSIX,
> but with "Input reflected" and "Result reflected" set to true compared to
> the
> CRC32_POSIX.
>

These are the results:
CRC32: 0xCBF43926
CRC32_JAMCRC: 0x340BC6D9
CRC_POSIX:  0x765E7680
CRC_POSIX w/ Input and Output Reflected:  0xD202D277

So, according with your original comment, NuttX is returning
0x340BC6D9, correct?

> I think that just adding these parameters to the documentation of crc32
> function
> should be enough.. possibly with warning that this implementation is unique
> to
> NuttX and probably should not be used for external communication. What do
> you
> think?
>

I think we can rename the current crc32() to crc32_jamcrc(), or other
name we realize is correct to it, and use this name on FS code that
are using crc32() to avoid the issue.

BR,

Alan

Re: CRC32 what gives?

Posted by Karel Kočí <cy...@email.cz>.
The impact might be pretty significant from my search and that is also why I 
rather discuss instead of suggesting changes.

The significant place where the current crc32 implementation is used is in 
file systems (such as smartfs or nxffs). The change would break any existing 
formating of those FSs. Thus I also do not think it should be done.

I think that only documentation should be updated to prevent confusion as right 
now I would consider crc32 using the "non-starndard" (well it is not the ISO 
one) implementation.

(I am now using here terms from that javascript page)

Well.. it is not CRC32_JAMCRC. That is just CRC32 but without final "~".
The closes to the current crc32 implementation in NuttX seems to be CRC32_POSIX, 
but with "Input reflected" and "Result reflected" set to true compared to the 
CRC32_POSIX.

I think that just adding these parameters to the documentation of crc32 function 
should be enough.. possibly with warning that this implementation is unique to 
NuttX and probably should not be used for external communication. What do you 
think?

K.K.


Excerpts from Alan Carvalho de Assis's message of July 15, 2022 5:45 pm:
> This site is very good to compare and test CRCs:
> 
> http://www.sunshine2k.de/coding/javascript/crc/crc_js.html
> 
> The result is CRC32_JAMCRC as Karel pointed.
> 
> So, just like CRC-16, there are many CRC-32 implementations.
> 
> Since crc32() function is already used in many places on NuttX I don't
> know the impact of including the bitwise "~" to return the most common
> CRC32 value.
> 
> BR,
> 
> Alan
> 
> On 7/15/22, Karel Kočí <cy...@email.cz> wrote:
>>
>> Excerpts from Nathan Hartman's message of July 15, 2022 2:59 pm:
>>> On Fri, Jul 15, 2022 at 8:10 AM Karel Kočí <cy...@email.cz> wrote:
>>>>
>>>> Hi
>>>>
>>>> I hit an issue with crc32 implementation in NuttX's LibC and it took me
>>>> some
>>>> time to figure out that crc32 is implemented differently in NuttX than I
>>>> was
>>>> expecting. Let me explain...
>>>>
>>>> Common implementations are using same precomputed table as there is in
>>>> the
>>>> NuttX, but the initial value is all ones and not zero as in case of the
>>>> NuttX
>>>> (0xffffffff vs 0x0) and the result is negated while that is not true in
>>>> the
>>>> NuttX.
>>>> In other words the call `crc32(msg, msgsiz)` gives "unexpected" result
>>>> while
>>>> `~crc32part(msg, msgsiz, 0xffffffff)` gives the "correct" one.
>>>>
>>>> I can see the idea behind not performing negation twice (`crc32part`
>>>> would have
>>>> to negate `crc32val` at the start and then return it negated again) but
>>>> using
>>>> the same precomputed table gives then different results.
>>>>
>>>> I am not sure if this weakens the crc32 in some way or just has no side
>>>> effect
>>>> except of not matching with common implementations. Either way this
>>>> discrepancy
>>>> should be at least documented with suggestion to use `~crc32part(msg,
>>>> msgsiz,
>>>> 0xffffffff)`. What do you think?
>>>>
>>>> With regards
>>>> Karel Kočí
>>>
>>>
>>> Hello,
>>>
>>> That is interesting. Which crc32 implementation are you comparing
>>> against? (i.e., what do you mean by "common implementations"?)
>> Well "common" I mean most of the implementations on the Internet (I know
>> that
>> there are load of variations) and used in our project (honestly just taken
>> from the Internet). It also probably matches what for example others present
>> on
>> Wikipedia:
>> https://en.wikipedia.org/wiki/Cyclic_redundancy_check#CRC-32_algorithm
>> I do not think that the one implementation we are using is "the correct one"
>> but
>> it also seemed that NuttX implementation is not well defined either.
>>
>>> The CRC RevEng project at SourceForge [1] helps identify CRC
>>> algorithms. Each algorithm is listed with the value it should output
>>> when input the string "123456789" (as 8-bit characters).
>> That is new for mew. I had no idea that there is such project. Looking into
>> it
>> more in depth I for example looked into which CRC32 variant implements zlib
>> and
>> that one uses CRC-32/ISO-HDLC. It is not hard to find it this way. Thanks
>> for
>> pointing this out.
>>
>>> But, when I run our algorithm as you suggest, with an initial value of
>>> 0xffffffff, I get 0x340bc6d9 which is listed as the "check=" value of
>>> "CRC-32/JAMCRC" [3].
>> You might have missed the binary negation. The difference between those is
>> just
>> a simple negation as it seems. The code `~crc32part("123456789", 9,
>> 0xffffffff)`
>> gives me 0xcbf43926 which matches the ISO-HDLC. Without the negation it
>> gives me
>> the answer you have. It makes sense as the difference is only in the final
>> XOR
>> and xor with zero does nothing while xor with ones simply does negation.
>>
>>> Based on a quick lookup there, it appears to me that the crc32()
>>> implementation in NuttX should be what CRC RevEng calls
>>> "CRC-32/CKSUM": width=32 poly=0x04c11db7 init=0x00000000 refin=false
>>> refout=false xorout=0xffffffff check=0x765e7680 residue=0xc704dd7b
>>> name="CRC-32/CKSUM" [2].
>>>
>>> However, when I run our algorithm against the input string
>>> "123456789", I don't get the value 0x765e7680 as listed above; I get
>>> 0x2dfd2d88, which isn't listed as the "check=" value of any of the
>>> algorithms.
>> So at minimum this should be stated in the function documentation.
>>
>> I also tried to look into why it does not match that CKSUM algorithm but I
>> pretty much failed. I am trying to tweak my own version that does not use
>> table
>> but still I get the invalid value (0xd202d277 which is negation of what you
>> have
>> and because that algorithm specifies xorout with ones that is probably
>> little
>> bit more correct).
>> The only other difference between CKSUM and ISO-HDCL I can see there is in
>> parameters refin and refout. From RevEng website it seems that it specifies
>>
>> endianess for input and output. The refin=false refout=false is stated as
>> big-endian but I am not sure if I should perform calculation in big endian
>> (which would make no difference if implemented correctly) or if only some
>> part
>> should be in that endianess. Just to be sure I also ran the code on Mips
>> (MSB)
>> but that gave me the same result (expected that). Thus I am not sure what
>> those
>> parameters mean in the end.
>>
>> K.K.
>>
> 

Re: CRC32 what gives?

Posted by Alan Carvalho de Assis <ac...@gmail.com>.
This site is very good to compare and test CRCs:

http://www.sunshine2k.de/coding/javascript/crc/crc_js.html

The result is CRC32_JAMCRC as Karel pointed.

So, just like CRC-16, there are many CRC-32 implementations.

Since crc32() function is already used in many places on NuttX I don't
know the impact of including the bitwise "~" to return the most common
CRC32 value.

BR,

Alan

On 7/15/22, Karel Kočí <cy...@email.cz> wrote:
>
> Excerpts from Nathan Hartman's message of July 15, 2022 2:59 pm:
>> On Fri, Jul 15, 2022 at 8:10 AM Karel Kočí <cy...@email.cz> wrote:
>>>
>>> Hi
>>>
>>> I hit an issue with crc32 implementation in NuttX's LibC and it took me
>>> some
>>> time to figure out that crc32 is implemented differently in NuttX than I
>>> was
>>> expecting. Let me explain...
>>>
>>> Common implementations are using same precomputed table as there is in
>>> the
>>> NuttX, but the initial value is all ones and not zero as in case of the
>>> NuttX
>>> (0xffffffff vs 0x0) and the result is negated while that is not true in
>>> the
>>> NuttX.
>>> In other words the call `crc32(msg, msgsiz)` gives "unexpected" result
>>> while
>>> `~crc32part(msg, msgsiz, 0xffffffff)` gives the "correct" one.
>>>
>>> I can see the idea behind not performing negation twice (`crc32part`
>>> would have
>>> to negate `crc32val` at the start and then return it negated again) but
>>> using
>>> the same precomputed table gives then different results.
>>>
>>> I am not sure if this weakens the crc32 in some way or just has no side
>>> effect
>>> except of not matching with common implementations. Either way this
>>> discrepancy
>>> should be at least documented with suggestion to use `~crc32part(msg,
>>> msgsiz,
>>> 0xffffffff)`. What do you think?
>>>
>>> With regards
>>> Karel Kočí
>>
>>
>> Hello,
>>
>> That is interesting. Which crc32 implementation are you comparing
>> against? (i.e., what do you mean by "common implementations"?)
> Well "common" I mean most of the implementations on the Internet (I know
> that
> there are load of variations) and used in our project (honestly just taken
> from the Internet). It also probably matches what for example others present
> on
> Wikipedia:
> https://en.wikipedia.org/wiki/Cyclic_redundancy_check#CRC-32_algorithm
> I do not think that the one implementation we are using is "the correct one"
> but
> it also seemed that NuttX implementation is not well defined either.
>
>> The CRC RevEng project at SourceForge [1] helps identify CRC
>> algorithms. Each algorithm is listed with the value it should output
>> when input the string "123456789" (as 8-bit characters).
> That is new for mew. I had no idea that there is such project. Looking into
> it
> more in depth I for example looked into which CRC32 variant implements zlib
> and
> that one uses CRC-32/ISO-HDLC. It is not hard to find it this way. Thanks
> for
> pointing this out.
>
>> But, when I run our algorithm as you suggest, with an initial value of
>> 0xffffffff, I get 0x340bc6d9 which is listed as the "check=" value of
>> "CRC-32/JAMCRC" [3].
> You might have missed the binary negation. The difference between those is
> just
> a simple negation as it seems. The code `~crc32part("123456789", 9,
> 0xffffffff)`
> gives me 0xcbf43926 which matches the ISO-HDLC. Without the negation it
> gives me
> the answer you have. It makes sense as the difference is only in the final
> XOR
> and xor with zero does nothing while xor with ones simply does negation.
>
>> Based on a quick lookup there, it appears to me that the crc32()
>> implementation in NuttX should be what CRC RevEng calls
>> "CRC-32/CKSUM": width=32 poly=0x04c11db7 init=0x00000000 refin=false
>> refout=false xorout=0xffffffff check=0x765e7680 residue=0xc704dd7b
>> name="CRC-32/CKSUM" [2].
>>
>> However, when I run our algorithm against the input string
>> "123456789", I don't get the value 0x765e7680 as listed above; I get
>> 0x2dfd2d88, which isn't listed as the "check=" value of any of the
>> algorithms.
> So at minimum this should be stated in the function documentation.
>
> I also tried to look into why it does not match that CKSUM algorithm but I
> pretty much failed. I am trying to tweak my own version that does not use
> table
> but still I get the invalid value (0xd202d277 which is negation of what you
> have
> and because that algorithm specifies xorout with ones that is probably
> little
> bit more correct).
> The only other difference between CKSUM and ISO-HDCL I can see there is in
> parameters refin and refout. From RevEng website it seems that it specifies
>
> endianess for input and output. The refin=false refout=false is stated as
> big-endian but I am not sure if I should perform calculation in big endian
> (which would make no difference if implemented correctly) or if only some
> part
> should be in that endianess. Just to be sure I also ran the code on Mips
> (MSB)
> but that gave me the same result (expected that). Thus I am not sure what
> those
> parameters mean in the end.
>
> K.K.
>

Re: CRC32 what gives?

Posted by Karel Kočí <cy...@email.cz>.
Excerpts from Nathan Hartman's message of July 15, 2022 2:59 pm:
> On Fri, Jul 15, 2022 at 8:10 AM Karel Kočí <cy...@email.cz> wrote:
>>
>> Hi
>>
>> I hit an issue with crc32 implementation in NuttX's LibC and it took me some
>> time to figure out that crc32 is implemented differently in NuttX than I was
>> expecting. Let me explain...
>>
>> Common implementations are using same precomputed table as there is in the
>> NuttX, but the initial value is all ones and not zero as in case of the NuttX
>> (0xffffffff vs 0x0) and the result is negated while that is not true in the
>> NuttX.
>> In other words the call `crc32(msg, msgsiz)` gives "unexpected" result while
>> `~crc32part(msg, msgsiz, 0xffffffff)` gives the "correct" one.
>>
>> I can see the idea behind not performing negation twice (`crc32part` would have
>> to negate `crc32val` at the start and then return it negated again) but using
>> the same precomputed table gives then different results.
>>
>> I am not sure if this weakens the crc32 in some way or just has no side effect
>> except of not matching with common implementations. Either way this discrepancy
>> should be at least documented with suggestion to use `~crc32part(msg, msgsiz,
>> 0xffffffff)`. What do you think?
>>
>> With regards
>> Karel Kočí
> 
> 
> Hello,
> 
> That is interesting. Which crc32 implementation are you comparing
> against? (i.e., what do you mean by "common implementations"?)
Well "common" I mean most of the implementations on the Internet (I know that 
there are load of variations) and used in our project (honestly just taken 
from the Internet). It also probably matches what for example others present on 
Wikipedia: 
https://en.wikipedia.org/wiki/Cyclic_redundancy_check#CRC-32_algorithm
I do not think that the one implementation we are using is "the correct one" but 
it also seemed that NuttX implementation is not well defined either.

> The CRC RevEng project at SourceForge [1] helps identify CRC
> algorithms. Each algorithm is listed with the value it should output
> when input the string "123456789" (as 8-bit characters).
That is new for mew. I had no idea that there is such project. Looking into it 
more in depth I for example looked into which CRC32 variant implements zlib and 
that one uses CRC-32/ISO-HDLC. It is not hard to find it this way. Thanks for 
pointing this out.

> But, when I run our algorithm as you suggest, with an initial value of
> 0xffffffff, I get 0x340bc6d9 which is listed as the "check=" value of
> "CRC-32/JAMCRC" [3].
You might have missed the binary negation. The difference between those is just 
a simple negation as it seems. The code `~crc32part("123456789", 9, 0xffffffff)` 
gives me 0xcbf43926 which matches the ISO-HDLC. Without the negation it gives me 
the answer you have. It makes sense as the difference is only in the final XOR 
and xor with zero does nothing while xor with ones simply does negation.

> Based on a quick lookup there, it appears to me that the crc32()
> implementation in NuttX should be what CRC RevEng calls
> "CRC-32/CKSUM": width=32 poly=0x04c11db7 init=0x00000000 refin=false
> refout=false xorout=0xffffffff check=0x765e7680 residue=0xc704dd7b
> name="CRC-32/CKSUM" [2].
> 
> However, when I run our algorithm against the input string
> "123456789", I don't get the value 0x765e7680 as listed above; I get
> 0x2dfd2d88, which isn't listed as the "check=" value of any of the
> algorithms.
So at minimum this should be stated in the function documentation.

I also tried to look into why it does not match that CKSUM algorithm but I 
pretty much failed. I am trying to tweak my own version that does not use table 
but still I get the invalid value (0xd202d277 which is negation of what you have 
and because that algorithm specifies xorout with ones that is probably little 
bit more correct).
The only other difference between CKSUM and ISO-HDCL I can see there is in 
parameters refin and refout. From RevEng website it seems that it specifies 
endianess for input and output. The refin=false refout=false is stated as 
big-endian but I am not sure if I should perform calculation in big endian 
(which would make no difference if implemented correctly) or if only some part 
should be in that endianess. Just to be sure I also ran the code on Mips (MSB) 
but that gave me the same result (expected that). Thus I am not sure what those 
parameters mean in the end.

K.K.

Re: CRC32 what gives?

Posted by Nathan Hartman <ha...@gmail.com>.
On Fri, Jul 15, 2022 at 8:10 AM Karel Kočí <cy...@email.cz> wrote:
>
> Hi
>
> I hit an issue with crc32 implementation in NuttX's LibC and it took me some
> time to figure out that crc32 is implemented differently in NuttX than I was
> expecting. Let me explain...
>
> Common implementations are using same precomputed table as there is in the
> NuttX, but the initial value is all ones and not zero as in case of the NuttX
> (0xffffffff vs 0x0) and the result is negated while that is not true in the
> NuttX.
> In other words the call `crc32(msg, msgsiz)` gives "unexpected" result while
> `~crc32part(msg, msgsiz, 0xffffffff)` gives the "correct" one.
>
> I can see the idea behind not performing negation twice (`crc32part` would have
> to negate `crc32val` at the start and then return it negated again) but using
> the same precomputed table gives then different results.
>
> I am not sure if this weakens the crc32 in some way or just has no side effect
> except of not matching with common implementations. Either way this discrepancy
> should be at least documented with suggestion to use `~crc32part(msg, msgsiz,
> 0xffffffff)`. What do you think?
>
> With regards
> Karel Kočí


Hello,

That is interesting. Which crc32 implementation are you comparing
against? (i.e., what do you mean by "common implementations"?)

The CRC RevEng project at SourceForge [1] helps identify CRC
algorithms. Each algorithm is listed with the value it should output
when input the string "123456789" (as 8-bit characters).

Based on a quick lookup there, it appears to me that the crc32()
implementation in NuttX should be what CRC RevEng calls
"CRC-32/CKSUM": width=32 poly=0x04c11db7 init=0x00000000 refin=false
refout=false xorout=0xffffffff check=0x765e7680 residue=0xc704dd7b
name="CRC-32/CKSUM" [2].

However, when I run our algorithm against the input string
"123456789", I don't get the value 0x765e7680 as listed above; I get
0x2dfd2d88, which isn't listed as the "check=" value of any of the
algorithms.

But, when I run our algorithm as you suggest, with an initial value of
0xffffffff, I get 0x340bc6d9 which is listed as the "check=" value of
"CRC-32/JAMCRC" [3].

Anyway, please let us know which implementation(s) you're comparing against...

References:

[1] CRC RevEng project: https://reveng.sourceforge.io

[2] Search for CRC-32/CKSUM on page:
https://reveng.sourceforge.io/crc-catalogue/17plus.htm#crc.cat-bits.32

[3] Search for CRC-32/JAMCRC on page:
https://reveng.sourceforge.io/crc-catalogue/17plus.htm#crc.cat-bits.32

Cheers,
Nathan