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 8a04c7dc23a9055155489ddbd6cc69c785d42d47
Author: nolash <dev@holbrook.no>
Date:   Sun, 12 Sep 2021 09:59:01 +0200

Initial commit

Diffstat:
AMakefile.dev | 14++++++++++++++
Asrc/bmt.c | 35+++++++++++++++++++++++++++++++++++
Asrc/bmt.h | 17+++++++++++++++++
Asrc/endian.c | 44++++++++++++++++++++++++++++++++++++++++++++
Asrc/endian.h | 19+++++++++++++++++++
Atest/check_bmt.c | 44++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 173 insertions(+), 0 deletions(-)

diff --git a/Makefile.dev b/Makefile.dev @@ -0,0 +1,14 @@ +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 + +build_test: build + gcc -I./src -o test/check_bmt lib/*.o test/check_bmt.c $(CFLAGS) -lcheck -lkeccak + +.PHONY: test + +test: build build_test + CK_FORK=no test/check_bmt diff --git a/src/bmt.c b/src/bmt.c @@ -0,0 +1,35 @@ +#include <string.h> + +#include <XKCP/KeccakHash.h> +#include <XKCP/KangarooTwelve.h> +#include <XKCP/SP800-185.h> + +#include "bmt.h" + +#define DIGEST_INPUT_SIZE WORD_SIZE * 2 + +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; + } + Keccak_HashUpdate(&instance, bmt_content->ptr, DIGEST_INPUT_SIZE); + Keccak_HashFinal(&instance, bmt_content->ptr); + } +} + +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->target = bmt_content->ptr + BLOCK_SIZE; + memset(bmt_content->ptr, 0, BLOCK_SIZE); + 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); + return bmt_rollup(bmt_content); + return 0; +} + + diff --git a/src/bmt.h b/src/bmt.h @@ -0,0 +1,17 @@ +#ifndef _LIBSWARM_BMT +#define _LIBSWARM_BMT + +#define BLOCK_SIZE 4096 +#define WORD_SIZE 32 + +typedef struct bmt { + char buf[BLOCK_SIZE + 8]; + 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); + +#endif // _LIBSWARM_BMT diff --git a/src/endian.c b/src/endian.c @@ -0,0 +1,44 @@ +#include "endian.h" + +int is_le() { + short s = 42; + return *((unsigned char*)&s) == 42; +} + +// convert unsigned integer to little-endian representation +int to_endian(char direction, int l, void *n) { + union le un; + + if (l == 1 || is_le() == direction) { + return 0; + } + switch(l) { + case sizeof(long long): + un.ll = (long long*)n; + break; + case sizeof(int): + un.i = (int*)n; + break; + case sizeof(short): + un.s = (short*)n; + break; + default: + return 1; + } + flip_endian(l, &un); + + return 0; +} + +void flip_endian(int l, union le *n) { + int i; + char t; + char *ne; + + ne = (n->c)+(l-1); + for (i = 0; i < l/2; i++) { + t = *(n->c+i); + *((n->c)+i) = *(ne-i); + *(ne-i) = t; + } +} diff --git a/src/endian.h b/src/endian.h @@ -0,0 +1,19 @@ +#ifndef LASH_ENDIAN_H_ +#define LASH_ENDIAN_H_ + +#define CONVERT_BIGENDIAN 0x00 +#define CONVERT_LITTLEENDIAN 0x01 + +union le { + short *s; + int *i; + long long *ll; + unsigned char *c; +}; + +int le(int l, void *n); +int is_le(); +int to_endian(char direction, int l, void *n); +void flip_endian(int l, union le *n); + +#endif // LASH_ENDIAN_H_ diff --git a/test/check_bmt.c b/test/check_bmt.c @@ -0,0 +1,44 @@ +#include <check.h> +#include <stdlib.h> + +#include "bmt.h" + + +START_TEST(check_bmt_init) { + bmt_t bmt_context; + char *data = "foo"; + char data_length = 3; + int r; + + bmt_init(&bmt_context, data, data_length, 3); + ck_assert_mem_eq(bmt_context.ptr, data, 3); +} +END_TEST + +Suite * common_suite(void) { + Suite *s; + TCase *tc; + + s = suite_create("bmt"); + tc = tcase_create("core"); + tcase_add_test(tc, check_bmt_init); + suite_add_tcase(s, tc); + + return s; +} + +int main(void) { + int n_fail; + + Suite *s; + SRunner *sr; + + s = common_suite(); + sr = srunner_create(s); + + srunner_run_all(sr, CK_VERBOSE); + n_fail = srunner_ntests_failed(sr); + srunner_free(sr); + + return (n_fail == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +}