15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* crc32.c -- compute the CRC-32 of a data stream
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright (C) 1995-2006, 2010 Mark Adler
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * For conditions of distribution and use, see copyright notice in zlib.h
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * tables for updating the shift register in one step with three exclusive-ors
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * instead of four steps with four exclusive-ors.  This results in about a
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* @(#) $Id$ */
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  protection on the static variables used to control the first-use generation
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  of the crc tables.  Therefore, if you #define DYNAMIC_CRC_TABLE, you should
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  first call get_crc_table() to initialize the tables before allowing more than
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  one thread to use crc32().
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef MAKECRCH
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  include <stdio.h>
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  ifndef DYNAMIC_CRC_TABLE
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#    define DYNAMIC_CRC_TABLE
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  endif /* !DYNAMIC_CRC_TABLE */
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* MAKECRCH */
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "zutil.h"      /* for STDC and FAR definitions */
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define local static
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Find a four-byte integer type for crc32_little() and crc32_big(). */
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NOBYFOUR
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  ifdef STDC           /* need ANSI C limits.h to determine sizes */
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#    include <limits.h>
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#    define BYFOUR
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#    if (UINT_MAX == 0xffffffffUL)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       typedef unsigned int u4;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#    else
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#      if (ULONG_MAX == 0xffffffffUL)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         typedef unsigned long u4;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#      else
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#        if (USHRT_MAX == 0xffffffffUL)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           typedef unsigned short u4;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#        else
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#          undef BYFOUR     /* can't find a four-byte integer type! */
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#        endif
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#      endif
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#    endif
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  endif /* STDC */
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* !NOBYFOUR */
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Definitions for doing the crc four data bytes at a time. */
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef BYFOUR
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define REV(w) ((((w)>>24)&0xff)+(((w)>>8)&0xff00)+ \
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                (((w)&0xff00)<<8)+(((w)&0xff)<<24))
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   local unsigned long crc32_little OF((unsigned long,
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        const unsigned char FAR *, unsigned));
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   local unsigned long crc32_big OF((unsigned long,
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        const unsigned char FAR *, unsigned));
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define TBLS 8
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  define TBLS 1
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* BYFOUR */
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Local functions for crc concatenation */
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)local unsigned long gf2_matrix_times OF((unsigned long *mat,
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         unsigned long vec));
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)local uLong crc32_combine_(uLong crc1, uLong crc2, z_off64_t len2);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DYNAMIC_CRC_TABLE
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)local volatile int crc_table_empty = 1;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)local unsigned long FAR crc_table[TBLS][256];
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)local void make_crc_table OF((void));
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef MAKECRCH
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   local void write_table OF((FILE *, const unsigned long FAR *));
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* MAKECRCH */
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Polynomials over GF(2) are represented in binary, one bit per coefficient,
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  with the lowest powers in the most significant bit.  Then adding polynomials
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  is just exclusive-or, and multiplying a polynomial by x is a right shift by
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  one.  If we call the above polynomial p, and represent a byte as the
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  polynomial q, also with the lowest power in the most significant bit (so the
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  where a mod b means the remainder after dividing a by b.
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  This calculation is done using the shift-register method of multiplying and
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  taking the remainder.  The register is initialized to zero, and for each
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  incoming bit, x^32 is added mod p to the register if the bit is a one (where
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  x (which is shifting right by one and adding x^32 mod p if the bit shifted
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  out is a one).  We start with the highest power (least significant bit) of
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  q and repeat for all eight bits of q.
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  The first table is simply the CRC of all possible eight bit values.  This is
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  all the information needed to generate CRCs on data a byte at a time for all
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  combinations of CRC register values and incoming bytes.  The remaining tables
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  allow for word-at-a-time CRC calculation for both big-endian and little-
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  endian machines, where a word is four bytes.
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)local void make_crc_table()
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned long c;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int n, k;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned long poly;                 /* polynomial exclusive-or pattern */
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* terms of polynomial defining this crc (except x^32): */
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    static volatile int first = 1;      /* flag to limit concurrent making */
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* See if another task is already doing this (not thread-safe, but better
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       than nothing -- significantly reduces duration of vulnerability in
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       case the advice about DYNAMIC_CRC_TABLE is ignored) */
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (first) {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        first = 0;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* make exclusive-or pattern from polynomial (0xedb88320UL) */
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        poly = 0UL;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            poly |= 1UL << (31 - p[n]);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* generate a crc for every 8-bit value */
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for (n = 0; n < 256; n++) {
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            c = (unsigned long)n;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            for (k = 0; k < 8; k++)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                c = c & 1 ? poly ^ (c >> 1) : c >> 1;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            crc_table[0][n] = c;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef BYFOUR
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* generate crc for each value followed by one, two, and three zeros,
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           and then the byte reversal of those as well as the first table */
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for (n = 0; n < 256; n++) {
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            c = crc_table[0][n];
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            crc_table[4][n] = REV(c);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            for (k = 1; k < 4; k++) {
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                c = crc_table[0][c & 0xff] ^ (c >> 8);
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                crc_table[k][n] = c;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                crc_table[k + 4][n] = REV(c);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* BYFOUR */
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        crc_table_empty = 0;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else {      /* not first */
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* wait for the other guy to finish (not efficient, but rare) */
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        while (crc_table_empty)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef MAKECRCH
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* write out CRC tables to crc32.h */
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FILE *out;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        out = fopen("crc32.h", "w");
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (out == NULL) return;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        fprintf(out, "local const unsigned long FAR ");
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        fprintf(out, "crc_table[TBLS][256] =\n{\n  {\n");
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        write_table(out, crc_table[0]);
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  ifdef BYFOUR
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        fprintf(out, "#ifdef BYFOUR\n");
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for (k = 1; k < 8; k++) {
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fprintf(out, "  },\n  {\n");
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            write_table(out, crc_table[k]);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        fprintf(out, "#endif\n");
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#  endif /* BYFOUR */
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        fprintf(out, "  }\n};\n");
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        fclose(out);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* MAKECRCH */
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef MAKECRCH
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)local void write_table(out, table)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FILE *out;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned long FAR *table;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int n;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (n = 0; n < 256; n++)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : "    ", table[n],
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* MAKECRCH */
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else /* !DYNAMIC_CRC_TABLE */
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* ========================================================================
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Tables of CRC-32s of all single-byte values, made by make_crc_table().
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "crc32.h"
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* DYNAMIC_CRC_TABLE */
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* =========================================================================
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This function can be used by asm versions of crc32()
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const unsigned long FAR * ZEXPORT get_crc_table()
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DYNAMIC_CRC_TABLE
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (crc_table_empty)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        make_crc_table();
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* DYNAMIC_CRC_TABLE */
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return (const unsigned long FAR *)crc_table;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* ========================================================================= */
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* ========================================================================= */
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)unsigned long ZEXPORT crc32(crc, buf, len)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned long crc;
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned char FAR *buf;
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uInt len;
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (buf == Z_NULL) return 0UL;
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DYNAMIC_CRC_TABLE
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (crc_table_empty)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        make_crc_table();
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* DYNAMIC_CRC_TABLE */
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef BYFOUR
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sizeof(void *) == sizeof(ptrdiff_t)) {
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        u4 endian;
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        endian = 1;
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (*((unsigned char *)(&endian)))
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return crc32_little(crc, buf, len);
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        else
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return crc32_big(crc, buf, len);
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* BYFOUR */
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    crc = crc ^ 0xffffffffUL;
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (len >= 8) {
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DO8;
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        len -= 8;
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (len) do {
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DO1;
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } while (--len);
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return crc ^ 0xffffffffUL;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef BYFOUR
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* ========================================================================= */
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DOLIT4 c ^= *buf4++; \
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* ========================================================================= */
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)local unsigned long crc32_little(crc, buf, len)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned long crc;
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned char FAR *buf;
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned len;
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    register u4 c;
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    register const u4 FAR *buf4;
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    c = (u4)crc;
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    c = ~c;
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (len && ((ptrdiff_t)buf & 3)) {
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        len--;
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buf4 = (const u4 FAR *)(const void FAR *)buf;
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (len >= 32) {
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DOLIT32;
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        len -= 32;
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (len >= 4) {
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DOLIT4;
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        len -= 4;
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buf = (const unsigned char FAR *)buf4;
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (len) do {
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } while (--len);
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    c = ~c;
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return (unsigned long)c;
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* ========================================================================= */
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DOBIG4 c ^= *++buf4; \
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* ========================================================================= */
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)local unsigned long crc32_big(crc, buf, len)
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned long crc;
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned char FAR *buf;
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned len;
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    register u4 c;
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    register const u4 FAR *buf4;
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    c = REV((u4)crc);
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    c = ~c;
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (len && ((ptrdiff_t)buf & 3)) {
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        len--;
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buf4 = (const u4 FAR *)(const void FAR *)buf;
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buf4--;
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (len >= 32) {
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DOBIG32;
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        len -= 32;
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (len >= 4) {
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DOBIG4;
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        len -= 4;
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buf4++;
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buf = (const unsigned char FAR *)buf4;
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (len) do {
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } while (--len);
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    c = ~c;
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return (unsigned long)(REV(c));
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* BYFOUR */
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GF2_DIM 32      /* dimension of GF(2) vectors (length of CRC) */
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* ========================================================================= */
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)local unsigned long gf2_matrix_times(mat, vec)
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned long *mat;
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned long vec;
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned long sum;
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sum = 0;
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (vec) {
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (vec & 1)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            sum ^= *mat;
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        vec >>= 1;
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mat++;
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return sum;
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* ========================================================================= */
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)local void gf2_matrix_square(square, mat)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned long *square;
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned long *mat;
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int n;
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (n = 0; n < GF2_DIM; n++)
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        square[n] = gf2_matrix_times(mat, mat[n]);
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* ========================================================================= */
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)local uLong crc32_combine_(crc1, crc2, len2)
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uLong crc1;
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uLong crc2;
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    z_off64_t len2;
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int n;
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned long row;
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned long even[GF2_DIM];    /* even-power-of-two zeros operator */
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned long odd[GF2_DIM];     /* odd-power-of-two zeros operator */
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* degenerate case (also disallow negative lengths) */
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (len2 <= 0)
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return crc1;
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* put operator for one zero bit in odd */
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    odd[0] = 0xedb88320UL;          /* CRC-32 polynomial */
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    row = 1;
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (n = 1; n < GF2_DIM; n++) {
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        odd[n] = row;
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        row <<= 1;
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* put operator for two zero bits in even */
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gf2_matrix_square(even, odd);
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* put operator for four zero bits in odd */
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gf2_matrix_square(odd, even);
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* apply len2 zeros to crc1 (first square will put the operator for one
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       zero byte, eight zero bits, in even) */
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    do {
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* apply zeros operator for this bit of len2 */
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        gf2_matrix_square(even, odd);
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (len2 & 1)
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            crc1 = gf2_matrix_times(even, crc1);
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        len2 >>= 1;
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* if no more bits set, then done */
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (len2 == 0)
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            break;
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* another iteration of the loop with odd and even swapped */
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        gf2_matrix_square(odd, even);
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (len2 & 1)
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            crc1 = gf2_matrix_times(odd, crc1);
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        len2 >>= 1;
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* if no more bits set, then done */
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } while (len2 != 0);
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* return combined crc */
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    crc1 ^= crc2;
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return crc1;
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* ========================================================================= */
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uLong ZEXPORT crc32_combine(crc1, crc2, len2)
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uLong crc1;
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uLong crc2;
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    z_off_t len2;
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return crc32_combine_(crc1, crc2, len2);
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uLong ZEXPORT crc32_combine64(crc1, crc2, len2)
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uLong crc1;
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uLong crc2;
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    z_off64_t len2;
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return crc32_combine_(crc1, crc2, len2);
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
443