xref: /aosp_15_r20/external/xz-embedded/linux/lib/xz/xz_crc32.c (revision d2c16535d139cb185e89120452531bba6b36d3c6)
1*d2c16535SElliott Hughes // SPDX-License-Identifier: 0BSD
2*d2c16535SElliott Hughes 
3*d2c16535SElliott Hughes /*
4*d2c16535SElliott Hughes  * CRC32 using the polynomial from IEEE-802.3
5*d2c16535SElliott Hughes  *
6*d2c16535SElliott Hughes  * Authors: Lasse Collin <[email protected]>
7*d2c16535SElliott Hughes  *          Igor Pavlov <https://7-zip.org/>
8*d2c16535SElliott Hughes  */
9*d2c16535SElliott Hughes 
10*d2c16535SElliott Hughes /*
11*d2c16535SElliott Hughes  * This is not the fastest implementation, but it is pretty compact.
12*d2c16535SElliott Hughes  * The fastest versions of xz_crc32() on modern CPUs without hardware
13*d2c16535SElliott Hughes  * accelerated CRC instruction are 3-5 times as fast as this version,
14*d2c16535SElliott Hughes  * but they are bigger and use more memory for the lookup table.
15*d2c16535SElliott Hughes  */
16*d2c16535SElliott Hughes 
17*d2c16535SElliott Hughes #include "xz_private.h"
18*d2c16535SElliott Hughes 
19*d2c16535SElliott Hughes /*
20*d2c16535SElliott Hughes  * STATIC_RW_DATA is used in the pre-boot environment on some architectures.
21*d2c16535SElliott Hughes  * See <linux/decompress/mm.h> for details.
22*d2c16535SElliott Hughes  */
23*d2c16535SElliott Hughes #ifndef STATIC_RW_DATA
24*d2c16535SElliott Hughes #	define STATIC_RW_DATA static
25*d2c16535SElliott Hughes #endif
26*d2c16535SElliott Hughes 
27*d2c16535SElliott Hughes STATIC_RW_DATA uint32_t xz_crc32_table[256];
28*d2c16535SElliott Hughes 
xz_crc32_init(void)29*d2c16535SElliott Hughes XZ_EXTERN void xz_crc32_init(void)
30*d2c16535SElliott Hughes {
31*d2c16535SElliott Hughes 	const uint32_t poly = 0xEDB88320;
32*d2c16535SElliott Hughes 
33*d2c16535SElliott Hughes 	uint32_t i;
34*d2c16535SElliott Hughes 	uint32_t j;
35*d2c16535SElliott Hughes 	uint32_t r;
36*d2c16535SElliott Hughes 
37*d2c16535SElliott Hughes 	for (i = 0; i < 256; ++i) {
38*d2c16535SElliott Hughes 		r = i;
39*d2c16535SElliott Hughes 		for (j = 0; j < 8; ++j)
40*d2c16535SElliott Hughes 			r = (r >> 1) ^ (poly & ~((r & 1) - 1));
41*d2c16535SElliott Hughes 
42*d2c16535SElliott Hughes 		xz_crc32_table[i] = r;
43*d2c16535SElliott Hughes 	}
44*d2c16535SElliott Hughes 
45*d2c16535SElliott Hughes 	return;
46*d2c16535SElliott Hughes }
47*d2c16535SElliott Hughes 
xz_crc32(const uint8_t * buf,size_t size,uint32_t crc)48*d2c16535SElliott Hughes XZ_EXTERN uint32_t xz_crc32(const uint8_t *buf, size_t size, uint32_t crc)
49*d2c16535SElliott Hughes {
50*d2c16535SElliott Hughes 	crc = ~crc;
51*d2c16535SElliott Hughes 
52*d2c16535SElliott Hughes 	while (size != 0) {
53*d2c16535SElliott Hughes 		crc = xz_crc32_table[*buf++ ^ (crc & 0xFF)] ^ (crc >> 8);
54*d2c16535SElliott Hughes 		--size;
55*d2c16535SElliott Hughes 	}
56*d2c16535SElliott Hughes 
57*d2c16535SElliott Hughes 	return ~crc;
58*d2c16535SElliott Hughes }
59