commit c749ff1ece8690bfe11b12c70db821ee7d065d4e
parent d1926b628743376ea13ae8fac5102df53e1298ab
Author: nolash <dev@holbrook.no>
Date: Tue, 14 Sep 2021 12:58:41 +0200
Add next level hasher
Diffstat:
5 files changed, 96 insertions(+), 36 deletions(-)
diff --git a/src/bmt.c b/src/bmt.c
@@ -5,26 +5,26 @@
#include "bmt.h"
-#define _DIGEST_INPUT_SIZE _WORD_SIZE*2
-#define _ROLLUP_TARGET BLOCK_SIZE + _DATA_LENGTH_TYPESIZE + _WORD_SIZE
+#define _SWARM_DIGEST_INPUT_SIZE _SWARM_WORD_SIZE*2
+#define _SWARM_ROLLUP_TARGET SWARM_BLOCK_SIZE + _SWARM_DATA_LENGTH_TYPESIZE + _SWARM_WORD_SIZE
#define _KECCAK_RATE 200-64
#define _KECCAK_PADDING 0x01
static int bmt_rollup(bmt_t *bmt_content) {
- char *last_target = bmt_content->w_ptr + _WORD_SIZE;
+ char *last_target = bmt_content->w_ptr + _SWARM_WORD_SIZE;
char *start = bmt_content->w_ptr;
char buf[256];
int r;
while (last_target != 0x00) {
while (bmt_content->r_ptr < bmt_content->target) {
- r = keccak_hash((unsigned char*)buf, _WORD_SIZE, (unsigned char*)bmt_content->r_ptr, _DIGEST_INPUT_SIZE, _KECCAK_RATE, _KECCAK_PADDING);
+ r = keccak_hash((unsigned char*)buf, _SWARM_WORD_SIZE, (unsigned char*)bmt_content->r_ptr, _SWARM_DIGEST_INPUT_SIZE, _KECCAK_RATE, _KECCAK_PADDING);
if (r != 0) {
return 1;
}
- memcpy(bmt_content->w_ptr, buf, _WORD_SIZE);
- bmt_content->w_ptr += _WORD_SIZE;
- bmt_content->r_ptr += _DIGEST_INPUT_SIZE;
+ memcpy(bmt_content->w_ptr, buf, _SWARM_WORD_SIZE);
+ bmt_content->w_ptr += _SWARM_WORD_SIZE;
+ bmt_content->r_ptr += _SWARM_DIGEST_INPUT_SIZE;
}
bmt_content->target = start + ((bmt_content->target - start) / 2);
if (bmt_content->target == last_target) {
@@ -34,24 +34,24 @@ static int bmt_rollup(bmt_t *bmt_content) {
bmt_content->w_ptr = start;
}
- r = keccak_hash((unsigned char*)buf, _WORD_SIZE, (unsigned char*)bmt_content->buf, _DATA_LENGTH_TYPESIZE + _WORD_SIZE, _KECCAK_RATE, _KECCAK_PADDING);
+ r = keccak_hash((unsigned char*)buf, _SWARM_WORD_SIZE, (unsigned char*)bmt_content->buf, _SWARM_DATA_LENGTH_TYPESIZE + _SWARM_WORD_SIZE, _KECCAK_RATE, _KECCAK_PADDING);
if (r != 0) {
return 1;
}
- memcpy(bmt_content->buf, buf, _WORD_SIZE);
+ memcpy(bmt_content->buf, buf, _SWARM_WORD_SIZE);
return 0;
}
-void bmt_init(bmt_t *bmt_content, char *input, size_t input_length, long long data_length) {
- bmt_content->w_ptr = (char*)bmt_content->buf+_DATA_LENGTH_TYPESIZE;
+void bmt_init(bmt_t *bmt_content, const char *input, const size_t input_length, const long long data_length) {
+ bmt_content->w_ptr = (char*)bmt_content->buf+_SWARM_DATA_LENGTH_TYPESIZE;
bmt_content->r_ptr = bmt_content->w_ptr;
- bmt_content->target = bmt_content->w_ptr + BLOCK_SIZE;
+ bmt_content->target = bmt_content->w_ptr + SWARM_BLOCK_SIZE;
- memset(bmt_content->buf, 0, _DATA_LENGTH_TYPESIZE + BLOCK_SIZE);
+ memset(bmt_content->buf, 0, _SWARM_DATA_LENGTH_TYPESIZE + SWARM_BLOCK_SIZE);
memcpy((char*)bmt_content->buf, &data_length, sizeof(long long));
- to_endian(CONVERT_LITTLEENDIAN, _DATA_LENGTH_TYPESIZE, (unsigned char*)bmt_content->buf);
+ to_endian(CONVERT_LITTLEENDIAN, _SWARM_DATA_LENGTH_TYPESIZE, (unsigned char*)bmt_content->buf);
memcpy(bmt_content->w_ptr, input, input_length);
}
diff --git a/src/bmt.h b/src/bmt.h
@@ -1,18 +1,18 @@
#ifndef _LIBSWARM_BMT
#define _LIBSWARM_BMT
-#define BLOCK_SIZE 4096
-#define _WORD_SIZE 32
-#define _DATA_LENGTH_TYPESIZE 8
+#define SWARM_BLOCK_SIZE 4096
+#define _SWARM_WORD_SIZE 32
+#define _SWARM_DATA_LENGTH_TYPESIZE 8
typedef struct bmt {
- char buf[_DATA_LENGTH_TYPESIZE + BLOCK_SIZE];
+ char buf[_SWARM_DATA_LENGTH_TYPESIZE + SWARM_BLOCK_SIZE];
char *w_ptr;
char *r_ptr;
char *target;
} 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);
+void bmt_init(bmt_t *bmt_context, const char *input, const size_t input_length, const long long data_length);
+int bmt_sum(bmt_t *bmt_context);
#endif // _LIBSWARM_BMT
diff --git a/src/file.c b/src/file.c
@@ -1,15 +1,70 @@
#include <stddef.h>
+#include <string.h>
#include "file.h"
-int filehash_init(filehash_t *filehash_context) {
+void filehash_reset(filehash_t *fctx) {
int i;
+ for (i = 0; i < SWARM_LEVELS; i++) {
+ fctx->ptr[i] = fctx->buf;
+ fctx->writes[i] = 0;
+ }
+ fctx->length = 0;
+}
+
+void filehash_init(filehash_t *fctx) {
+ int i;
+ int l;
+
+ l = SWARM_BLOCK_SIZE;
for (i = 0; i < SWARM_LEVELS; i++) {
- filehash_context->ptr[i] = filehash_context->buf;
+ fctx->spans[i] = l;
+ l *= _SWARM_BATCH_SIZE;
+ }
+
+ filehash_reset(fctx);
+}
+
+static int filehash_write_hash(filehash_t *fctx, int level, const char *data) {
+ bmt_t *bctx;
+ int next_level;
+ int r;
+
+
+ fctx->writes[level] += 1;
+ memcpy(fctx->ptr[level], data, _SWARM_WORD_SIZE);
+ if (fctx->writes[level] == _SWARM_BATCH_SIZE) {
+ bctx = &fctx->bmt_context;
+ next_level = level + 1;
+ bmt_init(bctx, fctx->ptr[next_level], SWARM_BLOCK_SIZE, (long long)fctx->spans[next_level]);
+ r = bmt_sum(bctx);
+ if (r != 0) {
+ return -1;
+ }
+ filehash_write_hash(fctx, level + 1, bctx->buf);
+ } else {
+ fctx->ptr[level] += _SWARM_WORD_SIZE;
}
- filehash_context->length = 0;
- filehash_context->writes = 0;
-
return 0;
}
+
+int filehash_write(filehash_t *fctx, const char *data, const size_t data_length) {
+ bmt_t *bctx;
+ int r;
+
+ bctx = &fctx->bmt_context;
+
+ bmt_init(bctx, data, data_length, (long long)data_length);
+ r = bmt_sum(bctx);
+ if (r != 0) {
+ return -1;
+ }
+ r = filehash_write_hash(fctx, 0, bctx->buf);
+ if (r != 0) {
+ return -1;
+ }
+ fctx->length += data_length;
+
+ return data_length;
+}
diff --git a/src/file.h b/src/file.h
@@ -3,18 +3,21 @@
#include "bmt.h"
-#define SWARM_BATCH_SIZE (int)(BLOCK_SIZE / _WORD_SIZE)
+#define _SWARM_BATCH_SIZE (int)(SWARM_BLOCK_SIZE / _SWARM_WORD_SIZE)
#define SWARM_LEVELS 9
typedef struct filehash {
- char buf[SWARM_LEVELS][BLOCK_SIZE];
+ char buf[SWARM_LEVELS * SWARM_BLOCK_SIZE];
char *ptr[SWARM_LEVELS];
- long long byte_length;
- long long writes;
+ long long writes[SWARM_LEVELS];
+ long long spans[SWARM_LEVELS];
+ long long length;
+ bmt_t bmt_context;
} filehash_t;
-int filehash_init(filehash_t *filehash_context);
-int filehash_write(filehash_t *filehash_context, char *data, size_t data_length);
+void filehash_reset(filehash_t *filehash_context);
+void filehash_init(filehash_t *filehash_context);
+int filehash_write(filehash_t *filehash_context, const char *data, const size_t data_length);
int filehash_sum(filehash_t *filehash_content);
#endif // _LIBSWARM_FILE
diff --git a/test/check_file.c b/test/check_file.c
@@ -6,15 +6,15 @@
START_TEST(check_file_init) {
- ck_assert_int_eq(SWARM_BATCH_SIZE, 128);
+ ck_assert_int_eq(_SWARM_BATCH_SIZE, 128);
filehash_t fh;
int r;
- r = filehash_init(&fh);
+ filehash_init(&fh);
- ck_assert_int_eq(r, 0);
ck_assert_ptr_eq(fh.ptr[SWARM_LEVELS-1], fh.buf);
+ ck_assert_int_eq(fh.spans[1], _SWARM_BATCH_SIZE * SWARM_BLOCK_SIZE);
}
END_TEST
@@ -22,12 +22,14 @@ START_TEST(check_file_single_write) {
filehash_t fh;
int r;
- char *data = "foo";
-
+ const char *data = "foo";
filehash_init(&fh);
r = filehash_write(&fh, data, strlen(data));
+ ck_assert_int_eq(r, 3);
+ ck_assert_int_eq(fh.writes[0], 1);
+ ck_assert_int_eq(fh.length, 3);
}
END_TEST