diff options
| author | Mattias Andrée <maandree@kth.se> | 2024-08-23 22:03:54 +0200 | 
|---|---|---|
| committer | Mattias Andrée <maandree@kth.se> | 2024-08-23 22:03:54 +0200 | 
| commit | eb943e0f73d43eb726671e522acf3a8f656b1947 (patch) | |
| tree | dd280b21ae48d0db7ceba23318eaa5e987e81eea | |
| download | libhashsum-eb943e0f73d43eb726671e522acf3a8f656b1947.tar.gz libhashsum-eb943e0f73d43eb726671e522acf3a8f656b1947.tar.bz2 libhashsum-eb943e0f73d43eb726671e522acf3a8f656b1947.tar.xz | |
First commit
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to '')
| -rw-r--r-- | .gitignore | 15 | ||||
| -rw-r--r-- | LICENSE | 15 | ||||
| -rw-r--r-- | Makefile | 103 | ||||
| -rw-r--r-- | common.h | 162 | ||||
| -rw-r--r-- | config.mk | 8 | ||||
| -rw-r--r-- | libhashsum.h | 344 | ||||
| -rw-r--r-- | libhashsum_init_hasher.c | 27 | ||||
| -rw-r--r-- | libhashsum_init_md2_hasher.c | 145 | ||||
| -rw-r--r-- | libhashsum_init_md4_hasher.c | 188 | ||||
| -rw-r--r-- | libhashsum_init_md5_hasher.c | 204 | ||||
| -rw-r--r-- | libhashsum_init_ripemd_128_hasher.c | 224 | ||||
| -rw-r--r-- | libhashsum_init_ripemd_160_hasher.c | 228 | ||||
| -rw-r--r-- | libhashsum_init_ripemd_256_hasher.c | 239 | ||||
| -rw-r--r-- | libhashsum_init_ripemd_320_hasher.c | 247 | ||||
| -rw-r--r-- | md2.c | 25 | ||||
| -rw-r--r-- | md4.c | 25 | ||||
| -rw-r--r-- | md5.c | 116 | ||||
| -rw-r--r-- | mk/linux.mk | 6 | ||||
| -rw-r--r-- | mk/macos.mk | 6 | ||||
| -rw-r--r-- | mk/windows.mk | 6 | ||||
| -rw-r--r-- | ripemd-128.c | 23 | ||||
| -rw-r--r-- | ripemd-160.c | 23 | ||||
| -rw-r--r-- | ripemd-256.c | 32 | ||||
| -rw-r--r-- | ripemd-320.c | 32 | 
24 files changed, 2443 insertions, 0 deletions
| diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..63f1b10 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +*\#* +*~ +*.o +*.a +*.lo +*.su +*.so +*.so.* +*.dll +*.dylib +*.gch +*.gcov +*.gcno +*.gcda +*.t @@ -0,0 +1,15 @@ +ISC License + +© 2024 Mattias Andrée <maandree@kth.se> + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ac60207 --- /dev/null +++ b/Makefile @@ -0,0 +1,103 @@ +.POSIX: + +CONFIGFILE = config.mk +include $(CONFIGFILE) + +OS = linux +# Linux:   linux +# Mac OS:  macos +# Windows: windows +include mk/$(OS).mk + + +LIB_MAJOR = 1 +LIB_MINOR = 0 +LIB_VERSION = $(LIB_MAJOR).$(LIB_MINOR) +LIB_NAME = hashsum + + +OBJ =\ +	libhashsum_init_hasher.o\ +	libhashsum_init_md2_hasher.o\ +	libhashsum_init_md4_hasher.o\ +	libhashsum_init_md5_hasher.o\ +	libhashsum_init_ripemd_128_hasher.o\ +	libhashsum_init_ripemd_160_hasher.o\ +	libhashsum_init_ripemd_256_hasher.o\ +	libhashsum_init_ripemd_320_hasher.o + +HDR =\ +	libhashsum.h\ +	common.h + +TEST =\ +	md2.t\ +	md4.t\ +	md5.t\ +	ripemd-128.t\ +	ripemd-160.t\ +	ripemd-256.t\ +	ripemd-320.t + +LOBJ = $(OBJ:.o=.lo) +TOBJ = $(TEST:.t=.o) + + +all: libhashsum.a libhashsum.$(LIBEXT) $(TEST) +$(OBJ): $(HDR) +$(LOBJ): $(HDR) +$(TOBJ): $(HDR) +$(TEST): libhashsum.a + +.c.o: +	$(CC) -c -o $@ $< $(CFLAGS) $(CPPFLAGS) + +.c.lo: +	$(CC) -fPIC -c -o $@ $< $(CFLAGS) $(CPPFLAGS) + +.c.t: +	$(CC) -o $@ $< libhashsum.a $(CFLAGS) $(CPPFLAGS) + +.o.t: +	$(CC) -o $@ $< libhashsum.a $(CFLAGS) $(CPPFLAGS) + +libhashsum.a: $(OBJ) +	@rm -f -- $@ +	$(AR) rc $@ $(OBJ) +	$(AR) ts $@ > /dev/null + +libhashsum.$(LIBEXT): $(LOBJ) +	$(CC) $(LIBFLAGS) -o $@ $(LOBJ) $(LDFLAGS) + +check: $(TEST) +	@set -e;\ +	for t in $(TEST); do\ +		printf '%s\n' ./$$t;\ +		$(CHECK_PREFIX) ./$$t;\ +	done + +install: libhashsum.a libhashsum.$(LIBEXT) +	mkdir -p -- "$(DESTDIR)$(PREFIX)/lib" +	mkdir -p -- "$(DESTDIR)$(PREFIX)/include" +	cp -- libhashsum.a "$(DESTDIR)$(PREFIX)/lib/" +	cp -- libhashsum.$(LIBEXT) "$(DESTDIR)$(PREFIX)/lib/libhashsum.$(LIBMINOREXT)" +	$(FIX_INSTALL_NAME) "$(DESTDIR)$(PREFIX)/lib/libhashsum.$(LIBMINOREXT)" +	ln -sf -- libhashsum.$(LIBMINOREXT) "$(DESTDIR)$(PREFIX)/lib/libhashsum.$(LIBMAJOREXT)" +	ln -sf -- libhashsum.$(LIBMAJOREXT) "$(DESTDIR)$(PREFIX)/lib/libhashsum.$(LIBEXT)" +	cp -- libhashsum.h "$(DESTDIR)$(PREFIX)/include/" + +uninstall: +	-rm -f -- "$(DESTDIR)$(PREFIX)/lib/libhashsum.a" +	-rm -f -- "$(DESTDIR)$(PREFIX)/lib/libhashsum.$(LIBMAJOREXT)" +	-rm -f -- "$(DESTDIR)$(PREFIX)/lib/libhashsum.$(LIBMINOREXT)" +	-rm -f -- "$(DESTDIR)$(PREFIX)/lib/libhashsum.$(LIBEXT)" +	-rm -f -- "$(DESTDIR)$(PREFIX)/include/libhashsum.h" + +clean: +	-rm -f -- *.o *.a *.lo *.su *.so *.so.* *.dll *.dylib *.t +	-rm -f -- *.gch *.gcov *.gcno *.gcda *.$(LIBEXT) + +.SUFFIXES: +.SUFFIXES: .lo .o .c .t + +.PHONY: all check install uninstall clean diff --git a/common.h b/common.h new file mode 100644 index 0000000..e79d6c8 --- /dev/null +++ b/common.h @@ -0,0 +1,162 @@ +/* See LICENSE file for copyright and license details. */ +#include "libhashsum.h" +#include <errno.h> +#include <string.h> + +#ifdef TEST +# include <stdlib.h> +# include <stdio.h> + +struct testcase { +	size_t input_repeat; +	unsigned extra_bits; +	const char *input; +	const char *output; +}; + +static void +hex(char *out, const unsigned char *in, size_t n) +{ +        for (; n--; in++) { +                *out++ = "0123456789abcdef"[(*in >> 4) & 15]; +                *out++ = "0123456789abcdef"[(*in >> 0) & 15]; +        } +        *out = '\0'; +} + +static char * +escape(const char *s, size_t n) +{ +	char *ret, *p; + +	ret = malloc(n * 4U + 1U); +	if (!ret) { +		perror("malloc"); +		exit(2); +	} + +	for (p = ret; n--; s++) { +		if (*s == '"' || *s == '\\') { +			*p++ = '\\'; +			*p++ = *s; +		} else if (*s == '\n') { +			*p++ = '\\'; +			*p++ = 'n'; +		} else if (*s < ' ' || *s >= 127) { +			*p++ = '\\'; +			*p++ = 'x'; +			*p++ = "0123456789abcdef"[(*s >> 4) & 15]; +			*p++ = "0123456789abcdef"[(*s >> 0) & 15]; +		} else { +			*p++ = *s; +		} +	} +	*p = '\0'; + +	return ret; +} + +static int +run_tests(const char *name, enum libhashsum_algorithm algorithm, size_t hash_size, +          struct testcase *testcases, size_t ntestcases, char hexsum[]) +{ +	struct libhashsum_hasher hasher; +	char *input, *p, bitstr[sizeof(" + b\"1234567\"")]; +	unsigned char extra_bit; +	int ok = 1, caseok; +	size_t i, j, input_string_len, input_total_len, input_size; +	size_t bits; +	for (i = 0; i < ntestcases; i++) { +		if (libhashsum_init_hasher(&hasher, algorithm)) { +			perror("libhashsum_init_hasher"); +			return 2; +		} +		if (hasher.algorithm != algorithm) { +			fprintf(stderr, "libhashsum_init_hasher returned unexpected value in .algorithm\n"); +			return 2; +		} +		if (hasher.hash_size != hash_size) { +			fprintf(stderr, "libhashsum_init_hasher returned unexpected value in .hash_size\n"); +			return 2; +		} +		if (hasher.hash_output) { +			fprintf(stderr, "libhashsum_init_hasher returned non-NULL pointer in .hash_output\n"); +			return 2; +		} +		if (!hasher.process) { +			fprintf(stderr, "libhashsum_init_hasher returned NULL pointer in .process\n"); +			return 2; +		} +		if (!hasher.finalise_const) { +			fprintf(stderr, "libhashsum_init_hasher returned NULL pointer in .finalise_const\n"); +			return 2; +		} +		if (!hasher.finalise) { +			fprintf(stderr, "libhashsum_init_hasher returned NULL pointer in .finalise\n"); +			return 2; +		} +		input_string_len = strlen(testcases[i].input); +		bits = testcases[i].extra_bits; +		if (bits) { +			if (input_string_len < (bits + 7U) / 8U) +				input_string_len = (bits + 7U) / 8U; +			bits %= 8U; +			if (bits) +				input_string_len -= 1U; +		} +		input_total_len = testcases[i].input_repeat * input_string_len; +		input_size = input_total_len + hasher.input_block_size + 1U; +		p = input = malloc(input_size); +		if (!input) { +			perror("malloc"); +			return 2; +		} +		for (j = 0; j < testcases[i].input_repeat; j++) { +			p = memcpy(p, testcases[i].input, input_string_len); +			p = &p[input_string_len]; +		} +		if (hasher.finalise(&hasher, input, input_total_len, (unsigned)bits, input_size)) { +			perror("hasher.finalise"); +			return 2; +		} +		if (!hasher.hash_output) { +			fprintf(stderr, "hasher.finalise did not set hasher.hash_output\n"); +			return 2; +		} +		free(input); +		hex(hexsum, hasher.hash_output, hasher.hash_size); +		ok &= caseok = !testcases[i].output || !strcmp(hexsum, testcases[i].output); +		input = escape(testcases[i].input, input_string_len); +		bitstr[0] = '\0'; +		if (bits) { +			extra_bit = (unsigned char)testcases[i].input[input_string_len]; +			p = bitstr; +			*p++ = ' '; +			*p++ = '+'; +			*p++ = ' '; +			*p++ = 'b'; +			*p++ = '"'; +			while (bits--) { +				*p++ = "01"[(extra_bit >> 7) & 1U]; +				extra_bit <<= 1; +			} +			*p++ = '"'; +			*p = '\0'; +		} +		if (testcases[i].input_repeat == 1) +			printf("[\033[1;%s\033[m] %s(\"%s\"%s) = %s\n", +			       caseok ? "32mPASS" : "31mFAIL", name, input, bitstr, hexsum); +		else +			printf("[\033[1;%s\033[m] %s(%zu * \"%s\"%s) = %s\n", +			       caseok ? "32mPASS" : "31mFAIL", name, testcases[i].input_repeat, input, bitstr, hexsum); +		free(input); +	} +	return !ok; +} + +#define TEST_MAIN(NAME, ID)\ +	char hexsum[LIBHASHSUM_##ID##_HASH_SIZE * 2 + 1];\ +	return run_tests(NAME, LIBHASHSUM_##ID, LIBHASHSUM_##ID##_HASH_SIZE,\ +	                 testcases, sizeof(testcases) / sizeof(*testcases), hexsum) + +#endif diff --git a/config.mk b/config.mk new file mode 100644 index 0000000..f4adf12 --- /dev/null +++ b/config.mk @@ -0,0 +1,8 @@ +PREFIX    = /usr +MANPREFIX = $(PREFIX)/share/man + +CC = c99 + +CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_GNU_SOURCE +CFLAGS   = +LDFLAGS  = diff --git a/libhashsum.h b/libhashsum.h new file mode 100644 index 0000000..460b86b --- /dev/null +++ b/libhashsum.h @@ -0,0 +1,344 @@ +/* See LICENSE file for copyright and license details. */ +#ifndef LIBHASHSUM_H +#define LIBHASHSUM_H + +#include <stddef.h> +#include <stdint.h> + + +#if defined(__GNUC__) +# define LIBHASHSUM_USERET_ __attribute__((__warn_unused_result__)) +# define LIBHASHSUM_1_NONNULL_ __attribute__((__nonnull__(1))) +#else +# define LIBHASHSUM_USERET_ +# define LIBHASHSUM_1_NONNULL_ +#endif + + +/** + * Hashing algorithm + */ +enum libhashsum_algorithm { +	LIBHASHSUM_MD2,        /**< MD2 */ +	LIBHASHSUM_MD4,        /**< MD4 */ +	LIBHASHSUM_MD5,        /**< MD5 */ +	LIBHASHSUM_RIPEMD_128, /**< RIPEMD-128 */ +	LIBHASHSUM_RIPEMD_160, /**< RIPEMD-160 */ +	LIBHASHSUM_RIPEMD_256, /**< RIPEMD-256 */ +	LIBHASHSUM_RIPEMD_320  /**< RIPEMD-320 */ +}; + + +/** + * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_MD2` + */ +#define LIBHASHSUM_MD2_HASH_SIZE 16 + +/** + * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_MD4` + */ +#define LIBHASHSUM_MD4_HASH_SIZE 16 + +/** + * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_MD5` + */ +#define LIBHASHSUM_MD5_HASH_SIZE 16 + +/** + * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_RIPEMD_128` + */ +#define LIBHASHSUM_RIPEMD_128_HASH_SIZE 16 + +/** + * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_RIPEMD_160` + */ +#define LIBHASHSUM_RIPEMD_160_HASH_SIZE 20 + +/** + * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_RIPEMD_256` + */ +#define LIBHASHSUM_RIPEMD_256_HASH_SIZE 32 + +/** + * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_RIPEMD_320` + */ +#define LIBHASHSUM_RIPEMD_320_HASH_SIZE 40 + + +/** + * Hash state + *  + * For internal use + */ +union libhashsum_state { +	struct { +		unsigned char x[32]; +		unsigned char mp[16]; +		unsigned char mz[16]; +		unsigned char sum[16]; +		unsigned t; +	} md2; + +	struct { +		union { +			uint32_t h32[4]; +			uint8_t sum[16]; +		} h; +		union { +			uint32_t m32[16]; +			uint8_t m8[64]; +		} m; +		uint64_t count; +	} md4; + +	struct { +		union { +			uint32_t h32[4]; +			uint8_t sum[16]; +		} h; +		uint8_t m[64]; +		uint32_t w[16]; +		uint64_t count; +	} md5; + +	struct { +		union { +			uint32_t h32[4]; +			uint8_t sum[16]; +		} h; +		union { +			uint32_t m32[16]; +			uint8_t m8[64]; +		} m; +		uint64_t count; +	} ripemd_128; + +	struct { +		union { +			uint32_t h32[5]; +			uint8_t sum[20]; +		} h; +		union { +			uint32_t m32[16]; +			uint8_t m8[64]; +		} m; +		uint32_t w1[5]; +		uint32_t w2[5]; +		uint64_t count; +	} ripemd_160; + +	struct { +		union { +			uint32_t h32[8]; +			uint8_t sum[32]; +		} h; +		union { +			uint32_t m32[16]; +			uint8_t m8[64]; +		} m; +		uint64_t count; +	} ripemd_256; + +	struct { +		union { +			uint32_t h32[10]; +			uint8_t sum[40]; +		} h; +		union { +			uint32_t m32[16]; +			uint8_t m8[64]; +		} m; +		uint32_t w1[5]; +		uint32_t w2[5]; +		uint64_t count; +	} ripemd_320; +}; + + +/** + * Message hash functions and state + */ +struct libhashsum_hasher { +	/** +	 * The used hash algorithm +	 */ +	enum libhashsum_algorithm algorithm; + +	/** +	 * The number of bytes required for each +	 * call to `.process_block` +	 */ +	size_t input_block_size; + +	/** +	 * The number of bytes in the resulting hash +	 */ +	size_t hash_size; + +	/** +	 * The hash +	 *  +	 * This will be set to `NULL` when the structure +	 * is initialised, but will be set to a pointer +	 * to a buffer inside `.state` once `.finalise_const` +	 * or `.finalise` has been called +	 */ +	unsigned char *hash_output; + +	/** +	 * Whether the algorithm supports non-whole octet input +	 */ +	unsigned char supports_non_whole_bytes; + +	/** +	 * Update the hash state given additional +	 * input data +	 *  +	 * @param   this   The object containing this function pointer +	 * @param   data   The new input data +	 * @param   bytes  The number of bytes available in `data` +	 * @return         The number of bytes processed from `data` +	 */ +	LIBHASHSUM_USERET_ LIBHASHSUM_1_NONNULL_ +	size_t (*process)(struct libhashsum_hasher *this, const void *data, size_t bytes); + +	/** +	 * Update the hash state given it's final +	 * input data +	 *  +	 * @param   this   The object containing this function pointer +	 * @param   data   The new input data +	 * @param   bytes  The number of bytes available in `data` +	 * @return         0 on success, -1 on failure +	 *  +	 * @throws  EINVAL  `extra_bits` is greater than 7 +	 * @throws  EINVAL  `extra_bits` is non-zero but `.supports_non_whole_bytes` is 0 +	 */ +	LIBHASHSUM_1_NONNULL_ +	int (*finalise_const)(struct libhashsum_hasher *this, const void *data, unsigned extra_bits, size_t bytes); + +	/** +	 * Update the hash state given it's final +	 * input data +	 *  +	 * @param   this   The object containing this function pointer +	 * @param   data   The new input data, the function may rewrite it's content +	 * @param   bytes  The number of bytes available in `data` for reading +	 * @param   size   `bytes` plus any number of additional bytes available +	 *                 for the function to write additional data block padding +	 * @return         0 on success, -1 on failure +	 *  +	 * @throws  EINVAL  `extra_bits` is greater than 7 +	 * @throws  EINVAL  `extra_bits` is non-zero but `.supports_non_whole_bytes` is 0 +	 */ +	LIBHASHSUM_1_NONNULL_ +	int (*finalise)(struct libhashsum_hasher *this, void *data, size_t bytes, unsigned extra_bits, size_t size); + +	/** +	 * The hash state +	 *  +	 * For internal use +	 */ +	union libhashsum_state state; +}; + + +/** + * Create an initialised state for a hash algorithm + * and return hash functions and details + *  + * @param   this       The output parameter for the functions, details, and state + * @param   algorithm  The hashing algorithm + * @return             0 on success, -1 on failure + *  + * @throws  EINVAL  `algorithm` is unsupported + */ +LIBHASHSUM_1_NONNULL_ +int libhashsum_init_hasher(struct libhashsum_hasher *this, enum libhashsum_algorithm algorithm); + +/** + * Create an initialised state for a MD2 + * and return hash functions and details + *  + * @param   this  The output parameter for the functions, details, and state + * @return        0 on success, -1 on failure + *  + * Failure isn't actually possible, so this function always return 0 + */ +LIBHASHSUM_1_NONNULL_ +int libhashsum_init_md2_hasher(struct libhashsum_hasher *this); + +/** + * Create an initialised state for a MD4 + * and return hash functions and details + *  + * @param   this  The output parameter for the functions, details, and state + * @return        0 on success, -1 on failure + *  + * Failure isn't actually possible, so this function always return 0 + */ +LIBHASHSUM_1_NONNULL_ +int libhashsum_init_md4_hasher(struct libhashsum_hasher *this); + +/** + * Create an initialised state for a MD5 + * and return hash functions and details + *  + * @param   this  The output parameter for the functions, details, and state + * @return        0 on success, -1 on failure + *  + * Failure isn't actually possible, so this function always return 0 + */ +LIBHASHSUM_1_NONNULL_ +int libhashsum_init_md5_hasher(struct libhashsum_hasher *this); + +/** + * Create an initialised state for a RIPEMD-128 + * and return hash functions and details + *  + * @param   this  The output parameter for the functions, details, and state + * @return        0 on success, -1 on failure + *  + * Failure isn't actually possible, so this function always return 0 + */ +LIBHASHSUM_1_NONNULL_ +int libhashsum_init_ripemd_128_hasher(struct libhashsum_hasher *this); + +/** + * Create an initialised state for a RIPEMD-160 + * and return hash functions and details + *  + * @param   this  The output parameter for the functions, details, and state + * @return        0 on success, -1 on failure + *  + * Failure isn't actually possible, so this function always return 0 + */ +LIBHASHSUM_1_NONNULL_ +int libhashsum_init_ripemd_160_hasher(struct libhashsum_hasher *this); + +/** + * Create an initialised state for a RIPEMD-256 + * and return hash functions and details + *  + * @param   this  The output parameter for the functions, details, and state + * @return        0 on success, -1 on failure + *  + * Failure isn't actually possible, so this function always return 0 + */ +LIBHASHSUM_1_NONNULL_ +int libhashsum_init_ripemd_256_hasher(struct libhashsum_hasher *this); + +/** + * Create an initialised state for a RIPEMD-320 + * and return hash functions and details + *  + * @param   this  The output parameter for the functions, details, and state + * @return        0 on success, -1 on failure + *  + * Failure isn't actually possible, so this function always return 0 + */ +LIBHASHSUM_1_NONNULL_ +int libhashsum_init_ripemd_320_hasher(struct libhashsum_hasher *this); + + +#endif diff --git a/libhashsum_init_hasher.c b/libhashsum_init_hasher.c new file mode 100644 index 0000000..fc39758 --- /dev/null +++ b/libhashsum_init_hasher.c @@ -0,0 +1,27 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +int +libhashsum_init_hasher(struct libhashsum_hasher *hasher, enum libhashsum_algorithm algorithm) +{ +	switch (algorithm) { +	case LIBHASHSUM_MD2: +		return libhashsum_init_md2_hasher(hasher); +	case LIBHASHSUM_MD4: +		return libhashsum_init_md4_hasher(hasher); +	case LIBHASHSUM_MD5: +		return libhashsum_init_md5_hasher(hasher); +	case LIBHASHSUM_RIPEMD_128: +		return libhashsum_init_ripemd_128_hasher(hasher); +	case LIBHASHSUM_RIPEMD_160: +		return libhashsum_init_ripemd_160_hasher(hasher); +	case LIBHASHSUM_RIPEMD_256: +		return libhashsum_init_ripemd_256_hasher(hasher); +	case LIBHASHSUM_RIPEMD_320: +		return libhashsum_init_ripemd_320_hasher(hasher); +	default: +		errno = EINVAL; +		return -1; +	} +} diff --git a/libhashsum_init_md2_hasher.c b/libhashsum_init_md2_hasher.c new file mode 100644 index 0000000..9c7148a --- /dev/null +++ b/libhashsum_init_md2_hasher.c @@ -0,0 +1,145 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +static const unsigned char S[] = { +	0x29, 0x2e, 0x43, 0xc9, 0xa2, 0xd8, 0x7c, 0x01, 0x3d, 0x36, 0x54, 0xa1, 0xec, 0xf0, 0x06, 0x13, +	0x62, 0xa7, 0x05, 0xf3, 0xc0, 0xc7, 0x73, 0x8c, 0x98, 0x93, 0x2b, 0xd9, 0xbc, 0x4c, 0x82, 0xca, +	0x1e, 0x9b, 0x57, 0x3c, 0xfd, 0xd4, 0xe0, 0x16, 0x67, 0x42, 0x6f, 0x18, 0x8a, 0x17, 0xe5, 0x12, +	0xbe, 0x4e, 0xc4, 0xd6, 0xda, 0x9e, 0xde, 0x49, 0xa0, 0xfb, 0xf5, 0x8e, 0xbb, 0x2f, 0xee, 0x7a, +	0xa9, 0x68, 0x79, 0x91, 0x15, 0xb2, 0x07, 0x3f, 0x94, 0xc2, 0x10, 0x89, 0x0b, 0x22, 0x5f, 0x21, +	0x80, 0x7f, 0x5d, 0x9a, 0x5a, 0x90, 0x32, 0x27, 0x35, 0x3e, 0xcc, 0xe7, 0xbf, 0xf7, 0x97, 0x03, +	0xff, 0x19, 0x30, 0xb3, 0x48, 0xa5, 0xb5, 0xd1, 0xd7, 0x5e, 0x92, 0x2a, 0xac, 0x56, 0xaa, 0xc6, +	0x4f, 0xb8, 0x38, 0xd2, 0x96, 0xa4, 0x7d, 0xb6, 0x76, 0xfc, 0x6b, 0xe2, 0x9c, 0x74, 0x04, 0xf1, +	0x45, 0x9d, 0x70, 0x59, 0x64, 0x71, 0x87, 0x20, 0x86, 0x5b, 0xcf, 0x65, 0xe6, 0x2d, 0xa8, 0x02, +	0x1b, 0x60, 0x25, 0xad, 0xae, 0xb0, 0xb9, 0xf6, 0x1c, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7e, 0x0f, +	0x55, 0x47, 0xa3, 0x23, 0xdd, 0x51, 0xaf, 0x3a, 0xc3, 0x5c, 0xf9, 0xce, 0xba, 0xc5, 0xea, 0x26, +	0x2c, 0x53, 0x0d, 0x6e, 0x85, 0x28, 0x84, 0x09, 0xd3, 0xdf, 0xcd, 0xf4, 0x41, 0x81, 0x4d, 0x52, +	0x6a, 0xdc, 0x37, 0xc8, 0x6c, 0xc1, 0xab, 0xfa, 0x24, 0xe1, 0x7b, 0x08, 0x0c, 0xbd, 0xb1, 0x4a, +	0x78, 0x88, 0x95, 0x8b, 0xe3, 0x63, 0xe8, 0x6d, 0xe9, 0xcb, 0xd5, 0xfe, 0x3b, 0x00, 0x1d, 0x39, +	0xf2, 0xef, 0xb7, 0x0e, 0x66, 0x58, 0xd0, 0xe4, 0xa6, 0x77, 0x72, 0xf8, 0xeb, 0x75, 0x4b, 0x0a, +	0x31, 0x44, 0x50, 0xb4, 0x8f, 0xed, 0x1f, 0x1a, 0xdb, 0x99, 0x8d, 0x33, 0x9f, 0x11, 0x83, 0x14}; + + +static void +process_block(const unsigned char *m, unsigned char *c, unsigned char *x) +{ +	unsigned i, j, t; + +	for (i = 0; i < 16U; i++) { +		x[i] = m[i]; +		x[i + 16U] = m[i] ^ c[i]; +	} + +	t = 0; +	for (i = 0; i < 18U; i++) { +		for (j = 0; j < 16U; j++) +			t = c[j] ^= S[t]; +		for (j = 0; j < 32U; j++) +			t = x[j] ^= S[t]; +		t = (t + i) & 0xFFU; +	} +} + + +LIBHASHSUM_1_NONNULL_ +static size_t +process(struct libhashsum_hasher *this, const void *data, size_t bytes) +{ +	const unsigned char *m = data; +	size_t off = 0; +	unsigned i, t; + +	t = this->state.md2.t; +	for (; bytes - off >= 16U; off += 16U) { +		process_block(&m[off], this->state.md2.sum, this->state.md2.x); +		for (i = 0; i < 16U; i++) +			t = this->state.md2.mz[i] ^= S[m[off + i] ^ t]; +	} +	this->state.md2.t = t; + +	return off; +} + + +LIBHASHSUM_1_NONNULL_ +static int +finalise_common(struct libhashsum_hasher *this, unsigned char *m, size_t bytes, unsigned extra_bits) +{ +	unsigned i, t; + +	if (extra_bits) { +		errno = EINVAL; +		return -1; +	} + +	memset(&m[bytes], 16 - (int)bytes, 16U - bytes); + +	t = this->state.md2.t; +	process_block(m, this->state.md2.sum, this->state.md2.x); +	for (i = 0; i < 16U; i++) +		t = this->state.md2.mz[i] ^= S[m[i] ^ t]; +	this->state.md2.t = t; + +	process_block(this->state.md2.mz, this->state.md2.sum, this->state.md2.x); + +	memset(this->state.md2.x, 0, sizeof(this->state.md2.x)); +	memset(this->state.md2.mp, 0, sizeof(this->state.md2.mp)); +	memset(this->state.md2.mz, 0, sizeof(this->state.md2.mz)); +	this->state.md2.t = 0; + +	this->hash_output = this->state.md2.sum; +	return 0; +} + + +LIBHASHSUM_1_NONNULL_ +static int +finalise_const(struct libhashsum_hasher *this, const void *data, unsigned extra_bits, size_t bytes) +{ +	const unsigned char *m = data; +	size_t r; + +	r = process(this, m, bytes); +	m = &m[r]; +	bytes -= r; + +	memcpy(this->state.md2.mp, m, bytes + (size_t)(extra_bits > 0U)); +	return finalise_common(this, this->state.md2.mp, bytes, extra_bits); +} + + +LIBHASHSUM_1_NONNULL_ +static int +finalise(struct libhashsum_hasher *this, void *data, size_t bytes, unsigned extra_bits, size_t size) +{ +	unsigned char *m = data; +	size_t r; + +	r = process(this, m, bytes); +	m = &m[r]; +	bytes -= r; +	size -= r; + +	if (size < 16U) { +		memcpy(this->state.md2.mp, m, bytes + (size_t)(extra_bits > 0U)); +		m = this->state.md2.mp; +	} +	return finalise_common(this, m, bytes, extra_bits); +} + + +int +libhashsum_init_md2_hasher(struct libhashsum_hasher *this) +{ +	this->algorithm = LIBHASHSUM_MD2; +	this->input_block_size = 16U; +	this->hash_size = sizeof(this->state.md2.sum); +	this->hash_output = NULL; +	this->supports_non_whole_bytes = 0; +	this->process = &process; +	this->finalise_const = &finalise_const; +	this->finalise = &finalise; +	memset(&this->state.md2, 0, sizeof(this->state.md2)); +	return 0; +} diff --git a/libhashsum_init_md4_hasher.c b/libhashsum_init_md4_hasher.c new file mode 100644 index 0000000..9bba540 --- /dev/null +++ b/libhashsum_init_md4_hasher.c @@ -0,0 +1,188 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +#define LETO32(X)\ +	(((uint32_t)(X)[0] <<  0) |\ +	 ((uint32_t)(X)[1] <<  8) |\ +	 ((uint32_t)(X)[2] << 16) |\ +	 ((uint32_t)(X)[3] << 24)) + + +static uint32_t rol32(uint32_t n, int k) { return (n << k) | (n >> (32 - k)); } /* k != 0, 32 */ + + +static void +process_block(uint32_t h[4], const uint32_t *x) +{ +#define FGH(A, BCD, I, C, S) (A = rol32(x[I] + A + (BCD) + UINT32_C(C), S)) +#define F(A, B, C, D, I, S) FGH(A, (B & C) | (~B & D),          I, 0x00000000, S) +#define G(A, B, C, D, I, S) FGH(A, (B & C) | (B & D) | (C & D), I, 0x5a827999, S) +#define H(A, B, C, D, I, S) FGH(A, B ^ C ^ D,                   I, 0x6ed9eba1, S) + +#define FOUR(M, I1, S1, I2, S2, I3, S3, I4, S4)\ +	(M(a, b, c, d, I1, S1),\ +	 M(d, a, b, c, I2, S2),\ +	 M(c, d, a, b, I3, S3),\ +	 M(b, c, d, a, I4, S4)) + +#define SIXTEEN(F, S1, S2, S3, S4, I11, I12, I13, I14,\ +                                   I21, I22, I23, I24,\ +                                   I31, I32, I33, I34,\ +                                   I41, I42, I43, I44)\ +	(FOUR(F, I11, S1, I12, S2, I13, S3, I14, S4),\ +	 FOUR(F, I21, S1, I22, S2, I23, S3, I24, S4),\ +	 FOUR(F, I31, S1, I32, S2, I33, S3, I34, S4),\ +	 FOUR(F, I41, S1, I42, S2, I43, S3, I44, S4)) + +	uint32_t a = h[0]; +	uint32_t b = h[1]; +	uint32_t c = h[2]; +	uint32_t d = h[3]; + +	SIXTEEN(F, 3, 7, 11, 19,  0,  1,  2,  3, +	                          4,  5,  6,  7, +	                          8,  9, 10, 11, +	                         12, 13, 14, 15); + +	SIXTEEN(G, 3, 5, 9, 13,   0,  4,  8, 12, +	                          1,  5,  9, 13, +	                          2,  6, 10, 14, +	                          3,  7, 11, 15); + +	SIXTEEN(H, 3, 9, 11, 15,  0,  8,  4, 12, +	                          2, 10,  6, 14, +	                          1,  9,  5, 13, +	                          3, 11,  7, 15); + +	h[0] += a; +	h[1] += b; +	h[2] += c; +	h[3] += d; +} + + +LIBHASHSUM_1_NONNULL_ +static size_t +process(struct libhashsum_hasher *this, const void *data, size_t bytes) +{ +	const uint8_t *m = data; +	size_t off = 0; +	size_t i; + +	for (; bytes - off >= 64U; off += 64U) { +		for (i = 0; i < 16U; i++) +			this->state.md4.m.m32[i] = LETO32(&m[off + i * 4U]); +		process_block(this->state.md4.h.h32, this->state.md4.m.m32); +	} + +	this->state.md4.count += off; +	return off; +} + + +LIBHASHSUM_1_NONNULL_ +static int +finalise_common(struct libhashsum_hasher *this, uint8_t *m, size_t bytes, unsigned extra_bits) +{ +	uint8_t mask; +	unsigned i; +	register uint32_t hi; + +	if (extra_bits > 7U) { +		errno = EINVAL; +		return -1; +	} + +	this->state.md4.count += bytes; +	this->state.md4.count *= 8U; +	this->state.md4.count += (size_t)extra_bits; + +	memset(&m[bytes], 0, 64U - bytes); +	mask = (uint8_t)(1U << (7U - extra_bits)); +	m[bytes] |= mask; +	m[bytes] &= (uint8_t)~(mask - 1U); /* keep high bits */ +	for (i = 0; i < 14; i++) +		this->state.md4.m.m32[i] = LETO32(&m[i * 4U]); + +	if (bytes > 55U) { +		this->state.md4.m.m32[14] = LETO32(&m[14U * 4U]); +		this->state.md4.m.m32[15] = LETO32(&m[15U * 4U]); +		process_block(this->state.md4.h.h32, this->state.md4.m.m32); +		memset(this->state.md4.m.m32, 0, 56U); +	} + +	this->state.md4.m.m32[14] = (uint32_t)(this->state.md4.count >>  0); +	this->state.md4.m.m32[15] = (uint32_t)(this->state.md4.count >> 32); +	process_block(this->state.md4.h.h32, this->state.md4.m.m32); + +	memset(&this->state.md4.m, 0, sizeof(this->state.md4.m)); +	this->state.md4.count = 0; + +	for (i = 0; i < 4U; i++) { +		hi = this->state.md4.h.h32[i]; +		this->state.md4.h.sum[i * 4U + 0U] = (uint8_t)(hi >>  0); +		this->state.md4.h.sum[i * 4U + 1U] = (uint8_t)(hi >>  8); +		this->state.md4.h.sum[i * 4U + 2U] = (uint8_t)(hi >> 16); +		this->state.md4.h.sum[i * 4U + 3U] = (uint8_t)(hi >> 24); +	} + +	this->hash_output = this->state.md4.h.sum; +	return 0; +} + + +LIBHASHSUM_1_NONNULL_ +static int +finalise_const(struct libhashsum_hasher *this, const void *data, unsigned extra_bits, size_t bytes) +{ +	const uint8_t *m = data; +	size_t r; + +	r = process(this, m, bytes); +	m = &m[r]; +	bytes -= r; + +	memcpy(this->state.md4.m.m8, m, bytes + (size_t)(extra_bits > 0U)); +	return finalise_common(this, this->state.md4.m.m8, bytes, extra_bits); +} + + +LIBHASHSUM_1_NONNULL_ +static int +finalise(struct libhashsum_hasher *this, void *data, size_t bytes, unsigned extra_bits, size_t size) +{ +	uint8_t *m = data; +	size_t r; + +	r = process(this, m, bytes); +	m = &m[r]; +	bytes -= r; +	size -= r; + +	if (size < 64U) { +		memcpy(this->state.md4.m.m8, m, bytes + (size_t)(extra_bits > 0U)); +		m = this->state.md4.m.m8; +	} +	return finalise_common(this, m, bytes, extra_bits); +} + + +int +libhashsum_init_md4_hasher(struct libhashsum_hasher *this) +{ +	this->algorithm = LIBHASHSUM_MD4; +	this->input_block_size = 64U; +	this->hash_size = sizeof(this->state.md4.h.sum); +	this->hash_output = NULL; +	this->supports_non_whole_bytes = 1; +	this->process = &process; +	this->finalise_const = &finalise_const; +	this->finalise = &finalise; +	memset(&this->state.md4, 0, sizeof(this->state.md4)); +	this->state.md4.h.h32[0] = UINT32_C(0x67452301); +	this->state.md4.h.h32[1] = UINT32_C(0xefcdab89); +	this->state.md4.h.h32[2] = UINT32_C(0x98badcfe); +	this->state.md4.h.h32[3] = UINT32_C(0x10325476); +	return 0; +} diff --git a/libhashsum_init_md5_hasher.c b/libhashsum_init_md5_hasher.c new file mode 100644 index 0000000..4dcd363 --- /dev/null +++ b/libhashsum_init_md5_hasher.c @@ -0,0 +1,204 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +static const uint32_t S[64] = { +	0xd76aa478UL, 0xe8c7b756UL, 0x242070dbUL, 0xc1bdceeeUL, 0xf57c0fafUL, 0x4787c62aUL, 0xa8304613UL, 0xfd469501UL, +	0x698098d8UL, 0x8b44f7afUL, 0xffff5bb1UL, 0x895cd7beUL, 0x6b901122UL, 0xfd987193UL, 0xa679438eUL, 0x49b40821UL, +	0xf61e2562UL, 0xc040b340UL, 0x265e5a51UL, 0xe9b6c7aaUL, 0xd62f105dUL, 0x02441453UL, 0xd8a1e681UL, 0xe7d3fbc8UL, +	0x21e1cde6UL, 0xc33707d6UL, 0xf4d50d87UL, 0x455a14edUL, 0xa9e3e905UL, 0xfcefa3f8UL, 0x676f02d9UL, 0x8d2a4c8aUL, +	0xfffa3942UL, 0x8771f681UL, 0x6d9d6122UL, 0xfde5380cUL, 0xa4beea44UL, 0x4bdecfa9UL, 0xf6bb4b60UL, 0xbebfbc70UL, +	0x289b7ec6UL, 0xeaa127faUL, 0xd4ef3085UL, 0x04881d05UL, 0xd9d4d039UL, 0xe6db99e5UL, 0x1fa27cf8UL, 0xc4ac5665UL, +	0xf4292244UL, 0x432aff97UL, 0xab9423a7UL, 0xfc93a039UL, 0x655b59c3UL, 0x8f0ccc92UL, 0xffeff47dUL, 0x85845dd1UL, +	0x6fa87e4fUL, 0xfe2ce6e0UL, 0xa3014314UL, 0x4e0811a1UL, 0xf7537e82UL, 0xbd3af235UL, 0x2ad7d2bbUL, 0xeb86d391UL +}; + + +static uint32_t rol32(uint32_t n, int k) { return (n << k) | (n >> (32 - k)); } /* k != 0, 32 */ + + +static void +process_block(uint32_t h[4], const uint8_t *x, uint32_t w[16]) +{ +#define F(x, y, z) (z ^ (x & (y ^ z))) +#define G(x, y, z) (y ^ (z & (y ^ x))) +#define H(x, y, z) (x ^ y ^ z) +#define I(x, y, z) (y ^ (x | ~z)) +#define FF(a, b, c, d, w, s, t) (a += F(b, c, d) + w + t, a = rol32(a, s) + b) +#define GG(a, b, c, d, w, s, t) (a += G(b, c, d) + w + t, a = rol32(a, s) + b) +#define HH(a, b, c, d, w, s, t) (a += H(b, c, d) + w + t, a = rol32(a, s) + b) +#define II(a, b, c, d, w, s, t) (a += I(b, c, d) + w + t, a = rol32(a, s) + b) + +	register uint32_t a, b, c, d; +	unsigned i; + +	for (i = 0; i < 16U; i++) { +		w[i]  = (uint32_t)x[4U * i + 0U] <<  0; +		w[i] |= (uint32_t)x[4U * i + 1U] <<  8; +		w[i] |= (uint32_t)x[4U * i + 2U] << 16; +		w[i] |= (uint32_t)x[4U * i + 3U] << 24; +	} + +	a = h[0]; +	b = h[1]; +	c = h[2]; +	d = h[3]; + +	i = 0U; +	while (i < 16U) { +		FF(a, b, c, d, w[i],  7, S[i]), i++; +		FF(d, a, b, c, w[i], 12, S[i]), i++; +		FF(c, d, a, b, w[i], 17, S[i]), i++; +		FF(b, c, d, a, w[i], 22, S[i]), i++; +	} +	while (i < 32U) { +		GG(a, b, c, d, w[(5 * i + 1) % 16],  5, S[i]), i++; +		GG(d, a, b, c, w[(5 * i + 1) % 16],  9, S[i]), i++; +		GG(c, d, a, b, w[(5 * i + 1) % 16], 14, S[i]), i++; +		GG(b, c, d, a, w[(5 * i + 1) % 16], 20, S[i]), i++; +	} +	while (i < 48U) { +		HH(a, b, c, d, w[(3 * i + 5) % 16],  4, S[i]), i++; +		HH(d, a, b, c, w[(3 * i + 5) % 16], 11, S[i]), i++; +		HH(c, d, a, b, w[(3 * i + 5) % 16], 16, S[i]), i++; +		HH(b, c, d, a, w[(3 * i + 5) % 16], 23, S[i]), i++; +	} +	while (i < 64U) { +		II(a, b, c, d, w[7 * i % 16],  6, S[i]), i++; +		II(d, a, b, c, w[7 * i % 16], 10, S[i]), i++; +		II(c, d, a, b, w[7 * i % 16], 15, S[i]), i++; +		II(b, c, d, a, w[7 * i % 16], 21, S[i]), i++; +	} + +	h[0] += a; +	h[1] += b; +	h[2] += c; +	h[3] += d; +} + + +LIBHASHSUM_1_NONNULL_ +static size_t +process(struct libhashsum_hasher *this, const void *data, size_t bytes) +{ +	const uint8_t *m = data; +	size_t off = 0; + +	for (; bytes - off >= 64U; off += 64U) +		process_block(this->state.md5.h.h32, &m[off], this->state.md5.w); + +	this->state.md5.count += off; +	return off; +} + + +LIBHASHSUM_1_NONNULL_ +static int +finalise_common(struct libhashsum_hasher *this, uint8_t *m, size_t bytes, unsigned extra_bits) +{ +	uint8_t mask; +	unsigned i; +	register uint32_t hi; + +	if (extra_bits > 7U) { +		errno = EINVAL; +		return -1; +	} + +	this->state.md5.count += bytes; +	this->state.md5.count *= 8U; +	this->state.md5.count += (size_t)extra_bits; + +	mask = (uint8_t)(1U << (7U - extra_bits)); +	m[bytes] |= mask; +	m[bytes] &= (uint8_t)~(mask - 1U); /* keep high bits */ +	bytes++; + +	if (bytes > 56U) { +		memset(&m[bytes], 0, 64U - bytes); +		process_block(this->state.md5.h.h32, m, this->state.md5.w); +		bytes = 0; +	} + +	memset(&m[bytes], 0, 56U - bytes); +	m[56] = (uint8_t)(this->state.md5.count >>  0); +	m[57] = (uint8_t)(this->state.md5.count >>  8); +	m[58] = (uint8_t)(this->state.md5.count >> 16); +	m[59] = (uint8_t)(this->state.md5.count >> 24); +	m[60] = (uint8_t)(this->state.md5.count >> 32); +	m[61] = (uint8_t)(this->state.md5.count >> 40); +	m[62] = (uint8_t)(this->state.md5.count >> 48); +	m[63] = (uint8_t)(this->state.md5.count >> 56); +	process_block(this->state.md5.h.h32, m, this->state.md5.w); + +	memset(this->state.md5.m, 0, sizeof(this->state.md5.m)); +	memset(this->state.md5.w, 0, sizeof(this->state.md5.w)); +	this->state.md5.count = 0; + +	for (i = 0; i < 4U; i++) { +		hi = this->state.md5.h.h32[i]; +		this->state.md5.h.sum[i * 4U + 0U] = (uint8_t)(hi >>  0); +		this->state.md5.h.sum[i * 4U + 1U] = (uint8_t)(hi >>  8); +		this->state.md5.h.sum[i * 4U + 2U] = (uint8_t)(hi >> 16); +		this->state.md5.h.sum[i * 4U + 3U] = (uint8_t)(hi >> 24); +	} + +	this->hash_output = this->state.md5.h.sum; +	return 0; +} + + +LIBHASHSUM_1_NONNULL_ +static int +finalise_const(struct libhashsum_hasher *this, const void *data, unsigned extra_bits, size_t bytes) +{ +	const uint8_t *m = data; +	size_t r; + +	r = process(this, m, bytes); +	m = &m[r]; +	bytes -= r; + +	memcpy(this->state.md5.m, m, bytes + (size_t)(extra_bits > 0U)); +	return finalise_common(this, this->state.md5.m, bytes, extra_bits); +} + + +LIBHASHSUM_1_NONNULL_ +static int +finalise(struct libhashsum_hasher *this, void *data, size_t bytes, unsigned extra_bits, size_t size) +{ +	uint8_t *m = data; +	size_t r; + +	r = process(this, m, bytes); +	m = &m[r]; +	bytes -= r; +	size -= r; + +	if (size < 64U) { +		memcpy(this->state.md5.m, m, bytes + (size_t)(extra_bits > 0U)); +		m = this->state.md5.m; +	} +	return finalise_common(this, m, bytes, extra_bits); +} + + +int +libhashsum_init_md5_hasher(struct libhashsum_hasher *this) +{ +	this->algorithm = LIBHASHSUM_MD5; +	this->input_block_size = 64U; +	this->hash_size = sizeof(this->state.md5.h.sum); +	this->hash_output = NULL; +	this->supports_non_whole_bytes = 1; +	this->process = &process; +	this->finalise_const = &finalise_const; +	this->finalise = &finalise; +	memset(&this->state.md5, 0, sizeof(this->state.md5)); +	this->state.md5.h.h32[0] = UINT32_C(0x67452301); +	this->state.md5.h.h32[1] = UINT32_C(0xefcdab89); +	this->state.md5.h.h32[2] = UINT32_C(0x98badcfe); +	this->state.md5.h.h32[3] = UINT32_C(0x10325476); +	return 0; +} diff --git a/libhashsum_init_ripemd_128_hasher.c b/libhashsum_init_ripemd_128_hasher.c new file mode 100644 index 0000000..71f0f29 --- /dev/null +++ b/libhashsum_init_ripemd_128_hasher.c @@ -0,0 +1,224 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +#define LETO32(X)\ +	(((uint32_t)(X)[0] <<  0) |\ +	 ((uint32_t)(X)[1] <<  8) |\ +	 ((uint32_t)(X)[2] << 16) |\ +	 ((uint32_t)(X)[3] << 24)) + + +static uint32_t rol32(uint32_t n, int k) { return (n << k) | (n >> (32 - k)); } /* k != 0, 32 */ + + +static void +process_block(uint32_t h[4], const uint32_t *x) +{ +#define F0(X, Y, Z) (X ^ Y ^ Z)  +#define G0(X, Y, Z) ((X & Y) | (~X & Z))  +#define H0(X, Y, Z) ((X | ~Y) ^ Z) +#define I0(X, Y, Z) ((X & Z) | (Y & ~Z))  + +#define F1(A, B, C, D, I, S) (A = rol32(F0(B, C, D) + A + x[I] + UINT32_C(0x00000000), S)) +#define G1(A, B, C, D, I, S) (A = rol32(G0(B, C, D) + A + x[I] + UINT32_C(0x5a827999), S)) +#define H1(A, B, C, D, I, S) (A = rol32(H0(B, C, D) + A + x[I] + UINT32_C(0x6ed9eba1), S)) +#define I1(A, B, C, D, I, S) (A = rol32(I0(B, C, D) + A + x[I] + UINT32_C(0x8f1bbcdc), S)) +#define F2(A, B, C, D, I, S) (A = rol32(F0(B, C, D) + A + x[I] + UINT32_C(0x00000000), S)) +#define G2(A, B, C, D, I, S) (A = rol32(G0(B, C, D) + A + x[I] + UINT32_C(0x6d703ef3), S)) +#define H2(A, B, C, D, I, S) (A = rol32(H0(B, C, D) + A + x[I] + UINT32_C(0x5c4dd124), S)) +#define I2(A, B, C, D, I, S) (A = rol32(I0(B, C, D) + A + x[I] + UINT32_C(0x50a28be6), S)) + +#define FOUR(P, M, I1, S1, I2, S2, I3, S3, I4, S4)\ +	(M(a##P, b##P, c##P, d##P, I1, S1),\ +	 M(d##P, a##P, b##P, c##P, I2, S2),\ +	 M(c##P, d##P, a##P, b##P, I3, S3),\ +	 M(b##P, c##P, d##P, a##P, I4, S4)) + +#define SIXTEEN(P, F, I11, I12, I13, I14,  S11, S12, S13, S14,\ +                      I21, I22, I23, I24,  S21, S22, S23, S24,\ +                      I31, I32, I33, I34,  S31, S32, S33, S34,\ +                      I41, I42, I43, I44,  S41, S42, S43, S44)\ +	(FOUR(P, F##P, I11, S11, I12, S12, I13, S13, I14, S14),\ +	 FOUR(P, F##P, I21, S21, I22, S22, I23, S23, I24, S24),\ +	 FOUR(P, F##P, I31, S31, I32, S32, I33, S33, I34, S34),\ +	 FOUR(P, F##P, I41, S41, I42, S42, I43, S43, I44, S44)) + +	register uint32_t a1 = h[0], a2 = h[0]; +	register uint32_t b1 = h[1], b2 = h[1]; +	register uint32_t c1 = h[2], c2 = h[2]; +	register uint32_t d1 = h[3], d2 = h[3]; +	register uint32_t htmp; + +	SIXTEEN(1, F,  0,  1,  2,  3,   11, 14, 15, 12, +	               4,  5,  6,  7,    5,  8,  7,  9, +	               8,  9, 10, 11,   11, 13, 14, 15, +	              12, 13, 14, 15,    6,  7,  9,  8); + +	SIXTEEN(1, G,  7,  4, 13,  1,    7,  6,  8, 13, +	              10,  6, 15,  3,   11,  9,  7, 15, +	              12,  0,  9,  5,    7, 12, 15,  9, +	               2, 14, 11,  8,   11,  7, 13, 12); + +	SIXTEEN(1, H,  3, 10, 14,  4,   11, 13,  6,  7, +	               9, 15,  8,  1,   14,  9, 13, 15, +	               2,  7,  0,  6,   14,  8, 13,  6, +	              13, 11,  5, 12,    5, 12,  7,  5); + +	SIXTEEN(1, I,  1,  9, 11, 10,   11, 12, 14, 15, +	               0,  8, 12,  4,   14, 15,  9,  8, +	              13,  3,  7, 15,    9, 14,  5,  6, +	              14,  5,  6,  2,    8,  6,  5, 12); + +	SIXTEEN(2, I,  5, 14,  7,  0,    8,  9,  9, 11, +	               9,  2, 11,  4,   13, 15, 15,  5, +	              13,  6, 15,  8,    7,  7,  8, 11, +	               1, 10,  3, 12,   14, 14, 12,  6); + +	SIXTEEN(2, H,  6, 11,  3,  7,    9, 13, 15,  7, +	               0, 13,  5, 10,   12,  8,  9, 11, +	              14, 15,  8, 12,    7,  7, 12,  7, +	               4,  9,  1,  2,    6, 15, 13, 11); + +	SIXTEEN(2, G, 15,  5,  1,  3,    9,  7, 15, 11, +	               7, 14,  6,  9,    8,  6,  6, 14, +	              11,  8, 12,  2,   12, 13,  5, 14, +	              10,  0,  4, 13,   13, 13,  7,  5); + +	SIXTEEN(2, F,  8,  6,  4,  1,   15,  5,  8, 11, +	               3, 11, 15,  0,   14, 14,  6, 14, +	               5, 12,  2, 13,    6,  9, 12,  9, +	               9,  7, 10, 14,   12,  5, 15,  8); + +	htmp = h[1]; +	h[1] = h[2] + d1 + a2; +	h[2] = h[3] + a1 + b2; +	h[3] = h[0] + b1 + c2; +	h[0] = htmp + c1 + d2; +} + + +LIBHASHSUM_1_NONNULL_ +static size_t +process(struct libhashsum_hasher *this, const void *data, size_t bytes) +{ +	const uint8_t *m = data; +	size_t off = 0; +	size_t i; + +	for (; bytes - off >= 64U; off += 64U) { +		for (i = 0; i < 16U; i++) +			this->state.ripemd_128.m.m32[i] = LETO32(&m[off + i * 4U]); +		process_block(this->state.ripemd_128.h.h32, this->state.ripemd_128.m.m32); +	} + +	this->state.ripemd_128.count += off; +	return off; +} + + +LIBHASHSUM_1_NONNULL_ +static int +finalise_common(struct libhashsum_hasher *this, uint8_t *m, size_t bytes, unsigned extra_bits) +{ +	uint8_t mask; +	unsigned i; +	register uint32_t hi; + +	if (extra_bits > 7U) { +		errno = EINVAL; +		return -1; +	} + +	this->state.ripemd_128.count += bytes; +	this->state.ripemd_128.count *= 8U; +	this->state.ripemd_128.count += (size_t)extra_bits; + +	memset(&m[bytes], 0, 64U - bytes); +	mask = (uint8_t)(1U << (7U - extra_bits)); +	m[bytes] |= mask; +	m[bytes] &= (uint8_t)~(mask - 1U); /* keep high bits */ +	for (i = 0; i < 14; i++) +		this->state.ripemd_128.m.m32[i] = LETO32(&m[i * 4U]); + +	if (bytes > 55U) { +		this->state.ripemd_128.m.m32[14] = LETO32(&m[14U * 4U]); +		this->state.ripemd_128.m.m32[15] = LETO32(&m[15U * 4U]); +		process_block(this->state.ripemd_128.h.h32, this->state.ripemd_128.m.m32); +		memset(this->state.ripemd_128.m.m32, 0, 56U); +	} + +	this->state.ripemd_128.m.m32[14] = (uint32_t)(this->state.ripemd_128.count >>  0); +	this->state.ripemd_128.m.m32[15] = (uint32_t)(this->state.ripemd_128.count >> 32); +	process_block(this->state.ripemd_128.h.h32, this->state.ripemd_128.m.m32); + +	memset(&this->state.ripemd_128.m, 0, sizeof(this->state.ripemd_128.m)); +	this->state.ripemd_128.count = 0; + +	for (i = 0; i < 4U; i++) { +		hi = this->state.ripemd_128.h.h32[i]; +		this->state.ripemd_128.h.sum[i * 4U + 0U] = (uint8_t)(hi >>  0); +		this->state.ripemd_128.h.sum[i * 4U + 1U] = (uint8_t)(hi >>  8); +		this->state.ripemd_128.h.sum[i * 4U + 2U] = (uint8_t)(hi >> 16); +		this->state.ripemd_128.h.sum[i * 4U + 3U] = (uint8_t)(hi >> 24); +	} + +	this->hash_output = this->state.ripemd_128.h.sum; +	return 0; +} + + +LIBHASHSUM_1_NONNULL_ +static int +finalise_const(struct libhashsum_hasher *this, const void *data, unsigned extra_bits, size_t bytes) +{ +	const uint8_t *m = data; +	size_t r; + +	r = process(this, m, bytes); +	m = &m[r]; +	bytes -= r; + +	memcpy(this->state.ripemd_128.m.m8, m, bytes + (size_t)(extra_bits > 0U)); +	return finalise_common(this, this->state.ripemd_128.m.m8, bytes, extra_bits); +} + + +LIBHASHSUM_1_NONNULL_ +static int +finalise(struct libhashsum_hasher *this, void *data, size_t bytes, unsigned extra_bits, size_t size) +{ +	uint8_t *m = data; +	size_t r; + +	r = process(this, m, bytes); +	m = &m[r]; +	bytes -= r; +	size -= r; + +	if (size < 64U) { +		memcpy(this->state.ripemd_128.m.m8, m, bytes + (size_t)(extra_bits > 0U)); +		m = this->state.ripemd_128.m.m8; +	} +	return finalise_common(this, m, bytes, extra_bits); +} + + +int +libhashsum_init_ripemd_128_hasher(struct libhashsum_hasher *this) +{ +	this->algorithm = LIBHASHSUM_RIPEMD_128; +	this->input_block_size = 64U; +	this->hash_size = sizeof(this->state.ripemd_128.h.sum); +	this->hash_output = NULL; +	this->supports_non_whole_bytes = 1; +	this->process = &process; +	this->finalise_const = &finalise_const; +	this->finalise = &finalise; +	memset(&this->state.ripemd_128, 0, sizeof(this->state.ripemd_128)); +	this->state.ripemd_128.h.h32[0] = UINT32_C(0x67452301); +	this->state.ripemd_128.h.h32[1] = UINT32_C(0xefcdab89); +	this->state.ripemd_128.h.h32[2] = UINT32_C(0x98badcfe); +	this->state.ripemd_128.h.h32[3] = UINT32_C(0x10325476); +	return 0; +} diff --git a/libhashsum_init_ripemd_160_hasher.c b/libhashsum_init_ripemd_160_hasher.c new file mode 100644 index 0000000..8235844 --- /dev/null +++ b/libhashsum_init_ripemd_160_hasher.c @@ -0,0 +1,228 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +#define LETO32(X)\ +	(((uint32_t)(X)[0] <<  0) |\ +	 ((uint32_t)(X)[1] <<  8) |\ +	 ((uint32_t)(X)[2] << 16) |\ +	 ((uint32_t)(X)[3] << 24)) + + +static uint32_t rol32(uint32_t n, int k) { return (n << k) | (n >> (32 - k)); } /* k != 0, 32 */ + + +static void +process_block(uint32_t h[5], const uint32_t *x, uint32_t w1[5], uint32_t w2[5]) +{ +#define F0(X, Y, Z) (X ^ Y ^ Z)  +#define G0(X, Y, Z) ((X & Y) | (~X & Z))  +#define H0(X, Y, Z) ((X | ~Y) ^ Z) +#define I0(X, Y, Z) ((X & Z) | (Y & ~Z))  +#define J0(X, Y, Z) (X ^ (Y | ~Z)) +   +#define F1(A, B, C, D, E, I, S) (A = rol32(F0(B, C, D) + A + x[I] + UINT32_C(0x00000000), S) + E, C = rol32(C, 10)) +#define G1(A, B, C, D, E, I, S) (A = rol32(G0(B, C, D) + A + x[I] + UINT32_C(0x5a827999), S) + E, C = rol32(C, 10)) +#define H1(A, B, C, D, E, I, S) (A = rol32(H0(B, C, D) + A + x[I] + UINT32_C(0x6ed9eba1), S) + E, C = rol32(C, 10)) +#define I1(A, B, C, D, E, I, S) (A = rol32(I0(B, C, D) + A + x[I] + UINT32_C(0x8f1bbcdc), S) + E, C = rol32(C, 10)) +#define J1(A, B, C, D, E, I, S) (A = rol32(J0(B, C, D) + A + x[I] + UINT32_C(0xa953fd4e), S) + E, C = rol32(C, 10)) +#define F2(A, B, C, D, E, I, S) (A = rol32(F0(B, C, D) + A + x[I] + UINT32_C(0x00000000), S) + E, C = rol32(C, 10)) +#define G2(A, B, C, D, E, I, S) (A = rol32(G0(B, C, D) + A + x[I] + UINT32_C(0x7a6d76e9), S) + E, C = rol32(C, 10)) +#define H2(A, B, C, D, E, I, S) (A = rol32(H0(B, C, D) + A + x[I] + UINT32_C(0x6d703ef3), S) + E, C = rol32(C, 10)) +#define I2(A, B, C, D, E, I, S) (A = rol32(I0(B, C, D) + A + x[I] + UINT32_C(0x5c4dd124), S) + E, C = rol32(C, 10)) +#define J2(A, B, C, D, E, I, S) (A = rol32(J0(B, C, D) + A + x[I] + UINT32_C(0x50a28be6), S) + E, C = rol32(C, 10)) + +#define A 0 +#define B 1 +#define C 2 +#define D 3 +#define E 4 + +#define ONE(N, P, F, ...) F##P(w##P[(N+0)%5], w##P[(N+1)%5], w##P[(N+2)%5], w##P[(N+3)%5], w##P[(N+4)%5], __VA_ARGS__) + +#define FIVE(L, P, F, I1, I2, I3, I4, I5, S1, S2, S3, S4, S5)\ +	(ONE(L + 4 * 0, P, F, I1, S1),\ +	 ONE(L + 4 * 1, P, F, I2, S2),\ +	 ONE(L + 4 * 2, P, F, I3, S3),\ +	 ONE(L + 4 * 3, P, F, I4, S4),\ +	 ONE(L + 4 * 4, P, F, I5, S5)) + +#define SIXTEEN(L, P, F, I11, I12, I13, I14, I15, I21, I22, I23,  S11, S12, S13, S14, S15, S21, S22, S23,\ +                         I24, I25, I31, I32, I33, I34, I35, I41,  S24, S25, S31, S32, S33, S34, S35, S41)\ +	(FIVE(L, P, F, I11, I12, I13, I14, I15, S11, S12, S13, S14, S15),\ +	 FIVE(L, P, F, I21, I22, I23, I24, I25, S21, S22, S23, S24, S25),\ +	 FIVE(L, P, F, I31, I32, I33, I34, I35, S31, S32, S33, S34, S35), ONE(L, P, F, I41, S41)) + +	register uint32_t htmp; +	memcpy(w1, h, 5U * sizeof(*w1)); +	memcpy(w2, h, 5U * sizeof(*w2)); + +	SIXTEEN(A, 1, F,   0,  1,  2,  3,  4,  5,  6,  7,   11, 14, 15, 12,  5,  8,  7,  9, +	                   8,  9, 10, 11, 12, 13, 14, 15,   11, 13, 14, 15,  6,  7,  9,  8); +                 +	SIXTEEN(E, 1, G,   7,  4, 13,  1, 10,  6, 15,  3,    7,  6,  8, 13, 11,  9,  7, 15, +	                  12,  0,  9,  5,  2, 14, 11,  8,    7, 12, 15,  9, 11,  7, 13, 12); + +	SIXTEEN(D, 1, H,   3, 10, 14,  4,  9, 15,  8,  1,   11, 13,  6,  7, 14,  9, 13, 15, +	                   2,  7,  0,  6, 13, 11,  5, 12,   14,  8, 13,  6,  5, 12,  7,  5); + +	SIXTEEN(C, 1, I,   1,  9, 11, 10,  0,  8, 12,  4,   11, 12, 14, 15, 14, 15,  9,  8, +	                  13,  3,  7, 15, 14,  5,  6,  2,    9, 14,  5,  6,  8,  6,  5, 12); + +	SIXTEEN(B, 1, J,   4,  0,  5,  9,  7, 12,  2, 10,    9, 15,  5, 11,  6,  8, 13, 12, +	                  14,  1,  3,  8, 11,  6, 15, 13,    5, 12, 13, 14, 11,  8,  5,  6); + +	SIXTEEN(A, 2, J,   5, 14,  7,  0,  9,  2, 11,  4,    8,  9,  9, 11, 13, 15, 15,  5, +	                  13,  6, 15,  8,  1, 10,  3, 12,    7,  7,  8, 11, 14, 14, 12,  6); + +	SIXTEEN(E, 2, I,   6, 11,  3,  7,  0, 13,  5, 10,    9, 13, 15,  7, 12,  8,  9, 11, +	                  14, 15,  8, 12,  4,  9,  1,  2,    7,  7, 12,  7,  6, 15, 13, 11); + +	SIXTEEN(D, 2, H,  15,  5,  1,  3,  7, 14,  6,  9,    9,  7, 15, 11,  8,  6,  6, 14, +	                  11,  8, 12,  2, 10,  0,  4, 13,    12, 13, 5, 14, 13, 13,  7,  5); + +	SIXTEEN(C, 2, G,   8,  6,  4,  1,  3, 11, 15,  0,   15,  5,  8, 11, 14, 14,  6, 14, +	                   5, 12,  2, 13,  9,  7, 10, 14,    6,  9, 12,  9, 12,  5, 15,  8); + +	SIXTEEN(B, 2, F,  12, 15, 10,  4,  1,  5,  8,  7,    8,  5, 12,  9, 12,  5, 14,  6, +	                   6,  2, 13, 14,  0,  3,  9, 11,    8, 13,  6,  5, 15, 13, 11, 11); + +	htmp = h[1]; +	h[1] = h[2] + w1[3] + w2[4]; +	h[2] = h[3] + w1[4] + w2[0]; +	h[3] = h[4] + w1[0] + w2[1]; +	h[4] = h[0] + w1[1] + w2[2]; +	h[0] = htmp + w1[2] + w2[3]; +} + + +LIBHASHSUM_1_NONNULL_ +static size_t +process(struct libhashsum_hasher *this, const void *data, size_t bytes) +{ +	const uint8_t *m = data; +	size_t off = 0; +	size_t i; + +	for (; bytes - off >= 64U; off += 64U) { +		for (i = 0; i < 16U; i++) +			this->state.ripemd_160.m.m32[i] = LETO32(&m[off + i * 4U]); +		process_block(this->state.ripemd_160.h.h32, this->state.ripemd_160.m.m32, +		              this->state.ripemd_160.w1, this->state.ripemd_160.w2); +	} + +	this->state.ripemd_160.count += off; +	return off; +} + + +LIBHASHSUM_1_NONNULL_ +static int +finalise_common(struct libhashsum_hasher *this, uint8_t *m, size_t bytes, unsigned extra_bits) +{ +	uint8_t mask; +	unsigned i; +	register uint32_t hi; + +	if (extra_bits > 7U) { +		errno = EINVAL; +		return -1; +	} + +	this->state.ripemd_160.count += bytes; +	this->state.ripemd_160.count *= 8U; +	this->state.ripemd_160.count += (size_t)extra_bits; + +	memset(&m[bytes], 0, 64U - bytes); +	mask = (uint8_t)(1U << (7U - extra_bits)); +	m[bytes] |= mask; +	m[bytes] &= (uint8_t)~(mask - 1U); /* keep high bits */ +	for (i = 0; i < 14; i++) +		this->state.ripemd_160.m.m32[i] = LETO32(&m[i * 4U]); + +	if (bytes > 55U) { +		this->state.ripemd_160.m.m32[14] = LETO32(&m[14U * 4U]); +		this->state.ripemd_160.m.m32[15] = LETO32(&m[15U * 4U]); +		process_block(this->state.ripemd_160.h.h32, this->state.ripemd_160.m.m32, +		              this->state.ripemd_160.w1, this->state.ripemd_160.w2); +		memset(this->state.ripemd_160.m.m32, 0, 56U); +	} + +	this->state.ripemd_160.m.m32[14] = (uint32_t)(this->state.ripemd_160.count >>  0); +	this->state.ripemd_160.m.m32[15] = (uint32_t)(this->state.ripemd_160.count >> 32); +	process_block(this->state.ripemd_160.h.h32, this->state.ripemd_160.m.m32, +	              this->state.ripemd_160.w1, this->state.ripemd_160.w2); + +	memset(&this->state.ripemd_160.m, 0, sizeof(this->state.ripemd_160.m)); +	memset(this->state.ripemd_160.w1, 0, sizeof(this->state.ripemd_160.w1)); +	memset(this->state.ripemd_160.w2, 0, sizeof(this->state.ripemd_160.w2)); +	this->state.ripemd_160.count = 0; + +	for (i = 0; i < 5U; i++) { +		hi = this->state.ripemd_160.h.h32[i]; +		this->state.ripemd_160.h.sum[i * 4U + 0U] = (uint8_t)(hi >>  0); +		this->state.ripemd_160.h.sum[i * 4U + 1U] = (uint8_t)(hi >>  8); +		this->state.ripemd_160.h.sum[i * 4U + 2U] = (uint8_t)(hi >> 16); +		this->state.ripemd_160.h.sum[i * 4U + 3U] = (uint8_t)(hi >> 24); +	} + +	this->hash_output = this->state.ripemd_160.h.sum; +	return 0; +} + + +LIBHASHSUM_1_NONNULL_ +static int +finalise_const(struct libhashsum_hasher *this, const void *data, unsigned extra_bits, size_t bytes) +{ +	const uint8_t *m = data; +	size_t r; + +	r = process(this, m, bytes); +	m = &m[r]; +	bytes -= r; + +	memcpy(this->state.ripemd_160.m.m8, m, bytes + (size_t)(extra_bits > 0U)); +	return finalise_common(this, this->state.ripemd_160.m.m8, bytes, extra_bits); +} + + +LIBHASHSUM_1_NONNULL_ +static int +finalise(struct libhashsum_hasher *this, void *data, size_t bytes, unsigned extra_bits, size_t size) +{ +	uint8_t *m = data; +	size_t r; + +	r = process(this, m, bytes); +	m = &m[r]; +	bytes -= r; +	size -= r; + +	if (size < 64U) { +		memcpy(this->state.ripemd_160.m.m8, m, bytes + (size_t)(extra_bits > 0U)); +		m = this->state.ripemd_160.m.m8; +	} +	return finalise_common(this, m, bytes, extra_bits); +} + + +int +libhashsum_init_ripemd_160_hasher(struct libhashsum_hasher *this) +{ +	this->algorithm = LIBHASHSUM_RIPEMD_160; +	this->input_block_size = 64U; +	this->hash_size = sizeof(this->state.ripemd_160.h.sum); +	this->hash_output = NULL; +	this->supports_non_whole_bytes = 1; +	this->process = &process; +	this->finalise_const = &finalise_const; +	this->finalise = &finalise; +	memset(&this->state.ripemd_160, 0, sizeof(this->state.ripemd_160)); +	this->state.ripemd_160.h.h32[0] = UINT32_C(0x67452301); +	this->state.ripemd_160.h.h32[1] = UINT32_C(0xefcdab89); +	this->state.ripemd_160.h.h32[2] = UINT32_C(0x98badcfe); +	this->state.ripemd_160.h.h32[3] = UINT32_C(0x10325476); +	this->state.ripemd_160.h.h32[4] = UINT32_C(0xc3d2e1f0); +	return 0; +} diff --git a/libhashsum_init_ripemd_256_hasher.c b/libhashsum_init_ripemd_256_hasher.c new file mode 100644 index 0000000..6491192 --- /dev/null +++ b/libhashsum_init_ripemd_256_hasher.c @@ -0,0 +1,239 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +#define LETO32(X)\ +	(((uint32_t)(X)[0] <<  0) |\ +	 ((uint32_t)(X)[1] <<  8) |\ +	 ((uint32_t)(X)[2] << 16) |\ +	 ((uint32_t)(X)[3] << 24)) + + +static uint32_t rol32(uint32_t n, int k) { return (n << k) | (n >> (32 - k)); } /* k != 0, 32 */ + + +static void +process_block(uint32_t h[8], const uint32_t *x) +{ +#define F0(X, Y, Z) (X ^ Y ^ Z)  +#define G0(X, Y, Z) ((X & Y) | (~X & Z))  +#define H0(X, Y, Z) ((X | ~Y) ^ Z) +#define I0(X, Y, Z) ((X & Z) | (Y & ~Z))  + +#define F1(A, B, C, D, I, S) (A = rol32(F0(B, C, D) + A + x[I] + UINT32_C(0x00000000), S)) +#define G1(A, B, C, D, I, S) (A = rol32(G0(B, C, D) + A + x[I] + UINT32_C(0x5a827999), S)) +#define H1(A, B, C, D, I, S) (A = rol32(H0(B, C, D) + A + x[I] + UINT32_C(0x6ed9eba1), S)) +#define I1(A, B, C, D, I, S) (A = rol32(I0(B, C, D) + A + x[I] + UINT32_C(0x8f1bbcdc), S)) +#define F2(A, B, C, D, I, S) (A = rol32(F0(B, C, D) + A + x[I] + UINT32_C(0x00000000), S)) +#define G2(A, B, C, D, I, S) (A = rol32(G0(B, C, D) + A + x[I] + UINT32_C(0x6d703ef3), S)) +#define H2(A, B, C, D, I, S) (A = rol32(H0(B, C, D) + A + x[I] + UINT32_C(0x5c4dd124), S)) +#define I2(A, B, C, D, I, S) (A = rol32(I0(B, C, D) + A + x[I] + UINT32_C(0x50a28be6), S)) + +#define FOUR(P, M, I1, S1, I2, S2, I3, S3, I4, S4)\ +	(M(a##P, b##P, c##P, d##P, I1, S1),\ +	 M(d##P, a##P, b##P, c##P, I2, S2),\ +	 M(c##P, d##P, a##P, b##P, I3, S3),\ +	 M(b##P, c##P, d##P, a##P, I4, S4)) + +#define SIXTEEN(P, F, I11, I12, I13, I14,  S11, S12, S13, S14,\ +                      I21, I22, I23, I24,  S21, S22, S23, S24,\ +                      I31, I32, I33, I34,  S31, S32, S33, S34,\ +                      I41, I42, I43, I44,  S41, S42, S43, S44)\ +	(FOUR(P, F##P, I11, S11, I12, S12, I13, S13, I14, S14),\ +	 FOUR(P, F##P, I21, S21, I22, S22, I23, S23, I24, S24),\ +	 FOUR(P, F##P, I31, S31, I32, S32, I33, S33, I34, S34),\ +	 FOUR(P, F##P, I41, S41, I42, S42, I43, S43, I44, S44)) + +	register uint32_t a1 = h[0], a2 = h[4]; +	register uint32_t b1 = h[1], b2 = h[5]; +	register uint32_t c1 = h[2], c2 = h[6]; +	register uint32_t d1 = h[3], d2 = h[7]; +	register uint32_t t; + +	SIXTEEN(1, F,  0,  1,  2,  3,   11, 14, 15, 12, +	               4,  5,  6,  7,    5,  8,  7,  9, +	               8,  9, 10, 11,   11, 13, 14, 15, +	              12, 13, 14, 15,    6,  7,  9,  8); + +	SIXTEEN(2, I,  5, 14,  7,  0,    8,  9,  9, 11, +	               9,  2, 11,  4,   13, 15, 15,  5, +	              13,  6, 15,  8,    7,  7,  8, 11, +	               1, 10,  3, 12,   14, 14, 12,  6); + +	t = a1, a1 = a2, a2 = t; + +	SIXTEEN(1, G,  7,  4, 13,  1,    7,  6,  8, 13, +	              10,  6, 15,  3,   11,  9,  7, 15, +	              12,  0,  9,  5,    7, 12, 15,  9, +	               2, 14, 11,  8,   11,  7, 13, 12); + +	SIXTEEN(2, H,  6, 11,  3,  7,    9, 13, 15,  7, +	               0, 13,  5, 10,   12,  8,  9, 11, +	              14, 15,  8, 12,    7,  7, 12,  7, +	               4,  9,  1,  2,    6, 15, 13, 11); + +	t = b1, b1 = b2, b2 = t; + +	SIXTEEN(1, H,  3, 10, 14,  4,   11, 13,  6,  7, +	               9, 15,  8,  1,   14,  9, 13, 15, +	               2,  7,  0,  6,   14,  8, 13,  6, +	              13, 11,  5, 12,    5, 12,  7,  5); + +	SIXTEEN(2, G, 15,  5,  1,  3,    9,  7, 15, 11, +	               7, 14,  6,  9,    8,  6,  6, 14, +	              11,  8, 12,  2,   12, 13,  5, 14, +	              10,  0,  4, 13,   13, 13,  7,  5); + +	t = c1, c1 = c2, c2 = t; + +	SIXTEEN(1, I,  1,  9, 11, 10,   11, 12, 14, 15, +	               0,  8, 12,  4,   14, 15,  9,  8, +	              13,  3,  7, 15,    9, 14,  5,  6, +	              14,  5,  6,  2,    8,  6,  5, 12); + +	SIXTEEN(2, F,  8,  6,  4,  1,   15,  5,  8, 11, +	               3, 11, 15,  0,   14, 14,  6, 14, +	               5, 12,  2, 13,    6,  9, 12,  9, +	               9,  7, 10, 14,   12,  5, 15,  8); + +	t = d1, d1 = d2, d2 = t; + +	h[0] += a1; +	h[1] += b1; +	h[2] += c1; +	h[3] += d1; +	h[4] += a2; +	h[5] += b2; +	h[6] += c2; +	h[7] += d2; +} + + +LIBHASHSUM_1_NONNULL_ +static size_t +process(struct libhashsum_hasher *this, const void *data, size_t bytes) +{ +	const uint8_t *m = data; +	size_t off = 0; +	size_t i; + +	for (; bytes - off >= 64U; off += 64U) { +		for (i = 0; i < 16U; i++) +			this->state.ripemd_256.m.m32[i] = LETO32(&m[off + i * 4U]); +		process_block(this->state.ripemd_256.h.h32, this->state.ripemd_256.m.m32); +	} + +	this->state.ripemd_256.count += off; +	return off; +} + + +LIBHASHSUM_1_NONNULL_ +static int +finalise_common(struct libhashsum_hasher *this, uint8_t *m, size_t bytes, unsigned extra_bits) +{ +	uint8_t mask; +	unsigned i; +	register uint32_t hi; + +	if (extra_bits > 7U) { +		errno = EINVAL; +		return -1; +	} + +	this->state.ripemd_256.count += bytes; +	this->state.ripemd_256.count *= 8U; +	this->state.ripemd_256.count += (size_t)extra_bits; + +	memset(&m[bytes], 0, 64U - bytes); +	mask = (uint8_t)(1U << (7U - extra_bits)); +	m[bytes] |= mask; +	m[bytes] &= (uint8_t)~(mask - 1U); /* keep high bits */ +	for (i = 0; i < 14; i++) +		this->state.ripemd_256.m.m32[i] = LETO32(&m[i * 4U]); + +	if (bytes > 55U) { +		this->state.ripemd_256.m.m32[14] = LETO32(&m[14U * 4U]); +		this->state.ripemd_256.m.m32[15] = LETO32(&m[15U * 4U]); +		process_block(this->state.ripemd_256.h.h32, this->state.ripemd_256.m.m32); +		memset(this->state.ripemd_256.m.m32, 0, 56U); +	} + +	this->state.ripemd_256.m.m32[14] = (uint32_t)(this->state.ripemd_256.count >>  0); +	this->state.ripemd_256.m.m32[15] = (uint32_t)(this->state.ripemd_256.count >> 32); +	process_block(this->state.ripemd_256.h.h32, this->state.ripemd_256.m.m32); + +	memset(&this->state.ripemd_256.m, 0, sizeof(this->state.ripemd_256.m)); +	this->state.ripemd_256.count = 0; + +	for (i = 0; i < 8U; i++) { +		hi = this->state.ripemd_256.h.h32[i]; +		this->state.ripemd_256.h.sum[i * 4U + 0U] = (uint8_t)(hi >>  0); +		this->state.ripemd_256.h.sum[i * 4U + 1U] = (uint8_t)(hi >>  8); +		this->state.ripemd_256.h.sum[i * 4U + 2U] = (uint8_t)(hi >> 16); +		this->state.ripemd_256.h.sum[i * 4U + 3U] = (uint8_t)(hi >> 24); +	} + +	this->hash_output = this->state.ripemd_256.h.sum; +	return 0; +} + + +LIBHASHSUM_1_NONNULL_ +static int +finalise_const(struct libhashsum_hasher *this, const void *data, unsigned extra_bits, size_t bytes) +{ +	const uint8_t *m = data; +	size_t r; + +	r = process(this, m, bytes); +	m = &m[r]; +	bytes -= r; + +	memcpy(this->state.ripemd_256.m.m8, m, bytes + (size_t)(extra_bits > 0U)); +	return finalise_common(this, this->state.ripemd_256.m.m8, bytes, extra_bits); +} + + +LIBHASHSUM_1_NONNULL_ +static int +finalise(struct libhashsum_hasher *this, void *data, size_t bytes, unsigned extra_bits, size_t size) +{ +	uint8_t *m = data; +	size_t r; + +	r = process(this, m, bytes); +	m = &m[r]; +	bytes -= r; +	size -= r; + +	if (size < 64U) { +		memcpy(this->state.ripemd_256.m.m8, m, bytes + (size_t)(extra_bits > 0U)); +		m = this->state.ripemd_256.m.m8; +	} +	return finalise_common(this, m, bytes, extra_bits); +} + + +int +libhashsum_init_ripemd_256_hasher(struct libhashsum_hasher *this) +{ +	this->algorithm = LIBHASHSUM_RIPEMD_256; +	this->input_block_size = 64U; +	this->hash_size = sizeof(this->state.ripemd_256.h.sum); +	this->hash_output = NULL; +	this->supports_non_whole_bytes = 1; +	this->process = &process; +	this->finalise_const = &finalise_const; +	this->finalise = &finalise; +	memset(&this->state.ripemd_256, 0, sizeof(this->state.ripemd_256)); +	this->state.ripemd_256.h.h32[0] = UINT32_C(0x67452301); +	this->state.ripemd_256.h.h32[1] = UINT32_C(0xefcdab89); +	this->state.ripemd_256.h.h32[2] = UINT32_C(0x98badcfe); +	this->state.ripemd_256.h.h32[3] = UINT32_C(0x10325476); +	this->state.ripemd_256.h.h32[4] = UINT32_C(0x76543210); +	this->state.ripemd_256.h.h32[5] = UINT32_C(0xfedcba98); +	this->state.ripemd_256.h.h32[6] = UINT32_C(0x89abcdef); +	this->state.ripemd_256.h.h32[7] = UINT32_C(0x01234567); +	return 0; +} diff --git a/libhashsum_init_ripemd_320_hasher.c b/libhashsum_init_ripemd_320_hasher.c new file mode 100644 index 0000000..4690be8 --- /dev/null +++ b/libhashsum_init_ripemd_320_hasher.c @@ -0,0 +1,247 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +#define LETO32(X)\ +	(((uint32_t)(X)[0] <<  0) |\ +	 ((uint32_t)(X)[1] <<  8) |\ +	 ((uint32_t)(X)[2] << 16) |\ +	 ((uint32_t)(X)[3] << 24)) + + +static uint32_t rol32(uint32_t n, int k) { return (n << k) | (n >> (32 - k)); } /* k != 0, 32 */ + + +static void +process_block(uint32_t h[10], const uint32_t *x, uint32_t w1[5], uint32_t w2[5]) +{ +#define F0(X, Y, Z) (X ^ Y ^ Z)  +#define G0(X, Y, Z) ((X & Y) | (~X & Z))  +#define H0(X, Y, Z) ((X | ~Y) ^ Z) +#define I0(X, Y, Z) ((X & Z) | (Y & ~Z))  +#define J0(X, Y, Z) (X ^ (Y | ~Z)) +   +#define F1(A, B, C, D, E, I, S) (A = rol32(F0(B, C, D) + A + x[I] + UINT32_C(0x00000000), S) + E, C = rol32(C, 10)) +#define G1(A, B, C, D, E, I, S) (A = rol32(G0(B, C, D) + A + x[I] + UINT32_C(0x5a827999), S) + E, C = rol32(C, 10)) +#define H1(A, B, C, D, E, I, S) (A = rol32(H0(B, C, D) + A + x[I] + UINT32_C(0x6ed9eba1), S) + E, C = rol32(C, 10)) +#define I1(A, B, C, D, E, I, S) (A = rol32(I0(B, C, D) + A + x[I] + UINT32_C(0x8f1bbcdc), S) + E, C = rol32(C, 10)) +#define J1(A, B, C, D, E, I, S) (A = rol32(J0(B, C, D) + A + x[I] + UINT32_C(0xa953fd4e), S) + E, C = rol32(C, 10)) +#define F2(A, B, C, D, E, I, S) (A = rol32(F0(B, C, D) + A + x[I] + UINT32_C(0x00000000), S) + E, C = rol32(C, 10)) +#define G2(A, B, C, D, E, I, S) (A = rol32(G0(B, C, D) + A + x[I] + UINT32_C(0x7a6d76e9), S) + E, C = rol32(C, 10)) +#define H2(A, B, C, D, E, I, S) (A = rol32(H0(B, C, D) + A + x[I] + UINT32_C(0x6d703ef3), S) + E, C = rol32(C, 10)) +#define I2(A, B, C, D, E, I, S) (A = rol32(I0(B, C, D) + A + x[I] + UINT32_C(0x5c4dd124), S) + E, C = rol32(C, 10)) +#define J2(A, B, C, D, E, I, S) (A = rol32(J0(B, C, D) + A + x[I] + UINT32_C(0x50a28be6), S) + E, C = rol32(C, 10)) + +#define A 0 +#define B 1 +#define C 2 +#define D 3 +#define E 4 + +#define ONE(N, P, F, ...) F##P(w##P[(N+0)%5], w##P[(N+1)%5], w##P[(N+2)%5], w##P[(N+3)%5], w##P[(N+4)%5], __VA_ARGS__) + +#define FIVE(L, P, F, I1, I2, I3, I4, I5, S1, S2, S3, S4, S5)\ +	(ONE(L + 4 * 0, P, F, I1, S1),\ +	 ONE(L + 4 * 1, P, F, I2, S2),\ +	 ONE(L + 4 * 2, P, F, I3, S3),\ +	 ONE(L + 4 * 3, P, F, I4, S4),\ +	 ONE(L + 4 * 4, P, F, I5, S5)) + +#define SIXTEEN(L, P, F, I11, I12, I13, I14, I15, I21, I22, I23,  S11, S12, S13, S14, S15, S21, S22, S23,\ +                         I24, I25, I31, I32, I33, I34, I35, I41,  S24, S25, S31, S32, S33, S34, S35, S41)\ +	(FIVE(L, P, F, I11, I12, I13, I14, I15, S11, S12, S13, S14, S15),\ +	 FIVE(L, P, F, I21, I22, I23, I24, I25, S21, S22, S23, S24, S25),\ +	 FIVE(L, P, F, I31, I32, I33, I34, I35, S31, S32, S33, S34, S35), ONE(L, P, F, I41, S41)) + +	register uint32_t t; +	memcpy(w1, &h[0], 5U * sizeof(*w1)); +	memcpy(w2, &h[5], 5U * sizeof(*w2)); + +	SIXTEEN(A, 1, F,   0,  1,  2,  3,  4,  5,  6,  7,   11, 14, 15, 12,  5,  8,  7,  9, +	                   8,  9, 10, 11, 12, 13, 14, 15,   11, 13, 14, 15,  6,  7,  9,  8); + +	SIXTEEN(A, 2, J,   5, 14,  7,  0,  9,  2, 11,  4,    8,  9,  9, 11, 13, 15, 15,  5, +	                  13,  6, 15,  8,  1, 10,  3, 12,    7,  7,  8, 11, 14, 14, 12,  6); + +	t = w1[0], w1[0] = w2[0], w2[0] = t; + +	SIXTEEN(E, 1, G,   7,  4, 13,  1, 10,  6, 15,  3,    7,  6,  8, 13, 11,  9,  7, 15, +	                  12,  0,  9,  5,  2, 14, 11,  8,    7, 12, 15,  9, 11,  7, 13, 12); + +	SIXTEEN(E, 2, I,   6, 11,  3,  7,  0, 13,  5, 10,    9, 13, 15,  7, 12,  8,  9, 11, +	                  14, 15,  8, 12,  4,  9,  1,  2,    7,  7, 12,  7,  6, 15, 13, 11); + +	t = w1[1], w1[1] = w2[1], w2[1] = t; + +	SIXTEEN(D, 1, H,   3, 10, 14,  4,  9, 15,  8,  1,   11, 13,  6,  7, 14,  9, 13, 15, +	                   2,  7,  0,  6, 13, 11,  5, 12,   14,  8, 13,  6,  5, 12,  7,  5); + +	SIXTEEN(D, 2, H,  15,  5,  1,  3,  7, 14,  6,  9,    9,  7, 15, 11,  8,  6,  6, 14, +	                  11,  8, 12,  2, 10,  0,  4, 13,    12, 13, 5, 14, 13, 13,  7,  5); + +	t = w1[2], w1[2] = w2[2], w2[2] = t; + +	SIXTEEN(C, 1, I,   1,  9, 11, 10,  0,  8, 12,  4,   11, 12, 14, 15, 14, 15,  9,  8, +	                  13,  3,  7, 15, 14,  5,  6,  2,    9, 14,  5,  6,  8,  6,  5, 12); + +	SIXTEEN(C, 2, G,   8,  6,  4,  1,  3, 11, 15,  0,   15,  5,  8, 11, 14, 14,  6, 14, +	                   5, 12,  2, 13,  9,  7, 10, 14,    6,  9, 12,  9, 12,  5, 15,  8); + +	t = w1[3], w1[3] = w2[3], w2[3] = t; + +	SIXTEEN(B, 1, J,   4,  0,  5,  9,  7, 12,  2, 10,    9, 15,  5, 11,  6,  8, 13, 12, +	                  14,  1,  3,  8, 11,  6, 15, 13,    5, 12, 13, 14, 11,  8,  5,  6); + +	SIXTEEN(B, 2, F,  12, 15, 10,  4,  1,  5,  8,  7,    8,  5, 12,  9, 12,  5, 14,  6, +	                   6,  2, 13, 14,  0,  3,  9, 11,    8, 13,  6,  5, 15, 13, 11, 11); + +	t = w1[4], w1[4] = w2[4], w2[4] = t; + +	h[0] += w1[0]; +	h[1] += w1[1]; +	h[2] += w1[2]; +	h[3] += w1[3]; +	h[4] += w1[4]; +	h[5] += w2[0]; +	h[6] += w2[1]; +	h[7] += w2[2]; +	h[8] += w2[3]; +	h[9] += w2[4]; +} + + +LIBHASHSUM_1_NONNULL_ +static size_t +process(struct libhashsum_hasher *this, const void *data, size_t bytes) +{ +	const uint8_t *m = data; +	size_t off = 0; +	size_t i; + +	for (; bytes - off >= 64U; off += 64U) { +		for (i = 0; i < 16U; i++) +			this->state.ripemd_320.m.m32[i] = LETO32(&m[off + i * 4U]); +		process_block(this->state.ripemd_320.h.h32, this->state.ripemd_320.m.m32, +		              this->state.ripemd_320.w1, this->state.ripemd_320.w2); +	} + +	this->state.ripemd_320.count += off; +	return off; +} + + +LIBHASHSUM_1_NONNULL_ +static int +finalise_common(struct libhashsum_hasher *this, uint8_t *m, size_t bytes, unsigned extra_bits) +{ +	uint8_t mask; +	unsigned i; +	register uint32_t hi; + +	if (extra_bits > 7U) { +		errno = EINVAL; +		return -1; +	} + +	this->state.ripemd_320.count += bytes; +	this->state.ripemd_320.count *= 8U; +	this->state.ripemd_320.count += (size_t)extra_bits; + +	memset(&m[bytes], 0, 64U - bytes); +	mask = (uint8_t)(1U << (7U - extra_bits)); +	m[bytes] |= mask; +	m[bytes] &= (uint8_t)~(mask - 1U); /* keep high bits */ +	for (i = 0; i < 14; i++) +		this->state.ripemd_320.m.m32[i] = LETO32(&m[i * 4U]); + +	if (bytes > 55U) { +		this->state.ripemd_320.m.m32[14] = LETO32(&m[14U * 4U]); +		this->state.ripemd_320.m.m32[15] = LETO32(&m[15U * 4U]); +		process_block(this->state.ripemd_320.h.h32, this->state.ripemd_320.m.m32, +		              this->state.ripemd_320.w1, this->state.ripemd_320.w2); +		memset(this->state.ripemd_320.m.m32, 0, 56U); +	} + +	this->state.ripemd_320.m.m32[14] = (uint32_t)(this->state.ripemd_320.count >>  0); +	this->state.ripemd_320.m.m32[15] = (uint32_t)(this->state.ripemd_320.count >> 32); +	process_block(this->state.ripemd_320.h.h32, this->state.ripemd_320.m.m32, +	              this->state.ripemd_320.w1, this->state.ripemd_320.w2); + +	memset(&this->state.ripemd_320.m, 0, sizeof(this->state.ripemd_320.m)); +	memset(this->state.ripemd_320.w1, 0, sizeof(this->state.ripemd_320.w1)); +	memset(this->state.ripemd_320.w2, 0, sizeof(this->state.ripemd_320.w2)); +	this->state.ripemd_320.count = 0; + +	for (i = 0; i < 10U; i++) { +		hi = this->state.ripemd_320.h.h32[i]; +		this->state.ripemd_320.h.sum[i * 4U + 0U] = (uint8_t)(hi >>  0); +		this->state.ripemd_320.h.sum[i * 4U + 1U] = (uint8_t)(hi >>  8); +		this->state.ripemd_320.h.sum[i * 4U + 2U] = (uint8_t)(hi >> 16); +		this->state.ripemd_320.h.sum[i * 4U + 3U] = (uint8_t)(hi >> 24); +	} + +	this->hash_output = this->state.ripemd_320.h.sum; +	return 0; +} + + +LIBHASHSUM_1_NONNULL_ +static int +finalise_const(struct libhashsum_hasher *this, const void *data, unsigned extra_bits, size_t bytes) +{ +	const uint8_t *m = data; +	size_t r; + +	r = process(this, m, bytes); +	m = &m[r]; +	bytes -= r; + +	memcpy(this->state.ripemd_320.m.m8, m, bytes + (size_t)(extra_bits > 0U)); +	return finalise_common(this, this->state.ripemd_320.m.m8, bytes, extra_bits); +} + + +LIBHASHSUM_1_NONNULL_ +static int +finalise(struct libhashsum_hasher *this, void *data, size_t bytes, unsigned extra_bits, size_t size) +{ +	uint8_t *m = data; +	size_t r; + +	r = process(this, m, bytes); +	m = &m[r]; +	bytes -= r; +	size -= r; + +	if (size < 64U) { +		memcpy(this->state.ripemd_320.m.m8, m, bytes + (size_t)(extra_bits > 0U)); +		m = this->state.ripemd_320.m.m8; +	} +	return finalise_common(this, m, bytes, extra_bits); +} + + +int +libhashsum_init_ripemd_320_hasher(struct libhashsum_hasher *this) +{ +	this->algorithm = LIBHASHSUM_RIPEMD_320; +	this->input_block_size = 64U; +	this->hash_size = sizeof(this->state.ripemd_320.h.sum); +	this->hash_output = NULL; +	this->supports_non_whole_bytes = 1; +	this->process = &process; +	this->finalise_const = &finalise_const; +	this->finalise = &finalise; +	memset(&this->state.ripemd_320, 0, sizeof(this->state.ripemd_320)); +	this->state.ripemd_320.h.h32[0] = UINT32_C(0x67452301); +	this->state.ripemd_320.h.h32[1] = UINT32_C(0xefcdab89); +	this->state.ripemd_320.h.h32[2] = UINT32_C(0x98badcfe); +	this->state.ripemd_320.h.h32[3] = UINT32_C(0x10325476); +	this->state.ripemd_320.h.h32[4] = UINT32_C(0xc3d2e1f0); +	this->state.ripemd_320.h.h32[5] = UINT32_C(0x76543210); +	this->state.ripemd_320.h.h32[6] = UINT32_C(0xfedcba98); +	this->state.ripemd_320.h.h32[7] = UINT32_C(0x89abcdef); +	this->state.ripemd_320.h.h32[8] = UINT32_C(0x01234567); +	this->state.ripemd_320.h.h32[9] = UINT32_C(0x3c2d1e0f); +	return 0; +} @@ -0,0 +1,25 @@ +/* See LICENSE file for copyright and license details. */ +#define TEST +#include "common.h" + + +static struct testcase testcases[] = { +	{1, 0, "The quick brown fox jumps over the lazy dog", "03d85a0d629d2c442e987525319fc471"}, +	{1, 0, "The quick brown fox jumps over the lazy cog", "6b890c9292668cdbbfda00a4ebf31f05"}, +	{1, 0, "", "8350e5a3e24c153df2275c9f80692773"}, +	{1, 0, "a", "32ec01ec4a6dac72c0ab96fb34c0b5d1"}, +	{1, 0, "abc", "da853b0d3f88d99b30283a69e6ded6bb"}, +	{1, 0, "message digest", "ab4f496bfb2a530b219ff33031fe06b0"}, +	{1, 0, "abcdefghijklmnopqrstuvwxyz", "4e8ddff3650292ab5a4108c3aa47940b"}, +	{1, 0, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "da33def2a42df13975352846c30338cd"}, +	{1, 0, "12345678901234567890123456789012345678901234567890123456789012345678901234567890", "d5976f79d83d3a0dc9806c3c66f3efd8"}, +	{1, 0, "1234567890123456789012345678901234567890123456789012345678901234", "1a07a94849157fc19442f42e84225ebd"}, +	{1000000UL, 0, "a", NULL} +}; + + +int +main(void) +{ +	TEST_MAIN("MD2", MD2); +} @@ -0,0 +1,25 @@ +/* See LICENSE file for copyright and license details. */ +#define TEST +#include "common.h" + + +static struct testcase testcases[] = { +	{1, 0, "The quick brown fox jumps over the lazy dog", "1bee69a46ba811185c194762abaeae90"}, +	{1, 0, "The quick brown fox jumps over the lazy cog", "b86e130ce7028da59e672d56ad0113df"}, +	{1, 0, "", "31d6cfe0d16ae931b73c59d7e0c089c0"}, +	{1, 0, "a", "bde52cb31de33e46245e05fbdbd6fb24"}, +	{1, 0, "abc", "a448017aaf21d8525fc10ae87aa6729d"}, +	{1, 0, "message digest", "d9130a8164549fe818874806e1c7014b"}, +	{1, 0, "abcdefghijklmnopqrstuvwxyz", "d79e1c308aa5bbcdeea8ed63df412da9"}, +	{1, 0, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "043f8582f241db351ce627e153e7f0e4"}, +	{1, 0, "12345678901234567890123456789012345678901234567890123456789012345678901234567890", "e33b4ddc9c38f2199c3e7b164fcc0536"}, +	{1, 0, "1234567890123456789012345678901234567890123456789012345678901234", "c30a2de7d6eb547b4ceb82d65e28c029"}, +	{1000000UL, 0, "a", NULL} +}; + + +int +main(void) +{ +	TEST_MAIN("MD4", MD4); +} @@ -0,0 +1,116 @@ +/* See LICENSE file for copyright and license details. */ +#define TEST +#include "common.h" + + +static struct testcase testcases[] = { +	{1, 0, "", "d41d8cd98f00b204e9800998ecf8427e"}, +	{1, 0, "a\n", "60b725f10c9c85c70d97880dfe8191b3"}, +	{1, 0, "a", "0cc175b9c0f1b6a831c399e269772661"}, +	{1, 0, "\n", "68b329da9893e34099c7d8ad5cb9c940"}, +	{1, 0, "\n\n", "e1c06d85ae7b8b032bef47e42e4c08f9"}, +	{1, 40, "\0\0\0\0\n", "220837fefd71ea604ab9f99017c9cb0e"}, +	{1, 0, "abc", "900150983cd24fb0d6963f7d28e17f72"}, +	{1, 0, "The quick brown fox jumps over the lazy dog", +	 "9e107d9d372bb6826bd81d3542a419d6"}, +	{1, 0, "The quick brown fox jumps over the lazy dog.", +	 "e4d909c290d0fb1ca068ffaddf22cbd0"}, +	{1, 0, "a\nb\nc\nd\ne\n", +	 "1065e32f2cfab7352c6d3211f5447069"}, +	{1, 0, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", +	 "d174ab98d277d9f5a5611c2c9f419d9f"}, +	{1, 0, "12345678901234567890123456789012345678901234567890123456789012345678901234567890", +	 "57edf4a22be3c955ac49da2e2107b67a"}, +	{1, 0, "abcdefghijklmnopqrstuvwxyz", +	 "c3fcd3d76192e4007dfb496cca67e13b"}, +	{1UL, 0, "x", "9dd4e461268c8034f5c8564e155c67a6"}, +	{2UL, 0, "x", "9336ebf25087d91c818ee6e9ec29f8c1"}, +	{3UL, 0, "x", "f561aaf6ef0bf14d4208bb46a4ccb3ad"}, +	{4UL, 0, "x", "ea416ed0759d46a8de58f63a59077499"}, +	{5UL, 0, "x", "fb0e22c79ac75679e9881e6ba183b354"}, +	{6UL, 0, "x", "dad3a37aa9d50688b5157698acfd7aee"}, +	{7UL, 0, "x", "04adb4e2f055c978c9bb101ee1bc5cd4"}, +	{8UL, 0, "x", "0b0cfc07fca81c956ab9181d8576f4a8"}, +	{9UL, 0, "x", "aba369f7d2b28a9098a0a26feb7dc965"}, +	{10UL, 0, "x", "336311a016184326ddbdd61edd4eeb52"}, +	{11UL, 0, "x", "dcb740b2c2836cb11f707d63e6ac664f"}, +	{12UL, 0, "x", "f94c84fac5cb091c60bb143cb957d229"}, +	{13UL, 0, "x", "df7c0a3fa59809752be392c52c4a0559"}, +	{14UL, 0, "x", "4e619f5b28df4a9744963e6700abe7ca"}, +	{15UL, 0, "x", "de59bd9061c93855e3fdd416e26f27a6"}, +	{16UL, 0, "x", "45ed9cc2f92b77cd8b2f5bd59ff635f8"}, +	{17UL, 0, "x", "3ef82839679f05ef260e3ac982de93cd"}, +	{18UL, 0, "x", "40e6267e5814c629b8e292735a77e2a9"}, +	{19UL, 0, "x", "079080d02c875b5a30be6e1e59ce6aa3"}, +	{20UL, 0, "x", "baf1da0e2b9065ab5edd36ca00ed1826"}, +	{28UL, 0, "x", "cd25b7f1c589ff14b9e9c0c5c2555ff2"}, +	{29UL, 0, "x", "0d046efba26ac1a3f561246081c086e7"}, +	{30UL, 0, "x", "4495c1948d806f6dd8cbd8e15f7e254a"}, +	{31UL, 0, "x", "48e95c91781dcf2c5eb90da6e8dcc14d"}, +	{32UL, 0, "x", "dc8fe1d6497ebd23f5975d8d2a1c5e81"}, +	{33UL, 0, "x", "b7b82191a246d3563ed060e298add91d"}, +	{34UL, 0, "x", "07e932fcd783c8deab1d20a49ed80c39"}, +	{35UL, 0, "x", "d77c54ec53a4ef5d5f81ed5685560e31"}, +	{36UL, 0, "x", "7c3f98f113332d38d08b5e9014792ba0"}, +	{60UL, 0, "x", "1198000c11968f9368e02d6da57ec147"}, +	{61UL, 0, "x", "ee8c65d71323cc65e6e8535663ea817c"}, +	{62UL, 0, "x", "31f6affeacbf0a8196f061a4e49a8a15"}, +	{63UL, 0, "x", "7dc2ca208106a2f703567bdff99d8981"}, +	{64UL, 0, "x", "c1bb4f81d892b2d57947682aeb252456"}, +	{65UL, 0, "x", "1bc932052302d074bdec39795fe00cf6"}, +	{66UL, 0, "x", "3c8d35046511f6b1b05e721d4f60256e"}, +	{67UL, 0, "x", "4bbca3f0abeaab4b7342a77e75f31d58"}, +	{68UL, 0, "x", "ffec2ae499ea42e2a8fa19b167e873dc"}, +	{124UL, 0, "x", "a35da70d31690b66cabdd4288671c263"}, +	{125UL, 0, "x", "09caa6eb477f42e8e19f5f3b4b42d849"}, +	{126UL, 0, "x", "8dd415f6a3a27df0899c8c6b54ea27ed"}, +	{127UL, 0, "x", "a0b28c1da68705c2ff883fe279b72753"}, +	{128UL, 0, "x", "d69cb61a6ee87200676eb0d4b90edbcb"}, +	{129UL, 0, "x", "3926841d393c00c3f36260e5ace10dc1"}, +	{130UL, 0, "x", "cfc92f41305ca00c9f9584bf67ae1b54"}, +	{131UL, 0, "x", "6cc46654feb888930c09d25f5c4d45a8"}, +	{132UL, 0, "x", "326c994f14a44790edbe0aa08dce10c5"}, +	{252UL, 0, "x", "96897c58b701383553034d7027eef698"}, +	{253UL, 0, "x", "1a244ae9fefe18985dbeec401592f821"}, +	{254UL, 0, "x", "1bfbf8d01c1d8d19664a9834edf6a182"}, +	{255UL, 0, "x", "cb3ead3ffb3d928128c57a88ddc023c9"}, +	{256UL, 0, "x", "c7a139a2b8e92164276f778917ba10b9"}, +	{257UL, 0, "x", "d36a37136d406826a19f8d222217fcf2"}, +	{258UL, 0, "x", "b53fb5e097ce58fa2e4ca1ddd9cb4c17"}, +	{259UL, 0, "x", "212075aa9ea2f4dfcd787fd722c6ca36"}, +	{260UL, 0, "x", "a9c279980354afb717ecb974915f5735"}, +	{508UL, 0, "x", "4dc1fad83b9ed2d53e6ee24ec6e3cd77"}, +	{509UL, 0, "x", "d5e9a6bb15c49dd852836ad1e3b7cc55"}, +	{510UL, 0, "x", "68c0b8dbb509c84b314782acb7fa8f52"}, +	{511UL, 0, "x", "dc1c50246bf0c9d112ae426500a49ccd"}, +	{512UL, 0, "x", "9147bc1f0f20e8ae1932e616b51240fb"}, +	{513UL, 0, "x", "d70999aa02d6479b04bc87c1c60a5073"}, +	{514UL, 0, "x", "51010e21c8ba2f8f37e312a2fa34795c"}, +	{515UL, 0, "x", "7f5d20b68c0da40ce24d0124ad5ad67f"}, +	{516UL, 0, "x", "2b6c8b791a19fd9de9dc5aba0ed7bf6d"}, +	{1020UL, 0, "x", "b73908fc7f1175d53183e646f4298478"}, +	{1021UL, 0, "x", "e52374c56cbf8a50e133ef7f8c9aeb50"}, +	{1022UL, 0, "x", "5e4d064e9476082eb78ba62a31c0935c"}, +	{1023UL, 0, "x", "7c944a22b4db95dd90b61331cafe605c"}, +	{1024UL, 0, "x", "7265f4d211b56873a381d321f586e4a9"}, +	{1025UL, 0, "x", "41b2b8ce59ecc0c64c9c7ecaae3002c3"}, +	{1026UL, 0, "x", "aabf55b958bc5b71749ee9c64523933f"}, +	{1027UL, 0, "x", "f8f06f8e36e9435183db627789cdd691"}, +	{1028UL, 0, "x", "8f1c68e076235ba5f52bf16f41b12194"}, +	{2044UL, 0, "x", "43c5028529ab5f64903b1e1459948a7f"}, +	{2045UL, 0, "x", "ea156212359f7894058fa2cc4193b0d7"}, +	{2046UL, 0, "x", "a77d0af5147801eceda2e059a6ee8eb4"}, +	{2047UL, 0, "x", "5aa00f0f1280c998648ecae491964f66"}, +	{2048UL, 0, "x", "cfb767f225d58469c5de3632a8803958"}, +	{2049UL, 0, "x", "01ee208262ef50b8ea672d0865ad58fa"}, +	{2050UL, 0, "x", "da23b925b41f6160146ade5dc7f65281"}, +	{2051UL, 0, "x", "2583da14d43398956e19e24a6f591748"}, +	{2052UL, 0, "x", "2388049a9674713a2e82cd59d2cc9241"} +}; + + +int +main(void) +{ +	TEST_MAIN("MD5", MD5); +} diff --git a/mk/linux.mk b/mk/linux.mk new file mode 100644 index 0000000..ad58f69 --- /dev/null +++ b/mk/linux.mk @@ -0,0 +1,6 @@ +LIBEXT      = so +LIBFLAGS    = -shared -Wl,-soname,lib$(LIB_NAME).$(LIBEXT).$(LIB_MAJOR) +LIBMAJOREXT = $(LIBEXT).$(LIB_MAJOR) +LIBMINOREXT = $(LIBEXT).$(LIB_VERSION) + +FIX_INSTALL_NAME = : diff --git a/mk/macos.mk b/mk/macos.mk new file mode 100644 index 0000000..11f1c96 --- /dev/null +++ b/mk/macos.mk @@ -0,0 +1,6 @@ +LIBEXT      = dylib +LIBFLAGS    = -dynamiclib -Wl,-compatibility_version,$(LIB_MAJOR) -Wl,-current_version,$(LIB_VERSION) +LIBMAJOREXT = $(LIB_MAJOR).$(LIBEXT) +LIBMINOREXT = $(LIB_VERSION).$(LIBEXT) + +FIX_INSTALL_NAME = install_name_tool -id "$(PREFIX)/lib/libhashsum.$(LIBMAJOREXT)" diff --git a/mk/windows.mk b/mk/windows.mk new file mode 100644 index 0000000..ed5ec8d --- /dev/null +++ b/mk/windows.mk @@ -0,0 +1,6 @@ +LIBEXT      = dll +LIBFLAGS    = -shared +LIBMAJOREXT = $(LIB_MAJOR).$(LIBEXT) +LIBMINOREXT = $(LIB_VERSION).$(LIBEXT) + +FIX_INSTALL_NAME = : diff --git a/ripemd-128.c b/ripemd-128.c new file mode 100644 index 0000000..8e15e07 --- /dev/null +++ b/ripemd-128.c @@ -0,0 +1,23 @@ +/* See LICENSE file for copyright and license details. */ +#define TEST +#include "common.h" + + +static struct testcase testcases[] = { +	{1, 0, "", "cdf26213a150dc3ecb610f18f6b38b46"}, +	{1, 0, "a", "86be7afa339d0fc7cfc785e72f578d33"}, +	{1, 0, "abc", "c14a12199c66e4ba84636b0f69144c77"}, +	{1, 0, "message digest", "9e327b3d6e523062afc1132d7df9d1b8"}, +	{1, 0, "abcdefghijklmnopqrstuvwxyz", "fd2aa607f71dc8f510714922b371834e"}, +	{1, 0, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "a1aa0689d0fafa2ddc22e88b49133a06"}, +	{1, 0, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "d1e959eb179c911faea4624c60c5c702"}, +	{8, 0, "1234567890", "3f45ef194732c2dbb2c4a2c769795fa3"}, +	{1000000UL, 0, "a", "4a7f5723f954eba1216c9d8f6320431f"} +}; + + +int +main(void) +{ +	TEST_MAIN("RIPEMD-128", RIPEMD_128); +} diff --git a/ripemd-160.c b/ripemd-160.c new file mode 100644 index 0000000..a5c4111 --- /dev/null +++ b/ripemd-160.c @@ -0,0 +1,23 @@ +/* See LICENSE file for copyright and license details. */ +#define TEST +#include "common.h" + + +static struct testcase testcases[] = { +	{1, 0, "", "9c1185a5c5e9fc54612808977ee8f548b2258d31"}, +	{1, 0, "a", "0bdc9d2d256b3ee9daae347be6f4dc835a467ffe"}, +	{1, 0, "abc", "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc"}, +	{1, 0, "message digest", "5d0689ef49d2fae572b881b123a85ffa21595f36"}, +	{1, 0, "abcdefghijklmnopqrstuvwxyz", "f71c27109c692c1b56bbdceb5b9d2865b3708dbc"}, +	{1, 0, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "12a053384a9c0c88e405a06c27dcf49ada62eb2b"}, +	{1, 0, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "b0e20b6e3116640286ed3a87a5713079b21f5189"}, +	{8, 0, "1234567890", "9b752e45573d4b39f4dbd3323cab82bf63326bfb"}, +	{1000000UL, 0, "a", "52783243c1697bdbe16d37f97f68f08325dc1528"} +}; + + +int +main(void) +{ +	TEST_MAIN("RIPEMD-160", RIPEMD_160); +} diff --git a/ripemd-256.c b/ripemd-256.c new file mode 100644 index 0000000..06f45ef --- /dev/null +++ b/ripemd-256.c @@ -0,0 +1,32 @@ +/* See LICENSE file for copyright and license details. */ +#define TEST +#include "common.h" + + +static struct testcase testcases[] = { +	{1, 0, "", +	 "02ba4c4e5f8ecd1877fc52d64d30e37a2d9774fb1e5d026380ae0168e3c5522d"}, +	{1, 0, "a", +	 "f9333e45d857f5d90a91bab70a1eba0cfb1be4b0783c9acfcd883a9134692925"}, +	{1, 0, "abc", +	 "afbd6e228b9d8cbbcef5ca2d03e6dba10ac0bc7dcbe4680e1e42d2e975459b65"}, +	{1, 0, "message digest", +	 "87e971759a1ce47a514d5c914c392c9018c7c46bc14465554afcdf54a5070c0e"}, +	{1, 0, "abcdefghijklmnopqrstuvwxyz", +	 "649d3034751ea216776bf9a18acc81bc7896118a5197968782dd1fd97d8d5133"}, +	{1, 0, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", +	 "3843045583aac6c8c8d9128573e7a9809afb2a0f34ccc36ea9e72f16f6368e3f"}, +	{1, 0, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", +	 "5740a408ac16b720b84424ae931cbb1fe363d1d0bf4017f1a89f7ea6de77a0b8"}, +	{8, 0, "1234567890", +	 "06fdcc7a409548aaf91368c06a6275b553e3f099bf0ea4edfd6778df89a890dd"}, +	{1000000UL, 0, "a", +	 "ac953744e10e31514c150d4d8d7b677342e33399788296e43ae4850ce4f97978"} +}; + + +int +main(void) +{ +	TEST_MAIN("RIPEMD-256", RIPEMD_256); +} diff --git a/ripemd-320.c b/ripemd-320.c new file mode 100644 index 0000000..ea39bc6 --- /dev/null +++ b/ripemd-320.c @@ -0,0 +1,32 @@ +/* See LICENSE file for copyright and license details. */ +#define TEST +#include "common.h" + + +static struct testcase testcases[] = { +	{1, 0, "", +	 "22d65d5661536cdc75c1fdf5c6de7b41b9f27325ebc61e8557177d705a0ec880151c3a32a00899b8"}, +	{1, 0, "a", +	 "ce78850638f92658a5a585097579926dda667a5716562cfcf6fbe77f63542f99b04705d6970dff5d"}, +	{1, 0, "abc", +	 "de4c01b3054f8930a79d09ae738e92301e5a17085beffdc1b8d116713e74f82fa942d64cdbc4682d"}, +	{1, 0, "message digest", +	 "3a8e28502ed45d422f68844f9dd316e7b98533fa3f2a91d29f84d425c88d6b4eff727df66a7c0197"}, +	{1, 0, "abcdefghijklmnopqrstuvwxyz", +	 "cabdb1810b92470a2093aa6bce05952c28348cf43ff60841975166bb40ed234004b8824463e6b009"}, +	{1, 0, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", +	 "d034a7950cf722021ba4b84df769a5de2060e259df4c9bb4a4268c0e935bbc7470a969c9d072a1ac"}, +	{1, 0, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", +	 "ed544940c86d67f250d232c30b7b3e5770e0c60c8cb9a4cafe3b11388af9920e1b99230b843c86a4"}, +	{8, 0, "1234567890", +	 "557888af5f6d8ed62ab66945c6d2a0a47ecd5341e915eb8fea1d0524955f825dc717e4a008ab2d42"}, +	{1000000UL, 0, "a", +	 "bdee37f4371e20646b8b0d862dda16292ae36f40965e8c8509e63d1dbddecc503e2b63eb9245bb66"} +}; + + +int +main(void) +{ +	TEST_MAIN("RIPEMD-320", RIPEMD_320); +} | 
