1/* adler32.c -- compute the Adler-32 checksum of a data stream
2 * Copyright (C) 1995-2011, 2016 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */
5
6#include "zutil.h"
7
8#define BASE 65521U     /* largest prime smaller than 65536 */
9#define NMAX 5552
10/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
11
12#define DO1(buf,i)  {adler += (buf)[i]; sum2 += adler;}
13#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
14#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
15#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
16#define DO16(buf)   DO8(buf,0); DO8(buf,8);
17
18/* use NO_DIVIDE if your processor does not do division in hardware --
19   try it both ways to see which is faster */
20#ifdef NO_DIVIDE
21/* note that this assumes BASE is 65521, where 65536 % 65521 == 15
22   (thank you to John Reiser for pointing this out) */
23#  define CHOP(a) \
24    do { \
25        unsigned long tmp = a >> 16; \
26        a &= 0xffffUL; \
27        a += (tmp << 4) - tmp; \
28    } while (0)
29#  define MOD28(a) \
30    do { \
31        CHOP(a); \
32        if (a >= BASE) a -= BASE; \
33    } while (0)
34#  define MOD(a) \
35    do { \
36        CHOP(a); \
37        MOD28(a); \
38    } while (0)
39#  define MOD63(a) \
40    do { /* this assumes a is not negative */ \
41        z_off64_t tmp = a >> 32; \
42        a &= 0xffffffffL; \
43        a += (tmp << 8) - (tmp << 5) + tmp; \
44        tmp = a >> 16; \
45        a &= 0xffffL; \
46        a += (tmp << 4) - tmp; \
47        tmp = a >> 16; \
48        a &= 0xffffL; \
49        a += (tmp << 4) - tmp; \
50        if (a >= BASE) a -= BASE; \
51    } while (0)
52#else
53#  define MOD(a) a %= BASE
54#  define MOD28(a) a %= BASE
55#  define MOD63(a) a %= BASE
56#endif
57
58/* ========================================================================= */
59uLong ZEXPORT adler32_z(uLong adler, const Bytef *buf, z_size_t len) {
60    unsigned long sum2;
61    unsigned n;
62
63    /* split Adler-32 into component sums */
64    sum2 = (adler >> 16) & 0xffff;
65    adler &= 0xffff;
66
67    /* in case user likes doing a byte at a time, keep it fast */
68    if (len == 1) {
69        adler += buf[0];
70        if (adler >= BASE)
71            adler -= BASE;
72        sum2 += adler;
73        if (sum2 >= BASE)
74            sum2 -= BASE;
75        return adler | (sum2 << 16);
76    }
77
78    /* initial Adler-32 value (deferred check for len == 1 speed) */
79    if (buf == Z_NULL)
80        return 1L;
81
82    /* in case short lengths are provided, keep it somewhat fast */
83    if (len < 16) {
84        while (len--) {
85            adler += *buf++;
86            sum2 += adler;
87        }
88        if (adler >= BASE)
89            adler -= BASE;
90        MOD28(sum2);            /* only added so many BASE's */
91        return adler | (sum2 << 16);
92    }
93
94    /* do length NMAX blocks -- requires just one modulo operation */
95    while (len >= NMAX) {
96        len -= NMAX;
97        n = NMAX / 16;          /* NMAX is divisible by 16 */
98        do {
99            DO16(buf);          /* 16 sums unrolled */
100            buf += 16;
101        } while (--n);
102        MOD(adler);
103        MOD(sum2);
104    }
105
106    /* do remaining bytes (less than NMAX, still just one modulo) */
107    if (len) {                  /* avoid modulos if none remaining */
108        while (len >= 16) {
109            len -= 16;
110            DO16(buf);
111            buf += 16;
112        }
113        while (len--) {
114            adler += *buf++;
115            sum2 += adler;
116        }
117        MOD(adler);
118        MOD(sum2);
119    }
120
121    /* return recombined sums */
122    return adler | (sum2 << 16);
123}
124
125/* ========================================================================= */
126uLong ZEXPORT adler32(uLong adler, const Bytef *buf, uInt len) {
127    return adler32_z(adler, buf, len);
128}
129
130/* ========================================================================= */
131local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2) {
132    unsigned long sum1;
133    unsigned long sum2;
134    unsigned rem;
135
136    /* for negative len, return invalid adler32 as a clue for debugging */
137    if (len2 < 0)
138        return 0xffffffffUL;
139
140    /* the derivation of this formula is left as an exercise for the reader */
141    MOD63(len2);                /* assumes len2 >= 0 */
142    rem = (unsigned)len2;
143    sum1 = adler1 & 0xffff;
144    sum2 = rem * sum1;
145    MOD(sum2);
146    sum1 += (adler2 & 0xffff) + BASE - 1;
147    sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
148    if (sum1 >= BASE) sum1 -= BASE;
149    if (sum1 >= BASE) sum1 -= BASE;
150    if (sum2 >= ((unsigned long)BASE << 1)) sum2 -= ((unsigned long)BASE << 1);
151    if (sum2 >= BASE) sum2 -= BASE;
152    return sum1 | (sum2 << 16);
153}
154
155/* ========================================================================= */
156uLong ZEXPORT adler32_combine(uLong adler1, uLong adler2, z_off_t len2) {
157    return adler32_combine_(adler1, adler2, len2);
158}
159
160uLong ZEXPORT adler32_combine64(uLong adler1, uLong adler2, z_off64_t len2) {
161    return adler32_combine_(adler1, adler2, len2);
162}
163