catcrypt.c, catsign.c: Shorten chunk sizes.
[u/mdw/catacomb] / hash.h
diff --git a/hash.h b/hash.h
index 5d43bfb..c2c10d0 100644 (file)
--- a/hash.h
+++ b/hash.h
@@ -1,13 +1,13 @@
 /* -*-c-*-
  *
- * $Id: hash.h,v 1.1 1999/09/03 08:41:12 mdw Exp $
+ * $Id$
  *
  * Generic handling for message digest functions
  *
  * (c) 1998 Straylight/Edgeware
  */
 
-/*----- Licensing notice --------------------------------------------------* 
+/*----- Licensing notice --------------------------------------------------*
  *
  * This file is part of Catacomb.
  *
  * it under the terms of the GNU Library General Public License as
  * published by the Free Software Foundation; either version 2 of the
  * License, or (at your option) any later version.
- * 
+ *
  * Catacomb is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU Library General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU Library General Public
  * License along with Catacomb; if not, write to the Free
  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
  * MA 02111-1307, USA.
  */
 
-/*----- Revision history --------------------------------------------------* 
- *
- * $Log: hash.h,v $
- * Revision 1.1  1999/09/03 08:41:12  mdw
- * Initial import.
- *
- */
-
-#ifndef HASH_H
-#define HASH_H
+#ifndef CATACOMB_HASH_H
+#define CATACOMB_HASH_H
 
 #ifdef __cplusplus
   extern "C" {
   size_t _bsz = (isz);                                                 \
   const octet *_bbuf = (octet *)(ibuf);                                        \
                                                                        \
-  /* --- Add on the size done so far --- */                            \
+  /* --- Add on the size done so far --- *                             \
+   *                                                                   \
+   * Messy, because trapping overflow is difficult when you don't know \
+   * how many bits you've actually got.                                        \
+   */                                                                  \
                                                                        \
-  _bctx->count += _bsz;                                                        \
+  {                                                                    \
+    uint32 _l = U32(_bsz);                                             \
+    uint32 _h = ((_bsz & ~MASK32) >> 16) >> 16;                                \
+    _bctx->nh += _h;                                                   \
+    _bctx->nl += _l;                                                   \
+    if (_bctx->nl < _l || _bctx->nl & ~MASK32)                         \
+      _bctx->nh++;                                                     \
+  }                                                                    \
                                                                        \
   /* --- Handle very small contributions --- */                                \
                                                                        \
 #define HASH_MD5STRENGTH(PRE, pre, ictx) do {                          \
   pre##_ctx *_mctx = (ictx);                                           \
   HASH_PAD(PRE, pre, _mctx, 0x80u, 0, 8);                              \
-  STORE32_L(_mctx->buf + PRE##_BUFSZ - 8, _mctx->count << 3);          \
-  STORE32_L(_mctx->buf + PRE##_BUFSZ - 4, _mctx->count >> 29);         \
+  STORE32_L(_mctx->buf + PRE##_BUFSZ - 8, _mctx->nl << 3);             \
+  STORE32_L(_mctx->buf + PRE##_BUFSZ - 4,                              \
+           (_mctx->nl >> 29) | (_mctx->nh << 3));                      \
   pre##_compress(_mctx, _mctx->buf);                                   \
 } while (0)
 
 #include <mLib/quis.h>
 #include <mLib/testrig.h>
 
+#define HASH_BUFLEN 100000
+
 #define HASH_TEST(PRE, pre)                                            \
                                                                        \
 static int verify(dstr *v)                                             \
@@ -209,8 +215,47 @@ static int verify(dstr *v)                                         \
   return (ok);                                                         \
 }                                                                      \
                                                                        \
+static int verifyrep(dstr *v)                                          \
+{                                                                      \
+  pre##_ctx ctx;                                                       \
+  size_t len = v[0].len;                                               \
+  int n = *(int *)v[1].buf;                                            \
+  int nd = 0;                                                          \
+  int nn = len;                                                                \
+  int ok = 1;                                                          \
+  octet *p, *q;                                                                \
+  dstr d = DSTR_INIT;                                                  \
+                                                                       \
+  while (nn < HASH_BUFLEN && (n & 1) == 0) { nd++; nn <<= 1; n >>= 1; }        \
+  p = xmalloc(nn);                                                     \
+  memcpy(p, v[0].buf, len);                                            \
+  q = p + len;                                                         \
+  while (nd--) { memcpy(q, p, len); q += len; len <<= 1; }             \
+                                                                       \
+  dstr_ensure(&d, PRE##_HASHSZ);                                       \
+  d.len = PRE##_HASHSZ;                                                        \
+  pre##_init(&ctx);                                                    \
+  while (n--) pre##_hash(&ctx, p, len);                                        \
+  pre##_done(&ctx, d.buf);                                             \
+                                                                       \
+  if (memcmp(d.buf, v[2].buf, PRE##_HASHSZ) != 0) {                    \
+    printf("\nfail:\n\tinput = `%s'\n\treps = `%i'\n\texpected = ",    \
+            v[0].buf, *(int *)v[1].buf);                               \
+    type_hex.dump(&v[2], stdout);                                      \
+    fputs("\n\tcomputed = ", stdout);                                  \
+    type_hex.dump(&d, stdout);                                         \
+    putchar('\n');                                                     \
+    ok = 0;                                                            \
+  }                                                                    \
+  xfree(p);                                                            \
+  dstr_destroy(&d);                                                    \
+  return (ok);                                                         \
+}                                                                      \
+                                                                       \
 static test_chunk defs[] = {                                           \
   { #pre, verify, { &type_string, &type_hex, 0 } },                    \
+  { #pre "-rep", verifyrep,                                            \
+    { &type_string, &type_int, &type_hex, 0 } },                       \
   { 0, 0, { 0 } }                                                      \
 };                                                                     \
                                                                        \