libswarm-ng

C implementation of BMT hasher, Swarmhash and Single Owner Chunk for swarm
git clone git://git.defalsify.org/libswarm-ng.git
Log | Files | Refs | Submodules | README

commit 8fc4cf4afebe363c8023b00b7e2cae18d15b5a2d
parent 8a04c7dc23a9055155489ddbd6cc69c785d42d47
Author: nolash <dev@holbrook.no>
Date:   Sun, 12 Sep 2021 10:35:46 +0200

Split init and sum, add length prefix

Diffstat:
MMakefile.dev | 8++++----
Msrc/bmt.c | 49+++++++++++++++++++++++++++++++++++++------------
Msrc/bmt.h | 8++++----
Msrc/endian.c | 2+-
Mtest/check_bmt.c | 21+++++++++++++++++----
5 files changed, 63 insertions(+), 25 deletions(-)

diff --git a/Makefile.dev b/Makefile.dev @@ -1,12 +1,12 @@ export LD_LIBRARY_PATH build: - mkdir -p build lib - gcc -I./src -c -o lib/bmt.o src/bmt.c $(CFLAGS) -lkeccak - gcc -I./src -c -o lib/endian.o $(CFLAGS) src/endian.c + mkdir -p build + gcc -I./src -c -o build/bmt.o src/bmt.c $(CFLAGS) -lkeccak + gcc -I./src -c -o build/endian.o $(CFLAGS) src/endian.c build_test: build - gcc -I./src -o test/check_bmt lib/*.o test/check_bmt.c $(CFLAGS) -lcheck -lkeccak + gcc -I./src -o test/check_bmt build/*.o test/check_bmt.c $(CFLAGS) -lcheck -lkeccak .PHONY: test diff --git a/src/bmt.c b/src/bmt.c @@ -3,33 +3,58 @@ #include <XKCP/KeccakHash.h> #include <XKCP/KangarooTwelve.h> #include <XKCP/SP800-185.h> +#include "endian.h" #include "bmt.h" -#define DIGEST_INPUT_SIZE WORD_SIZE * 2 +#define _DIGEST_INPUT_SIZE _WORD_SIZE * 2 +#define _ROLLUP_TARGET BLOCK_SIZE + _DATA_LENGTH_TYPESIZE + _WORD_SIZE + static int bmt_rollup(bmt_t *bmt_content) { - while (bmt_content->ptr != bmt_content->target) { - Keccak_HashInstance instance; - if (Keccak_HashInitialize(&instance, 1088, 512, 256, 0x01)) { - return 1; + char *last_target = bmt_content->ptr + _WORD_SIZE; + + while (last_target != 0x00) { + while (bmt_content->ptr != bmt_content->target) { + Keccak_HashInstance instance; + if (Keccak_HashInitialize(&instance, 1088, 512, 256, 0x01)) { + return 1; + } + Keccak_HashUpdate(&instance, bmt_content->ptr, _DIGEST_INPUT_SIZE); + Keccak_HashFinal(&instance, bmt_content->ptr); + bmt_content->ptr += _DIGEST_INPUT_SIZE; + } + bmt_content->target = (bmt_content->target - bmt_content->ptr) / 2; + if (bmt_content->target < last_target) { + last_target = 0x00; } - Keccak_HashUpdate(&instance, bmt_content->ptr, DIGEST_INPUT_SIZE); - Keccak_HashFinal(&instance, bmt_content->ptr); } + + Keccak_HashInstance instance; + if (Keccak_HashInitialize(&instance, 1088, 512, 256, 0x01)) { + return 1; + } + Keccak_HashUpdate(&instance, bmt_content->buf, _DATA_LENGTH_TYPESIZE + _WORD_SIZE); + Keccak_HashFinal(&instance, bmt_content->buf); + + return 0; } + void bmt_init(bmt_t *bmt_content, char *input, size_t input_length, long long data_length) { - bmt_content->ptr = (char*)bmt_content->buf+8; + bmt_content->ptr = (char*)bmt_content->buf+_DATA_LENGTH_TYPESIZE; bmt_content->target = bmt_content->ptr + BLOCK_SIZE; - memset(bmt_content->ptr, 0, BLOCK_SIZE); + memset(bmt_content->buf, 0, BLOCK_SIZE+_DATA_LENGTH_TYPESIZE); + + memcpy((char*)bmt_content->buf, &data_length, sizeof(long long)); + to_endian(CONVERT_BIGENDIAN, _DATA_LENGTH_TYPESIZE, bmt_content->buf); + memcpy(bmt_content->ptr, input, input_length); } -int bmt_sum(bmt_t *bmt_content, char *input, size_t input_length, long long data_length) { - bmt_init(bmt_content, input, input_length, data_length); + +int bmt_sum(bmt_t *bmt_content) { return bmt_rollup(bmt_content); - return 0; } diff --git a/src/bmt.h b/src/bmt.h @@ -2,16 +2,16 @@ #define _LIBSWARM_BMT #define BLOCK_SIZE 4096 -#define WORD_SIZE 32 +#define _WORD_SIZE 32 +#define _DATA_LENGTH_TYPESIZE 8 typedef struct bmt { - char buf[BLOCK_SIZE + 8]; + char buf[BLOCK_SIZE + _DATA_LENGTH_TYPESIZE]; char *ptr; char *target; - long long data_length; } bmt_t; void bmt_init(bmt_t *bmt_content, char *input, size_t input_length, long long data_length); -int bmt_sum(bmt_t *bmt_content, char *input, size_t input_length, long long data_length); +int bmt_sum(bmt_t *bmt_content); #endif // _LIBSWARM_BMT diff --git a/src/endian.c b/src/endian.c @@ -5,7 +5,7 @@ int is_le() { return *((unsigned char*)&s) == 42; } -// convert unsigned integer to little-endian representation +// convert unsigned integer to the given endian representation int to_endian(char direction, int l, void *n) { union le un; diff --git a/test/check_bmt.c b/test/check_bmt.c @@ -6,15 +6,27 @@ START_TEST(check_bmt_init) { bmt_t bmt_context; - char *data = "foo"; - char data_length = 3; + char *input = "foo"; + char input_length = 3; + char data_length_bytes[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03}; int r; - bmt_init(&bmt_context, data, data_length, 3); - ck_assert_mem_eq(bmt_context.ptr, data, 3); + bmt_init(&bmt_context, input, input_length, 3); + ck_assert_mem_eq(bmt_context.buf, data_length_bytes, sizeof(long long)); + ck_assert_mem_eq(bmt_context.ptr, input, 3); } END_TEST + +START_TEST(check_bmt_sum) { + bmt_t bmt_context; + char *input = "foo"; + char input_length = 3; + + bmt_init(&bmt_context, input, input_length, 3); + bmt_sum(&bmt_context); +} + Suite * common_suite(void) { Suite *s; TCase *tc; @@ -22,6 +34,7 @@ Suite * common_suite(void) { s = suite_create("bmt"); tc = tcase_create("core"); tcase_add_test(tc, check_bmt_init); + tcase_add_test(tc, check_bmt_sum); suite_add_tcase(s, tc); return s;