]> pd.if.org Git - zpackage/blob - libtomcrypt/src/misc/adler32.c
commit files needed for zpm-fetchurl
[zpackage] / libtomcrypt / src / misc / adler32.c
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
2  *
3  * LibTomCrypt is a library that provides various cryptographic
4  * algorithms in a highly modular and flexible manner.
5  *
6  * The library is free for all purposes without any express
7  * guarantee it works.
8  */
9 #include "tomcrypt.h"
10
11 /**
12    @file adler32.c
13    Adler-32 checksum algorithm
14    Written and placed in the public domain by Wei Dai
15    Adapted for libtomcrypt by Steffen Jaeckel
16 */
17 #ifdef LTC_ADLER32
18
19 static const unsigned long _adler32_base = 65521;
20
21 void adler32_init(adler32_state *ctx)
22 {
23    LTC_ARGCHKVD(ctx != NULL);
24    ctx->s[0] = 1;
25    ctx->s[1] = 0;
26 }
27
28 void adler32_update(adler32_state *ctx, const unsigned char *input, unsigned long length)
29 {
30    unsigned long s1, s2;
31
32    LTC_ARGCHKVD(ctx != NULL);
33    LTC_ARGCHKVD(input != NULL);
34    s1 = ctx->s[0];
35    s2 = ctx->s[1];
36
37    if (length % 8 != 0) {
38       do {
39          s1 += *input++;
40          s2 += s1;
41          length--;
42       } while (length % 8 != 0);
43
44       if (s1 >= _adler32_base)
45          s1 -= _adler32_base;
46       s2 %= _adler32_base;
47    }
48
49    while (length > 0) {
50       s1 += input[0];
51       s2 += s1;
52       s1 += input[1];
53       s2 += s1;
54       s1 += input[2];
55       s2 += s1;
56       s1 += input[3];
57       s2 += s1;
58       s1 += input[4];
59       s2 += s1;
60       s1 += input[5];
61       s2 += s1;
62       s1 += input[6];
63       s2 += s1;
64       s1 += input[7];
65       s2 += s1;
66
67       length -= 8;
68       input += 8;
69
70       if (s1 >= _adler32_base)
71          s1 -= _adler32_base;
72       s2 %= _adler32_base;
73    }
74
75    LTC_ARGCHKVD(s1 < _adler32_base);
76    LTC_ARGCHKVD(s2 < _adler32_base);
77
78    ctx->s[0] = (unsigned short)s1;
79    ctx->s[1] = (unsigned short)s2;
80 }
81
82 void adler32_finish(adler32_state *ctx, void *hash, unsigned long size)
83 {
84    unsigned char* h;
85
86    LTC_ARGCHKVD(ctx != NULL);
87    LTC_ARGCHKVD(hash != NULL);
88
89    h = hash;
90
91    switch (size) {
92       default:
93          h[3] = ctx->s[0] & 0x0ff;
94          /* FALLTHROUGH */
95       case 3:
96          h[2] = (ctx->s[0] >> 8) & 0x0ff;
97          /* FALLTHROUGH */
98       case 2:
99          h[1] = ctx->s[1] & 0x0ff;
100          /* FALLTHROUGH */
101       case 1:
102          h[0] = (ctx->s[1] >> 8) & 0x0ff;
103          /* FALLTHROUGH */
104       case 0:
105          ;
106    }
107 }
108
109 int adler32_test(void)
110 {
111 #ifndef LTC_TEST
112    return CRYPT_NOP;
113 #else
114    const void* in = "libtomcrypt";
115    const unsigned char adler32[] = { 0x1b, 0xe8, 0x04, 0xba };
116    unsigned char out[4];
117    adler32_state ctx;
118    adler32_init(&ctx);
119    adler32_update(&ctx, in, strlen(in));
120    adler32_finish(&ctx, out, 4);
121    if (compare_testvector(adler32, 4, out, 4, "adler32", 0)) {
122       return CRYPT_FAIL_TESTVECTOR;
123    }
124    return CRYPT_OK;
125 #endif
126 }
127 #endif
128
129 /* ref:         $Format:%D$ */
130 /* git commit:  $Format:%H$ */
131 /* commit time: $Format:%ai$ */