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