adler32.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
  2. /* SPDX-License-Identifier: Unlicense */
  3. #include "tomcrypt_private.h"
  4. /**
  5. @file adler32.c
  6. Adler-32 checksum algorithm
  7. Written and placed in the public domain by Wei Dai
  8. Adapted for libtomcrypt by Steffen Jaeckel
  9. */
  10. #ifdef LTC_ADLER32
  11. static const unsigned long s_adler32_base = 65521;
  12. void adler32_init(adler32_state *ctx)
  13. {
  14. LTC_ARGCHKVD(ctx != NULL);
  15. ctx->s[0] = 1;
  16. ctx->s[1] = 0;
  17. }
  18. void adler32_update(adler32_state *ctx, const unsigned char *input, unsigned long length)
  19. {
  20. unsigned long s1, s2;
  21. LTC_ARGCHKVD(ctx != NULL);
  22. LTC_ARGCHKVD(input != NULL);
  23. s1 = ctx->s[0];
  24. s2 = ctx->s[1];
  25. if (length % 8 != 0) {
  26. do {
  27. s1 += *input++;
  28. s2 += s1;
  29. length--;
  30. } while (length % 8 != 0);
  31. if (s1 >= s_adler32_base) {
  32. s1 -= s_adler32_base;
  33. }
  34. s2 %= s_adler32_base;
  35. }
  36. while (length > 0) {
  37. s1 += input[0];
  38. s2 += s1;
  39. s1 += input[1];
  40. s2 += s1;
  41. s1 += input[2];
  42. s2 += s1;
  43. s1 += input[3];
  44. s2 += s1;
  45. s1 += input[4];
  46. s2 += s1;
  47. s1 += input[5];
  48. s2 += s1;
  49. s1 += input[6];
  50. s2 += s1;
  51. s1 += input[7];
  52. s2 += s1;
  53. length -= 8;
  54. input += 8;
  55. if (s1 >= s_adler32_base) {
  56. s1 -= s_adler32_base;
  57. }
  58. s2 %= s_adler32_base;
  59. }
  60. LTC_ARGCHKVD(s1 < s_adler32_base);
  61. LTC_ARGCHKVD(s2 < s_adler32_base);
  62. ctx->s[0] = (unsigned short)s1;
  63. ctx->s[1] = (unsigned short)s2;
  64. }
  65. void adler32_finish(const adler32_state *ctx, void *hash, unsigned long size)
  66. {
  67. unsigned char* h;
  68. LTC_ARGCHKVD(ctx != NULL);
  69. LTC_ARGCHKVD(hash != NULL);
  70. h = hash;
  71. switch (size) {
  72. default:
  73. h[3] = ctx->s[0] & 0x0ff;
  74. /* FALLTHROUGH */
  75. case 3:
  76. h[2] = (ctx->s[0] >> 8) & 0x0ff;
  77. /* FALLTHROUGH */
  78. case 2:
  79. h[1] = ctx->s[1] & 0x0ff;
  80. /* FALLTHROUGH */
  81. case 1:
  82. h[0] = (ctx->s[1] >> 8) & 0x0ff;
  83. /* FALLTHROUGH */
  84. case 0:
  85. ;
  86. }
  87. }
  88. int adler32_test(void)
  89. {
  90. #ifndef LTC_TEST
  91. return CRYPT_NOP;
  92. #else
  93. const void* in = "libtomcrypt";
  94. const unsigned char adler32[] = { 0x1b, 0xe8, 0x04, 0xba };
  95. unsigned char out[4];
  96. adler32_state ctx;
  97. adler32_init(&ctx);
  98. adler32_update(&ctx, in, XSTRLEN(in));
  99. adler32_finish(&ctx, out, 4);
  100. if (ltc_compare_testvector(adler32, 4, out, 4, "adler32", 0)) {
  101. return CRYPT_FAIL_TESTVECTOR;
  102. }
  103. return CRYPT_OK;
  104. #endif
  105. }
  106. #endif