summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDonovan Baarda <abo@minkirri.apana.org.au>2020-04-07 00:48:55 +1000
committerGitHub <noreply@github.com>2020-04-07 00:48:55 +1000
commit2a32f5ec01796cfc0f5704fb653b0e356633c5de (patch)
tree5d065fa50539a7fe8ae0d5aa903d737d69a4dc34
parentef519bfffb93394293162149aa7f511064bb7bab (diff)
parent6c342799f02d15c051c373fa1fc3d98d760dbfb2 (diff)
downloadlibrsync-2a32f5ec01796cfc0f5704fb653b0e356633c5de.tar.gz
Merge pull request #109 from dbaarda/dev/sigparms1
Add public rs_sig_args() function for recommend signature args from filesize.
-rw-r--r--CMakeLists.txt4
-rw-r--r--NEWS.md23
-rw-r--r--librsync.spec4
-rw-r--r--src/librsync.h56
-rw-r--r--src/mksum.c6
-rw-r--r--src/rdiff.c13
-rw-r--r--src/sumset.c71
-rw-r--r--src/sumset.h44
-rw-r--r--src/util.c26
-rw-r--r--src/util.h3
-rw-r--r--src/whole.c11
-rw-r--r--tests/signature.input/01-Rrabinkarp-Hblake2-S-1.sigbin0 -> 1052 bytes
-rw-r--r--tests/signature.input/01-Rrabinkarp-Hblake2-S0.sigbin0 -> 3756 bytes
-rw-r--r--tests/signature.input/01-Rrabinkarp-Hblake2-S8.sigbin0 -> 1260 bytes
-rw-r--r--tests/signature.input/01-Rrabinkarp-Hmd4-S-1.sigbin0 -> 1052 bytes
-rw-r--r--tests/signature.input/01-Rrabinkarp-Hmd4-S0.sigbin0 -> 2092 bytes
-rw-r--r--tests/signature.input/01-Rrabinkarp-Hmd4-S8.sigbin0 -> 1260 bytes
-rw-r--r--tests/signature.input/01-Rrollsum-Hblake2-S-1.sigbin0 -> 1052 bytes
-rw-r--r--tests/signature.input/01-Rrollsum-Hblake2-S0.sigbin0 -> 3756 bytes
-rw-r--r--tests/signature.input/01-Rrollsum-Hblake2-S8.sigbin0 -> 1260 bytes
-rw-r--r--tests/signature.input/01-Rrollsum-Hmd4-S-1.sigbin0 -> 1052 bytes
-rw-r--r--tests/signature.input/01-Rrollsum-Hmd4-S0.sigbin0 -> 2092 bytes
-rw-r--r--tests/signature.input/01-Rrollsum-Hmd4-S8.sigbin0 -> 1260 bytes
-rw-r--r--tests/signature.input/rabinkarp-blake2/01.sigbin480 -> 0 bytes
-rw-r--r--tests/signature.input/rabinkarp-md4/01.sigbin168 -> 0 bytes
-rw-r--r--tests/signature.input/rollsum-blake2/01.sigbin480 -> 0 bytes
-rw-r--r--tests/signature.input/rollsum-md4/01.sigbin168 -> 0 bytes
-rwxr-xr-xtests/signature.test16
-rw-r--r--tests/sumset_test.c153
29 files changed, 357 insertions, 73 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c271ad6..939ea78 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -23,8 +23,8 @@ INCLUDE(CMakeDependentOption)
include(GNUInstallDirs)
set(LIBRSYNC_MAJOR_VERSION 2)
-set(LIBRSYNC_MINOR_VERSION 2)
-set(LIBRSYNC_PATCH_VERSION 2)
+set(LIBRSYNC_MINOR_VERSION 3)
+set(LIBRSYNC_PATCH_VERSION 0)
set(LIBRSYNC_VERSION
${LIBRSYNC_MAJOR_VERSION}.${LIBRSYNC_MINOR_VERSION}.${LIBRSYNC_PATCH_VERSION})
diff --git a/NEWS.md b/NEWS.md
index 40021b7..de6b8d0 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -1,9 +1,30 @@
# librsync NEWS
-## librsync 2.2.2
+## librsync 2.3.0
NOT RELEASED YET
+ * Bump minor version from 2.3.1 to 2.3.0 to reflect additional rs_sig_args()
+ and strong_len=-1 support.
+
+ * Add public rs_sig_args() function for getting the recommend signature args
+ from the filesize. Added support to rdiff for `--sum-size=-1` to indicate
+ "use minimum size safe against random block collisions". Added warning
+ output for sum-sizes that are too small to be safe. Fixed possible rdiff
+ bug affecting popt parsing on non-little-endian platforms. (dbaarda,
+ https://github.com/librsync/librsync/pull/109)
+
+ * Fixed yet more compiler warnings for various platforms. (Adsun701, texierp,
+ https://github.com/librsync/librsync/pull/187,
+ https://github.com/librsync/librsync/pull/188)
+
+ * Improved cmake popt handling to find popt dependencies using PkgConfig.
+ (ffontaine, https://github.com/librsync/librsync/pull/186)
+
+ * Tidied internal code and improved tests for netint.[ch], tube.c, and
+ hashtable.h. (dbaarda, https://github.com/librsync/librsync/pull/183
+ https://github.com/librsync/librsync/pull/185).
+
* Improved C99 compatibility. Add `-std=c99 -pedantic` to `CMAKE_C_FLAGS` for
gcc and clang. Fix all C99 warnings by making all code C99 compliant. Tidy
all CMake checks, #cmakedefines, and #includes. Fix 64bit support for
diff --git a/librsync.spec b/librsync.spec
index 24de403..2115399 100644
--- a/librsync.spec
+++ b/librsync.spec
@@ -1,7 +1,7 @@
# This RPM supposes that you download the release zip file from github to SOURCES directory as v2.2.2.zip
%define name librsync
-%define version 2.2.2
+%define version 2.3.0
%define gitsource https://github.com/librsync/%{name}/archive/v%{version}.zip
Summary: Rsync libraries
@@ -72,6 +72,8 @@ rm -rf $RPM_BUILD_ROOT
%{_includedir}/%{name}*
%changelog
+* Tue Apr 07 2020 Donovan Baarda <abo@minkirri.apana.org.au>
+- Prepared SPEC file for librsync 2.3.0
* Wed Oct 17 2019 Donovan Baarda <abo@minkirri.apana.org.au>
- Prepared SPEC file for librsync 2.2.2
* Wed Oct 16 2019 Donovan Baarda <abo@minkirri.apana.org.au>
diff --git a/src/librsync.h b/src/librsync.h
index 30fd961..c85a2bc 100644
--- a/src/librsync.h
+++ b/src/librsync.h
@@ -354,9 +354,18 @@ struct rs_buffers_s {
/** \sa ::rs_buffers_s */
typedef struct rs_buffers_s rs_buffers_t;
-/** Default block length, if not determined by any other factors. */
+/** Default block length, if not determined by any other factors.
+ *
+ * The 2K default assumes a typical file is about 4MB and should be OK for
+ * files up to 32G with more than 1GB ram. */
# define RS_DEFAULT_BLOCK_LEN 2048
+/** Default minimum strong sum length, if the filesize is unknown.
+ *
+ * This is conservative, and should be safe for files less than 45TB with a 2KB
+ * block_len, assuming no collision attack with crafted data. */
+# define RS_DEFAULT_MIN_STRONG_LEN 12
+
/** Job of work to be done.
*
* Created by functions such as rs_sig_begin(), and then iterated over by
@@ -402,23 +411,52 @@ LIBRSYNC_EXPORT const rs_stats_t *rs_job_statistics(rs_job_t *job);
/** Deallocate job state. */
LIBRSYNC_EXPORT rs_result rs_job_free(rs_job_t *);
+/** Get or check signature arguments for a given file size.
+ *
+ * This can be used to get the recommended arguments for generating a
+ * signature. On calling, old_fsize should be set to the old file size or -1
+ * for "unknown". The magic and block_len arguments should be set to a valid
+ * value or 0 for "recommended". The strong_len input should be set to a valid
+ * value, 0 for "maximum", or -1 for "miniumum". Use strong_len=0 for the best
+ * protection against active hash collision attacks for the given magic type.
+ * Use strong_len=-1 for the smallest signature size that is safe against
+ * random hash collisions for the block_len and old_fsize. On return the 0 or
+ * -1 input args will be set to recommended values and the returned result will
+ * indicate if any inputs were invalid.
+ *
+ * \param old_fsize - the original file size (-1 for "unknown").
+ *
+ * \param *magic - the magic type to use (0 for "recommended").
+ *
+ * \param *block_len - the block length to use (0 for "recommended").
+ *
+ * \param *strong_len - the strongsum length to use (0 for "maximum", -1 for
+ * "minimum").
+ *
+ * \return RS_DONE if all arguments are valid, otherwise an error code. */
+LIBRSYNC_EXPORT rs_result rs_sig_args(rs_long_t old_fsize,
+ rs_magic_number * magic,
+ size_t *block_len, size_t *strong_len);
+
/** Start generating a signature.
*
+ * It's recommended you use rs_sig_args() to get the recommended arguments for
+ * this based on the original file size.
+ *
* \return A new rs_job_t into which the old file data can be passed.
*
- * \param sig_magic Indicates the version of signature file format to generate.
+ * \param sig_magic Signature file format to generate (0 for "recommended").
* See ::rs_magic_number.
*
- * \param new_block_len Size of checksum blocks. Larger values make the
- * signature shorter, and the delta longer.
+ * \param block_len Checksum block size to use (0 for "recommended"). Larger
+ * values make the signature shorter, and the delta longer.
*
- * \param strong_sum_len If non-zero, truncate the strong signatures to this
- * many bytes, to make the signature shorter. It's recommended you leave this
- * at zero to get the full strength.
+ * \param strong_len Strongsum length in bytes to use (0 for "maximum", -1 for
+ * "minimum"). Smaller values make the signature shorter but increase the risk
+ * of corruption from hash collisions.
*
* \sa rs_sig_file() */
-LIBRSYNC_EXPORT rs_job_t *rs_sig_begin(size_t new_block_len,
- size_t strong_sum_len,
+LIBRSYNC_EXPORT rs_job_t *rs_sig_begin(size_t block_len, size_t strong_len,
rs_magic_number sig_magic);
/** Prepare to compute a streaming delta.
diff --git a/src/mksum.c b/src/mksum.c
index 07a99d7..f162270 100644
--- a/src/mksum.c
+++ b/src/mksum.c
@@ -112,7 +112,7 @@ static rs_result rs_sig_s_generate(rs_job_t *job)
return rs_sig_do_block(job, block, len);
}
-rs_job_t *rs_sig_begin(size_t new_block_len, size_t strong_sum_len,
+rs_job_t *rs_sig_begin(size_t block_len, size_t strong_len,
rs_magic_number sig_magic)
{
rs_job_t *job;
@@ -121,7 +121,7 @@ rs_job_t *rs_sig_begin(size_t new_block_len, size_t strong_sum_len,
job->signature = rs_alloc_struct(rs_signature_t);
job->job_owns_sig = 1;
job->sig_magic = sig_magic;
- job->sig_block_len = new_block_len;
- job->sig_strong_len = strong_sum_len;
+ job->sig_block_len = block_len;
+ job->sig_strong_len = strong_len;
return job;
}
diff --git a/src/rdiff.c b/src/rdiff.c
index fb981d2..b1bc6ce 100644
--- a/src/rdiff.c
+++ b/src/rdiff.c
@@ -51,8 +51,8 @@
#include "librsync.h"
#include "isprefix.h"
-static size_t block_len = RS_DEFAULT_BLOCK_LEN;
-static size_t strong_len = 0;
+static int block_len = 0;
+static int strong_len = 0;
static int show_stats = 0;
@@ -108,8 +108,8 @@ static void help(void)
" -H, --hash=ALG Hash algorithm: blake2 (default), md4\n"
" -R, --rollsum=ALG Rollsum algorithm: rabinkarp (default), rollsum\n"
"Delta-encoding options:\n"
- " -b, --block-size=BYTES Signature block size\n"
- " -S, --sum-size=BYTES Set signature strength\n"
+ " -b, --block-size=BYTES Signature block size, 0 (default) for recommended\n"
+ " -S, --sum-size=BYTES Signature strength, 0 (default) for max, -1 for min\n"
"IO options:\n" " -I, --input-size=BYTES Input buffer size\n"
" -O, --output-size=BYTES Output buffer size\n"
" -z, --gzip[=LEVEL] gzip-compress deltas\n"
@@ -205,11 +205,6 @@ static rs_result rdiff_sig(poptContext opcon)
if (!rs_hash_name || !strcmp(rs_hash_name, "blake2")) {
sig_magic = RS_BLAKE2_SIG_MAGIC;
} else if (!strcmp(rs_hash_name, "md4")) {
- /* By default, for compatibility with rdiff 0.9.8 and before, mdfour
- sums are truncated to only 8 bytes, making them even weaker, but
- making the signature file shorter. */
- if (!strong_len)
- strong_len = 8;
sig_magic = RS_MD4_SIG_MAGIC;
} else {
rdiff_usage("Unknown hash algorithm '%s'.", rs_hash_name);
diff --git a/src/sumset.c b/src/sumset.c
index 81d5fd7..752ebf5 100644
--- a/src/sumset.c
+++ b/src/sumset.c
@@ -114,14 +114,18 @@ static inline int rs_block_sig_idx(const rs_signature_t *sig,
(char *)sig->block_sigs) / rs_block_sig_size(sig);
}
-rs_result rs_signature_init(rs_signature_t *sig, int magic, int block_len,
- int strong_len, rs_long_t sig_fsize)
+rs_result rs_sig_args(rs_long_t old_fsize, rs_magic_number * magic,
+ size_t *block_len, size_t *strong_len)
{
- int max_strong_len;
+ size_t rec_block_len; /* the recomended block_len for the given
+ old_fsize. */
+ size_t min_strong_len; /* the minimum strong_len for the given
+ old_fsize and block_len. */
+ size_t max_strong_len; /* the maximum strong_len for the given magic. */
/* Check and set default arguments. */
- magic = magic ? magic : RS_RK_BLAKE2_SIG_MAGIC;
- switch (magic) {
+ *magic = *magic ? *magic : RS_RK_BLAKE2_SIG_MAGIC;
+ switch (*magic) {
case RS_BLAKE2_SIG_MAGIC:
case RS_RK_BLAKE2_SIG_MAGIC:
max_strong_len = RS_BLAKE2_SUM_LENGTH;
@@ -131,14 +135,63 @@ rs_result rs_signature_init(rs_signature_t *sig, int magic, int block_len,
max_strong_len = RS_MD4_SUM_LENGTH;
break;
default:
- rs_error("invalid magic %#x", magic);
+ rs_error("invalid magic %#x", *magic);
return RS_BAD_MAGIC;
}
- strong_len = strong_len ? strong_len : max_strong_len;
- if (strong_len < 1 || max_strong_len < strong_len) {
- rs_error("invalid strong_sum_len %d for magic %#x", strong_len, magic);
+ /* The recommended block_len is sqrt(old_fsize) with a 256 min size to give
+ a reasonable compromise between signature size, delta size, and
+ performance. If the old_fsize is unknown, we use the default. */
+ if (old_fsize < 0) {
+ rec_block_len = RS_DEFAULT_BLOCK_LEN;
+ } else {
+ rec_block_len = old_fsize <= 256 * 256 ? 256 : rs_long_sqrt(old_fsize);
+ }
+ if (*block_len == 0)
+ *block_len = rec_block_len;
+ /* The recommended strong_len assumes the worst case new_fsize = old_fsize
+ + 16MB with no matches. This results in comparing a block at every byte
+ offset against all the blocks in the signature, or new_fsize*block_num
+ comparisons. With N bits in the blocksig, there is a 1/2^N chance per
+ comparison of a hash colision. So with 2^N attempts there would be a
+ fair chance of having a collision. So we want to round up to the next
+ byte, add an extra 2 bytes (16 bits) in the strongsum, and assume the
+ weaksum is worth another 16 bits, for at least 32 bits extra, giving a
+ worst case 1/2^32 chance of having a hash collision per delta. If
+ old_fsize is unknown we use a conservative default. */
+ if (old_fsize < 0) {
+ min_strong_len = RS_DEFAULT_MIN_STRONG_LEN;
+ } else {
+ min_strong_len =
+ 2 + (rs_long_ln2(old_fsize + ((rs_long_t)1 << 24)) +
+ rs_long_ln2(old_fsize / *block_len + 1) + 7) / 8;
+ }
+ if (*strong_len == 0)
+ *strong_len = max_strong_len;
+ else if (*strong_len == -1)
+ *strong_len = min_strong_len;
+ else if (old_fsize >= 0 && *strong_len < min_strong_len) {
+ rs_log(RS_LOG_WARNING,
+ "strong_len=" FMT_SIZE " smaller than recommended minimum "
+ FMT_SIZE " for old_fsize=" FMT_LONG " with block_len=" FMT_SIZE,
+ *strong_len, min_strong_len, old_fsize, *block_len);
+ } else if (*strong_len > max_strong_len) {
+ rs_error("invalid strong_len=" FMT_SIZE " for magic=%#x", *strong_len,
+ (int)*magic);
return RS_PARAM_ERROR;
}
+ rs_sig_args_check(*magic, *block_len, *strong_len);
+ return RS_DONE;
+}
+
+rs_result rs_signature_init(rs_signature_t *sig, rs_magic_number magic,
+ size_t block_len, size_t strong_len,
+ rs_long_t sig_fsize)
+{
+ rs_result result;
+
+ /* Check and set default arguments, using old_fsize=-1 for unknown. */
+ if ((result = rs_sig_args(-1, &magic, &block_len, &strong_len)) != RS_DONE)
+ return result;
/* Set attributes from args. */
sig->magic = magic;
sig->block_len = block_len;
diff --git a/src/sumset.h b/src/sumset.h
index d1b078a..592ba01 100644
--- a/src/sumset.h
+++ b/src/sumset.h
@@ -52,18 +52,19 @@ struct rs_signature {
*
* \param *sig the signature to initialize.
*
- * \param magic the signature magic value. Must be set to a valid magic value.
+ * \param magic - the magic type to use (0 for "recommended").
*
- * \param block_len the block size to use. Must be > 0.
+ * \param block_len - the block length to use (0 for "recommended").
*
- * \param strong_len the strongsum size to use. Must be <= the max strongsum
- * size for the strongsum type indicated by the magic value. Use 0 to use the
- * recommended size for the provided magic value.
+ * \param strong_len - the strongsum length to use (0 for "maximum", -1 for
+ * "minimum"). Must be <= the max strongsum size for the strongsum type
+ * indicated by the magic value.
*
- * \param sig_fsize signature file size to preallocate required storage for.
- * Use 0 if size is unknown. */
-rs_result rs_signature_init(rs_signature_t *sig, int magic, int block_len,
- int strong_len, rs_long_t sig_fsize);
+ * \param sig_fsize - the signature file size (-1 for "unknown"). Used to
+ * preallocate required storage. */
+rs_result rs_signature_init(rs_signature_t *sig, rs_magic_number magic,
+ size_t block_len, size_t strong_len,
+ rs_long_t sig_fsize);
/** Destroy an rs_signature instance. */
void rs_signature_done(rs_signature_t *sig);
@@ -77,20 +78,27 @@ rs_block_sig_t *rs_signature_add_block(rs_signature_t *sig,
rs_long_t rs_signature_find_match(rs_signature_t *sig, rs_weak_sum_t weak_sum,
void const *buf, size_t len);
+/** Assert that rs_sig_args() args for rs_signature_init() are valid.
+ *
+ * We don't use a static inline function here so that assert failure output
+ * points at where rs_sig_args_check() was called from. */
+#define rs_sig_args_check(magic, block_len, strong_len) do {\
+ assert(((magic) & 0xffffff00) == (RS_MD4_SIG_MAGIC & 0xffffff00));\
+ assert(((magic) & 0xf0) == 0x30 || ((magic) & 0xf0) == 0x40);\
+ assert((((magic) & 0x0f) == 0x06 &&\
+ (strong_len) <= RS_MD4_SUM_LENGTH) ||\
+ (((magic) & 0x0f) == 0x07 &&\
+ (strong_len) <= RS_BLAKE2_SUM_LENGTH));\
+ assert(0 < (block_len));\
+ assert(0 < (strong_len) && (strong_len) <= RS_MAX_STRONG_SUM_LENGTH);\
+} while (0)
+
/** Assert that a signature is valid.
*
* We don't use a static inline function here so that assert failure output
* points at where rs_signature_check() was called from. */
#define rs_signature_check(sig) do {\
- assert(((sig)->magic & 0xffffff00) == (RS_MD4_SIG_MAGIC & 0xffffff00));\
- assert(((sig)->magic & 0xf0) == 0x30 || ((sig)->magic & 0xf0) == 0x40);\
- assert((((sig)->magic & 0x0f) == 0x07 &&\
- (sig)->strong_sum_len <= RS_BLAKE2_SUM_LENGTH) ||\
- (((sig)->magic & 0x0f) == 0x06 &&\
- (sig)->strong_sum_len <= RS_MD4_SUM_LENGTH));\
- assert(0 < (sig)->block_len);\
- assert(0 < (sig)->strong_sum_len &&\
- (sig)->strong_sum_len <= RS_MAX_STRONG_SUM_LENGTH);\
+ rs_sig_args_check((sig)->magic, (sig)->block_len, (sig)->strong_sum_len);\
assert(0 <= (sig)->count && (sig)->count <= (sig)->size);\
assert(!(sig)->hashtable || (sig)->hashtable->count <= (sig)->count);\
} while (0)
diff --git a/src/util.c b/src/util.c
index 3490ed3..59351da 100644
--- a/src/util.c
+++ b/src/util.c
@@ -66,3 +66,29 @@ void *rs_realloc(void *ptr, size_t size, char const *name)
}
return p;
}
+
+int rs_long_ln2(rs_long_t v)
+{
+ int n;
+
+ /* Count the number of shifts to zero v. */
+ for (n = 0; (v >>= 1); n++) ;
+ return n;
+}
+
+int rs_long_sqrt(rs_long_t v)
+{
+ rs_long_t n, b;
+
+ /* Find the most significant bit of the root. */
+ for (b = 1, n = v; (n >>= 2); b <<= 1) ;
+ /* Walk down the bits of the root. */
+ for (n = 0; b; b >>= 1) {
+ /* Set the bit in the answer n. */
+ n |= b;
+ /* If n^2 is too big, clear the bit. */
+ if (n * n > v)
+ n ^= b;
+ }
+ return n;
+}
diff --git a/src/util.h b/src/util.h
index e7b3b43..4fbd1c7 100644
--- a/src/util.h
+++ b/src/util.h
@@ -26,6 +26,9 @@ void *rs_alloc_struct0(size_t size, char const *name);
void rs_bzero(void *buf, size_t size);
+int rs_long_ln2(rs_long_t v);
+int rs_long_sqrt(rs_long_t v);
+
/** Allocate and zero-fill an instance of TYPE. */
#define rs_alloc_struct(type) \
((type *) rs_alloc_struct0(sizeof(type), #type))
diff --git a/src/whole.c b/src/whole.c
index be08abd..e7034c6 100644
--- a/src/whole.c
+++ b/src/whole.c
@@ -80,16 +80,21 @@ rs_result rs_whole_run(rs_job_t *job, FILE *in_file, FILE *out_file,
return result;
}
-rs_result rs_sig_file(FILE *old_file, FILE *sig_file, size_t new_block_len,
+rs_result rs_sig_file(FILE *old_file, FILE *sig_file, size_t block_len,
size_t strong_len, rs_magic_number sig_magic,
rs_stats_t *stats)
{
rs_job_t *job;
rs_result r;
+ rs_long_t old_fsize = rs_file_size(old_file);
- job = rs_sig_begin(new_block_len, strong_len, sig_magic);
+ if ((r =
+ rs_sig_args(old_fsize, &sig_magic, &block_len,
+ &strong_len)) != RS_DONE)
+ return r;
+ job = rs_sig_begin(block_len, strong_len, sig_magic);
/* Size inbuf for 4 blocks, outbuf for header + 4 blocksums. */
- r = rs_whole_run(job, old_file, sig_file, 4 * new_block_len,
+ r = rs_whole_run(job, old_file, sig_file, 4 * block_len,
12 + 4 * (4 + strong_len));
if (stats)
memcpy(stats, &job->stats, sizeof *stats);
diff --git a/tests/signature.input/01-Rrabinkarp-Hblake2-S-1.sig b/tests/signature.input/01-Rrabinkarp-Hblake2-S-1.sig
new file mode 100644
index 0000000..ee0cbe6
--- /dev/null
+++ b/tests/signature.input/01-Rrabinkarp-Hblake2-S-1.sig
Binary files differ
diff --git a/tests/signature.input/01-Rrabinkarp-Hblake2-S0.sig b/tests/signature.input/01-Rrabinkarp-Hblake2-S0.sig
new file mode 100644
index 0000000..7744860
--- /dev/null
+++ b/tests/signature.input/01-Rrabinkarp-Hblake2-S0.sig
Binary files differ
diff --git a/tests/signature.input/01-Rrabinkarp-Hblake2-S8.sig b/tests/signature.input/01-Rrabinkarp-Hblake2-S8.sig
new file mode 100644
index 0000000..0a19edb
--- /dev/null
+++ b/tests/signature.input/01-Rrabinkarp-Hblake2-S8.sig
Binary files differ
diff --git a/tests/signature.input/01-Rrabinkarp-Hmd4-S-1.sig b/tests/signature.input/01-Rrabinkarp-Hmd4-S-1.sig
new file mode 100644
index 0000000..ea90e59
--- /dev/null
+++ b/tests/signature.input/01-Rrabinkarp-Hmd4-S-1.sig
Binary files differ
diff --git a/tests/signature.input/01-Rrabinkarp-Hmd4-S0.sig b/tests/signature.input/01-Rrabinkarp-Hmd4-S0.sig
new file mode 100644
index 0000000..aa08860
--- /dev/null
+++ b/tests/signature.input/01-Rrabinkarp-Hmd4-S0.sig
Binary files differ
diff --git a/tests/signature.input/01-Rrabinkarp-Hmd4-S8.sig b/tests/signature.input/01-Rrabinkarp-Hmd4-S8.sig
new file mode 100644
index 0000000..4c106c5
--- /dev/null
+++ b/tests/signature.input/01-Rrabinkarp-Hmd4-S8.sig
Binary files differ
diff --git a/tests/signature.input/01-Rrollsum-Hblake2-S-1.sig b/tests/signature.input/01-Rrollsum-Hblake2-S-1.sig
new file mode 100644
index 0000000..9c9faec
--- /dev/null
+++ b/tests/signature.input/01-Rrollsum-Hblake2-S-1.sig
Binary files differ
diff --git a/tests/signature.input/01-Rrollsum-Hblake2-S0.sig b/tests/signature.input/01-Rrollsum-Hblake2-S0.sig
new file mode 100644
index 0000000..49966d0
--- /dev/null
+++ b/tests/signature.input/01-Rrollsum-Hblake2-S0.sig
Binary files differ
diff --git a/tests/signature.input/01-Rrollsum-Hblake2-S8.sig b/tests/signature.input/01-Rrollsum-Hblake2-S8.sig
new file mode 100644
index 0000000..43fff97
--- /dev/null
+++ b/tests/signature.input/01-Rrollsum-Hblake2-S8.sig
Binary files differ
diff --git a/tests/signature.input/01-Rrollsum-Hmd4-S-1.sig b/tests/signature.input/01-Rrollsum-Hmd4-S-1.sig
new file mode 100644
index 0000000..c02ec4c
--- /dev/null
+++ b/tests/signature.input/01-Rrollsum-Hmd4-S-1.sig
Binary files differ
diff --git a/tests/signature.input/01-Rrollsum-Hmd4-S0.sig b/tests/signature.input/01-Rrollsum-Hmd4-S0.sig
new file mode 100644
index 0000000..ccd4398
--- /dev/null
+++ b/tests/signature.input/01-Rrollsum-Hmd4-S0.sig
Binary files differ
diff --git a/tests/signature.input/01-Rrollsum-Hmd4-S8.sig b/tests/signature.input/01-Rrollsum-Hmd4-S8.sig
new file mode 100644
index 0000000..28d40a6
--- /dev/null
+++ b/tests/signature.input/01-Rrollsum-Hmd4-S8.sig
Binary files differ
diff --git a/tests/signature.input/rabinkarp-blake2/01.sig b/tests/signature.input/rabinkarp-blake2/01.sig
deleted file mode 100644
index 824e129..0000000
--- a/tests/signature.input/rabinkarp-blake2/01.sig
+++ /dev/null
Binary files differ
diff --git a/tests/signature.input/rabinkarp-md4/01.sig b/tests/signature.input/rabinkarp-md4/01.sig
deleted file mode 100644
index e33b591..0000000
--- a/tests/signature.input/rabinkarp-md4/01.sig
+++ /dev/null
Binary files differ
diff --git a/tests/signature.input/rollsum-blake2/01.sig b/tests/signature.input/rollsum-blake2/01.sig
deleted file mode 100644
index f7a488f..0000000
--- a/tests/signature.input/rollsum-blake2/01.sig
+++ /dev/null
Binary files differ
diff --git a/tests/signature.input/rollsum-md4/01.sig b/tests/signature.input/rollsum-md4/01.sig
deleted file mode 100644
index 898bc51..0000000
--- a/tests/signature.input/rollsum-md4/01.sig
+++ /dev/null
Binary files differ
diff --git a/tests/signature.test b/tests/signature.test
index 89c26ea..82f5aa0 100755
--- a/tests/signature.test
+++ b/tests/signature.test
@@ -28,13 +28,15 @@ srcdir='.'
new=$tmpdir/signature
-for hashfunc in md4 blake2; do
- for rollfunc in rollsum rabinkarp; do
- for input in "$srcdir/signature.input"/*.in; do
- for inbuf in $bufsizes; do
- expect=`echo $input | sed -e 's/.in$/.sig/' -e "s,input,input/$rollfunc-$hashfunc,"`
- run_test $bindir/rdiff --rollsum=$rollfunc --hash=$hashfunc -I$inbuf -f signature "$input" "$new"
- check_compare "$expect" "$new"
+for rollfunc in rollsum rabinkarp; do
+ for hashfunc in md4 blake2; do
+ for stronglen in 0 -1 8; do
+ for input in "$srcdir/signature.input"/*.in; do
+ for inbuf in $bufsizes; do
+ expect=`echo $input | sed -e "s/.in\$/-R${rollfunc}-H${hashfunc}-S${stronglen}.sig/"`
+ run_test $bindir/rdiff -R$rollfunc -H$hashfunc -S$stronglen -I$inbuf -f signature "$input" "$new"
+ check_compare "$expect" "$new"
+ done
done
done
done
diff --git a/tests/sumset_test.c b/tests/sumset_test.c
index 1fea866..7a8d3e0 100644
--- a/tests/sumset_test.c
+++ b/tests/sumset_test.c
@@ -41,13 +41,136 @@ int main(int argc, char **argv)
for (i = 0; i < 256; i++)
buf[i] = i;
+ /* Test rs_sig_args() */
+ rs_magic_number magic;
+ size_t block_len, strong_len;
+
+ /* old_fsize=unknown, all recommended. */
+ magic = 0;
+ block_len = 0;
+ strong_len = 0;
+ res = rs_sig_args(-1, &magic, &block_len, &strong_len);
+ assert(res == RS_DONE);
+ assert(magic == RS_RK_BLAKE2_SIG_MAGIC);
+ assert(block_len == 2048);
+ assert(strong_len == 32);
+
+ /* old_fsize=0, all recommended. */
+ magic = 0;
+ block_len = 0;
+ strong_len = 0;
+ res = rs_sig_args(0, &magic, &block_len, &strong_len);
+ assert(res == RS_DONE);
+ assert(magic == RS_RK_BLAKE2_SIG_MAGIC);
+ assert(block_len == 256);
+ assert(strong_len == 32);
+
+ /* old_fsize=100000, magic=rs/md4, block_len=rec, strong_len=rec. */
+ magic = RS_MD4_SIG_MAGIC;
+ block_len = 0;
+ strong_len = 0;
+ res = rs_sig_args(100000, &magic, &block_len, &strong_len);
+ assert(res == RS_DONE);
+ assert(magic == RS_MD4_SIG_MAGIC);
+ assert(block_len == 316);
+ assert(strong_len == 16);
+
+ /* old_fsize=unknown, magic=rk/b2, block_len=rec, strong_len=min. */
+ magic = RS_RK_BLAKE2_SIG_MAGIC;
+ block_len = 0;
+ strong_len = -1;
+ res = rs_sig_args(-1, &magic, &block_len, &strong_len);
+ assert(res == RS_DONE);
+ assert(magic == RS_RK_BLAKE2_SIG_MAGIC);
+ assert(block_len == 2048);
+ assert(strong_len == 12);
+
+ /* old_fsize=unknown, magic=rs/b2, block_len=1000, strong_len=8. */
+ magic = RS_BLAKE2_SIG_MAGIC;
+ block_len = 1000;
+ strong_len = 8;
+ res = rs_sig_args(-1, &magic, &block_len, &strong_len);
+ assert(res == RS_DONE);
+ assert(magic == RS_BLAKE2_SIG_MAGIC);
+ assert(block_len == 1000);
+ assert(strong_len == 8);
+
+ /* old_fsize=0, magic=rs/md4, block_len=rec, strong_len=min. */
+ magic = RS_RK_MD4_SIG_MAGIC;
+ block_len = 0;
+ strong_len = -1;
+ res = rs_sig_args(0, &magic, &block_len, &strong_len);
+ assert(res == RS_DONE);
+ assert(magic == RS_RK_MD4_SIG_MAGIC);
+ assert(block_len == 256);
+ assert(strong_len == 5);
+
+ /* old_fsize=0, magic=rs/md4, block_len=1000, strong_len=8. */
+ magic = RS_MD4_SIG_MAGIC;
+ block_len = 1000;
+ strong_len = 8;
+ res = rs_sig_args(0, &magic, &block_len, &strong_len);
+ assert(res == RS_DONE);
+ assert(magic == RS_MD4_SIG_MAGIC);
+ assert(block_len == 1000);
+ assert(strong_len == 8);
+
+ /* old_fsize=100000, magic=rs/b2, block_len=rec, strong_len=min. */
+ magic = RS_BLAKE2_SIG_MAGIC;
+ block_len = 0;
+ strong_len = -1;
+ res = rs_sig_args(100000, &magic, &block_len, &strong_len);
+ assert(res == RS_DONE);
+ assert(magic == RS_BLAKE2_SIG_MAGIC);
+ assert(block_len == 316);
+ assert(strong_len == 6);
+
+ /* old_fsize=100000, magic=rk/md4, block_len=1000, strong_len=8. */
+ magic = RS_RK_MD4_SIG_MAGIC;
+ block_len = 1000;
+ strong_len = 8;
+ res = rs_sig_args(100000, &magic, &block_len, &strong_len);
+ assert(res == RS_DONE);
+ assert(magic == RS_RK_MD4_SIG_MAGIC);
+ assert(block_len == 1000);
+ assert(strong_len == 8);
+
+ /* magic=bad. */
+ magic = 1;
+ block_len = 0;
+ strong_len = 0;
+ res = rs_sig_args(-1, &magic, &block_len, &strong_len);
+ assert(res == RS_BAD_MAGIC);
+
+ /* strong_len=bad. */
+ magic = RS_RK_BLAKE2_SIG_MAGIC;
+ block_len = 0;
+ strong_len = 33;
+ res = rs_sig_args(-1, &magic, &block_len, &strong_len);
+ assert(res == RS_PARAM_ERROR);
+ magic = RS_BLAKE2_SIG_MAGIC;
+ block_len = 0;
+ strong_len = 33;
+ res = rs_sig_args(-1, &magic, &block_len, &strong_len);
+ assert(res == RS_PARAM_ERROR);
+ magic = RS_RK_MD4_SIG_MAGIC;
+ block_len = 0;
+ strong_len = 17;
+ res = rs_sig_args(-1, &magic, &block_len, &strong_len);
+ assert(res == RS_PARAM_ERROR);
+ magic = RS_MD4_SIG_MAGIC;
+ block_len = 0;
+ strong_len = 17;
+ res = rs_sig_args(-1, &magic, &block_len, &strong_len);
+ assert(res == RS_PARAM_ERROR);
+
/* Test rs_signature_init() */
- /* Default zero magic. */
- res = rs_signature_init(&sig, 0, 16, 6, -1);
+ /* magic=rec, block_len=rec, strong_len=max. */
+ res = rs_signature_init(&sig, 0, 0, 0, -1);
assert(res == RS_DONE);
assert(sig.magic == RS_RK_BLAKE2_SIG_MAGIC);
- assert(sig.block_len == 16);
- assert(sig.strong_sum_len == 6);
+ assert(sig.block_len == 2048);
+ assert(sig.strong_sum_len == 32);
assert(sig.count == 0);
assert(sig.size == 0);
assert(sig.block_sigs == NULL);
@@ -56,25 +179,33 @@ int main(int argc, char **argv)
assert(sig.calc_strong_count == 0);
#endif
- /* Blake2 magic. */
- res = rs_signature_init(&sig, RS_BLAKE2_SIG_MAGIC, 16, 6, -1);
+ /* Blake2 magic, block_len=rec, strong_len=max. */
+ res = rs_signature_init(&sig, RS_BLAKE2_SIG_MAGIC, 0, 0, -1);
assert(res == RS_DONE);
assert(sig.magic == RS_BLAKE2_SIG_MAGIC);
+ assert(sig.block_len == 2048);
+ assert(sig.strong_sum_len == 32);
- /* MD4 magic. */
- res = rs_signature_init(&sig, RS_MD4_SIG_MAGIC, 16, 6, -1);
+ /* MD4 magic, block_len=rec, strong_len=max. */
+ res = rs_signature_init(&sig, RS_MD4_SIG_MAGIC, 0, 0, -1);
assert(res == RS_DONE);
assert(sig.magic == RS_MD4_SIG_MAGIC);
+ assert(sig.block_len == 2048);
+ assert(sig.strong_sum_len == 16);
- /* RabinKarp + Blake2 magic. */
- res = rs_signature_init(&sig, RS_RK_BLAKE2_SIG_MAGIC, 16, 6, -1);
+ /* RabinKarp + Blake2 magic, block_len=16, strong_len=min. */
+ res = rs_signature_init(&sig, RS_RK_BLAKE2_SIG_MAGIC, 16, -1, -1);
assert(res == RS_DONE);
assert(sig.magic == RS_RK_BLAKE2_SIG_MAGIC);
+ assert(sig.block_len == 16);
+ assert(sig.strong_sum_len == 12);
- /* RabinKarp + MD4 magic. */
+ /* RabinKarp + MD4 magic, block_len=16, strong_len=6. */
res = rs_signature_init(&sig, RS_RK_MD4_SIG_MAGIC, 16, 6, -1);
assert(res == RS_DONE);
assert(sig.magic == RS_RK_MD4_SIG_MAGIC);
+ assert(sig.block_len == 16);
+ assert(sig.strong_sum_len == 6);
/* Bad magic. */
res = rs_signature_init(&sig, 1, 16, 6, -1);