Use multiple sum algorithm from zlib for Adler and Fletcher checksums.

This commit is contained in:
2021-09-22 23:49:32 +01:00
parent 186f57d7cb
commit bf1b026a7e
6 changed files with 409 additions and 38 deletions

View File

@@ -38,15 +38,138 @@ AARU_EXPORT fletcher32_ctx* AARU_CALL fletcher32_init()
AARU_EXPORT int AARU_CALL fletcher32_update(fletcher32_ctx* ctx, const uint8_t* data, uint32_t len)
{
uint32_t i;
if(!ctx || !data) return -1;
for(i = 0; i < len; i++)
uint32_t sum1 = ctx->sum1;
uint32_t sum2 = ctx->sum2;
unsigned n;
/* in case user likes doing a byte at a time, keep it fast */
if(len == 1)
{
ctx->sum1 = (ctx->sum1 + data[i]) % FLETCHER32_MODULE;
ctx->sum2 = (ctx->sum2 + ctx->sum1) % FLETCHER32_MODULE;
sum1 += data[0];
if(sum1 >= FLETCHER32_MODULE) sum1 -= FLETCHER32_MODULE;
sum2 += sum1;
if(sum2 >= FLETCHER32_MODULE) sum2 -= FLETCHER32_MODULE;
ctx->sum1 = sum1 & 0xFFFF;
ctx->sum2 = sum2 & 0xFFFF;
return 0;
}
/* in case short lengths are provided, keep it somewhat fast */
if(len < 16)
{
while(len--)
{
sum1 += *data++;
sum2 += sum1;
}
if(sum1 >= FLETCHER32_MODULE) sum1 -= FLETCHER32_MODULE;
sum2 %= FLETCHER32_MODULE; /* only added so many FLETCHER32_MODULE's */
ctx->sum1 = sum1 & 0xFFFF;
ctx->sum2 = sum2 & 0xFFFF;
return 0;
}
/* do length NMAX blocks -- requires just one modulo operation */
while(len >= NMAX)
{
len -= NMAX;
n = NMAX / 16; /* NMAX is divisible by 16 */
do {
sum1 += (data)[0];
sum2 += sum1;
sum1 += (data)[0 + 1];
sum2 += sum1;
sum1 += (data)[0 + 2];
sum2 += sum1;
sum1 += (data)[0 + 2 + 1];
sum2 += sum1;
sum1 += (data)[0 + 4];
sum2 += sum1;
sum1 += (data)[0 + 4 + 1];
sum2 += sum1;
sum1 += (data)[0 + 4 + 2];
sum2 += sum1;
sum1 += (data)[0 + 4 + 2 + 1];
sum2 += sum1;
sum1 += (data)[8];
sum2 += sum1;
sum1 += (data)[8 + 1];
sum2 += sum1;
sum1 += (data)[8 + 2];
sum2 += sum1;
sum1 += (data)[8 + 2 + 1];
sum2 += sum1;
sum1 += (data)[8 + 4];
sum2 += sum1;
sum1 += (data)[8 + 4 + 1];
sum2 += sum1;
sum1 += (data)[8 + 4 + 2];
sum2 += sum1;
sum1 += (data)[8 + 4 + 2 + 1];
sum2 += sum1;
/* 16 sums unrolled */
data += 16;
} while(--n);
sum1 %= FLETCHER32_MODULE;
sum2 %= FLETCHER32_MODULE;
}
/* do remaining bytes (less than NMAX, still just one modulo) */
if(len)
{ /* avoid modulos if none remaining */
while(len >= 16)
{
len -= 16;
sum1 += (data)[0];
sum2 += sum1;
sum1 += (data)[0 + 1];
sum2 += sum1;
sum1 += (data)[0 + 2];
sum2 += sum1;
sum1 += (data)[0 + 2 + 1];
sum2 += sum1;
sum1 += (data)[0 + 4];
sum2 += sum1;
sum1 += (data)[0 + 4 + 1];
sum2 += sum1;
sum1 += (data)[0 + 4 + 2];
sum2 += sum1;
sum1 += (data)[0 + 4 + 2 + 1];
sum2 += sum1;
sum1 += (data)[8];
sum2 += sum1;
sum1 += (data)[8 + 1];
sum2 += sum1;
sum1 += (data)[8 + 2];
sum2 += sum1;
sum1 += (data)[8 + 2 + 1];
sum2 += sum1;
sum1 += (data)[8 + 4];
sum2 += sum1;
sum1 += (data)[8 + 4 + 1];
sum2 += sum1;
sum1 += (data)[8 + 4 + 2];
sum2 += sum1;
sum1 += (data)[8 + 4 + 2 + 1];
sum2 += sum1;
data += 16;
}
while(len--)
{
sum1 += *data++;
sum2 += sum1;
}
sum1 %= FLETCHER32_MODULE;
sum2 %= FLETCHER32_MODULE;
}
ctx->sum1 = sum1 & 0xFFFF;
ctx->sum2 = sum2 & 0xFFFF;
return 0;
}