Merge branch 'master' of git+ssh://metalzone.distorted.org.uk/~mdw/public-git/catacomb/
[u/mdw/catacomb] / hash.h
diff --git a/hash.h b/hash.h
index 5b7f0c3..881feeb 100644 (file)
--- a/hash.h
+++ b/hash.h
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: hash.h,v 1.2 1999/12/10 23:16:40 mdw Exp $
+ * $Id$
  *
  * Generic handling for message digest functions
  *
  * MA 02111-1307, USA.
  */
 
-/*----- Revision history --------------------------------------------------* 
- *
- * $Log: hash.h,v $
- * Revision 1.2  1999/12/10 23:16:40  mdw
- * Split mode macros into interface and implementation.
- *
- * Revision 1.1  1999/09/03 08:41:12  mdw
- * Initial import.
- *
- */
-
 #ifndef CATACOMB_HASH_H
 #define CATACOMB_HASH_H
 
@@ -80,7 +69,8 @@
    */                                                                  \
                                                                        \
   {                                                                    \
-    uint32 _l = U32(_bsz), _h = (_bsz >> 16) >> 16;                    \
+    uint32 _l = U32(_bsz);                                             \
+    uint32 _h = ((_bsz & ~MASK32) >> 16) >> 16;                                \
     _bctx->nh += _h;                                                   \
     _bctx->nl += _l;                                                   \
     if (_bctx->nl < _l || _bctx->nl & ~MASK32)                         \
 #include <mLib/quis.h>
 #include <mLib/testrig.h>
 
+#define HASH_BUFLEN 100000
+
 #define HASH_TEST(PRE, pre)                                            \
                                                                        \
 static int verify(dstr *v)                                             \
@@ -223,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 } }                                                      \
 };                                                                     \
                                                                        \