diff options
author | Donovan Baarda <abo@minkirri.apana.org.au> | 2020-04-07 00:48:55 +1000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-04-07 00:48:55 +1000 |
commit | 2a32f5ec01796cfc0f5704fb653b0e356633c5de (patch) | |
tree | 5d065fa50539a7fe8ae0d5aa903d737d69a4dc34 | |
parent | ef519bfffb93394293162149aa7f511064bb7bab (diff) | |
parent | 6c342799f02d15c051c373fa1fc3d98d760dbfb2 (diff) | |
download | librsync-2a32f5ec01796cfc0f5704fb653b0e356633c5de.tar.gz |
Merge pull request #109 from dbaarda/dev/sigparms1
Add public rs_sig_args() function for recommend signature args from filesize.
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}) @@ -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) @@ -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; +} @@ -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 Binary files differnew file mode 100644 index 0000000..ee0cbe6 --- /dev/null +++ b/tests/signature.input/01-Rrabinkarp-Hblake2-S-1.sig diff --git a/tests/signature.input/01-Rrabinkarp-Hblake2-S0.sig b/tests/signature.input/01-Rrabinkarp-Hblake2-S0.sig Binary files differnew file mode 100644 index 0000000..7744860 --- /dev/null +++ b/tests/signature.input/01-Rrabinkarp-Hblake2-S0.sig diff --git a/tests/signature.input/01-Rrabinkarp-Hblake2-S8.sig b/tests/signature.input/01-Rrabinkarp-Hblake2-S8.sig Binary files differnew file mode 100644 index 0000000..0a19edb --- /dev/null +++ b/tests/signature.input/01-Rrabinkarp-Hblake2-S8.sig diff --git a/tests/signature.input/01-Rrabinkarp-Hmd4-S-1.sig b/tests/signature.input/01-Rrabinkarp-Hmd4-S-1.sig Binary files differnew file mode 100644 index 0000000..ea90e59 --- /dev/null +++ b/tests/signature.input/01-Rrabinkarp-Hmd4-S-1.sig diff --git a/tests/signature.input/01-Rrabinkarp-Hmd4-S0.sig b/tests/signature.input/01-Rrabinkarp-Hmd4-S0.sig Binary files differnew file mode 100644 index 0000000..aa08860 --- /dev/null +++ b/tests/signature.input/01-Rrabinkarp-Hmd4-S0.sig diff --git a/tests/signature.input/01-Rrabinkarp-Hmd4-S8.sig b/tests/signature.input/01-Rrabinkarp-Hmd4-S8.sig Binary files differnew file mode 100644 index 0000000..4c106c5 --- /dev/null +++ b/tests/signature.input/01-Rrabinkarp-Hmd4-S8.sig diff --git a/tests/signature.input/01-Rrollsum-Hblake2-S-1.sig b/tests/signature.input/01-Rrollsum-Hblake2-S-1.sig Binary files differnew file mode 100644 index 0000000..9c9faec --- /dev/null +++ b/tests/signature.input/01-Rrollsum-Hblake2-S-1.sig diff --git a/tests/signature.input/01-Rrollsum-Hblake2-S0.sig b/tests/signature.input/01-Rrollsum-Hblake2-S0.sig Binary files differnew file mode 100644 index 0000000..49966d0 --- /dev/null +++ b/tests/signature.input/01-Rrollsum-Hblake2-S0.sig diff --git a/tests/signature.input/01-Rrollsum-Hblake2-S8.sig b/tests/signature.input/01-Rrollsum-Hblake2-S8.sig Binary files differnew file mode 100644 index 0000000..43fff97 --- /dev/null +++ b/tests/signature.input/01-Rrollsum-Hblake2-S8.sig diff --git a/tests/signature.input/01-Rrollsum-Hmd4-S-1.sig b/tests/signature.input/01-Rrollsum-Hmd4-S-1.sig Binary files differnew file mode 100644 index 0000000..c02ec4c --- /dev/null +++ b/tests/signature.input/01-Rrollsum-Hmd4-S-1.sig diff --git a/tests/signature.input/01-Rrollsum-Hmd4-S0.sig b/tests/signature.input/01-Rrollsum-Hmd4-S0.sig Binary files differnew file mode 100644 index 0000000..ccd4398 --- /dev/null +++ b/tests/signature.input/01-Rrollsum-Hmd4-S0.sig diff --git a/tests/signature.input/01-Rrollsum-Hmd4-S8.sig b/tests/signature.input/01-Rrollsum-Hmd4-S8.sig Binary files differnew file mode 100644 index 0000000..28d40a6 --- /dev/null +++ b/tests/signature.input/01-Rrollsum-Hmd4-S8.sig diff --git a/tests/signature.input/rabinkarp-blake2/01.sig b/tests/signature.input/rabinkarp-blake2/01.sig Binary files differdeleted file mode 100644 index 824e129..0000000 --- a/tests/signature.input/rabinkarp-blake2/01.sig +++ /dev/null diff --git a/tests/signature.input/rabinkarp-md4/01.sig b/tests/signature.input/rabinkarp-md4/01.sig Binary files differdeleted file mode 100644 index e33b591..0000000 --- a/tests/signature.input/rabinkarp-md4/01.sig +++ /dev/null diff --git a/tests/signature.input/rollsum-blake2/01.sig b/tests/signature.input/rollsum-blake2/01.sig Binary files differdeleted file mode 100644 index f7a488f..0000000 --- a/tests/signature.input/rollsum-blake2/01.sig +++ /dev/null diff --git a/tests/signature.input/rollsum-md4/01.sig b/tests/signature.input/rollsum-md4/01.sig Binary files differdeleted file mode 100644 index 898bc51..0000000 --- a/tests/signature.input/rollsum-md4/01.sig +++ /dev/null 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); |