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

bmt.c (2389B)


      1 #include <string.h>
      2 #include <stdlib.h>
      3 
      4 #include "keccak-tiny.h"
      5 #include "endian.h"
      6 
      7 #include "swarm.h"
      8 #ifdef LIBSWARM_MALLOC
      9 #include "bmt_malloc.h"
     10 #else
     11 #include "bmt.h"
     12 #endif
     13 
     14 #define _SWARM_DIGEST_INPUT_SIZE SWARM_WORD_SIZE*2
     15 #define _SWARM_ROLLUP_TARGET SWARM_BLOCK_SIZE + SWARM_DATA_LENGTH_TYPESIZE + SWARM_WORD_SIZE
     16 
     17 extern void dlog(int p, int v);
     18 
     19 static int bmt_rollup(bmt_t *bctx) {
     20 	unsigned char *last_target = bctx->w_ptr + SWARM_WORD_SIZE;
     21 	unsigned char *start = bctx->w_ptr;
     22 	unsigned char buf[256];
     23 	int r;
     24 
     25 	while (last_target != 0x00) {
     26 		while (bctx->r_ptr < bctx->target) {
     27 			r = keccak_hash_btc((unsigned char*)buf, SWARM_WORD_SIZE, (unsigned char*)bctx->r_ptr, _SWARM_DIGEST_INPUT_SIZE);
     28 			if (r < 0) {
     29 				return 1;
     30 			}
     31 			memcpy(bctx->w_ptr, buf, SWARM_WORD_SIZE);
     32 			bctx->w_ptr += SWARM_WORD_SIZE;
     33 			bctx->r_ptr += _SWARM_DIGEST_INPUT_SIZE;
     34 		}
     35 		bctx->target = start + ((bctx->target - start) / 2);
     36 		if (bctx->target == last_target) {
     37 			last_target = 0x00;
     38 		}
     39 		bctx->r_ptr = start;
     40 		bctx->w_ptr = start;
     41 	}
     42 
     43 	r = keccak_hash_btc((unsigned char*)buf, SWARM_WORD_SIZE, (unsigned char*)bctx->buf, SWARM_DATA_LENGTH_TYPESIZE + SWARM_WORD_SIZE);
     44 	if (r < 0) {
     45 		return 1;
     46 	}
     47 	memcpy(bctx->buf, buf, SWARM_WORD_SIZE);
     48 	return 0;
     49 }
     50 
     51 void bmt_init(bmt_t *bctx, const unsigned char *input, const size_t input_length, const bmt_spansize_t data_length) {
     52 #ifdef LIBSWARM_MALLOC
     53 	bctx->buf = malloc(sizeof(unsigned char) * SWARM_DATA_LENGTH_TYPESIZE + SWARM_BLOCK_SIZE);
     54 #endif
     55 	bctx->w_ptr = bctx->buf + SWARM_DATA_LENGTH_TYPESIZE;
     56 	bctx->r_ptr = bctx->w_ptr;
     57 	bctx->target = bctx->w_ptr + SWARM_BLOCK_SIZE;
     58 	memset(bctx->buf, 0, SWARM_DATA_LENGTH_TYPESIZE + SWARM_BLOCK_SIZE);
     59 
     60 	memcpy((unsigned char*)bctx->buf, &data_length, sizeof(bmt_spansize_t));
     61 	to_endian(CONVERT_LITTLEENDIAN, SWARM_DATA_LENGTH_TYPESIZE, (unsigned char*)bctx->buf);
     62 
     63 	memcpy(bctx->w_ptr, input, input_length);
     64 }
     65 
     66 int bmt_sum(bmt_t *bctx) {
     67 	return bmt_rollup(bctx);
     68 }
     69 
     70 
     71 int bmt_hash(unsigned char *zOut, const unsigned char *input, const size_t input_length, const bmt_spansize_t data_length) {
     72 	int i;
     73 	int r;
     74 
     75 	bmt_t bctx;
     76 	bmt_init(&bctx,	input, input_length, data_length);
     77 	r = bmt_sum(&bctx);
     78 	memcpy(zOut, bctx.buf, SWARM_WORD_SIZE);
     79 #ifdef LIBSWARM_MALLOC
     80 	bmt_free(&bctx);
     81 #endif
     82 	return r;
     83 }
     84 
     85 #ifdef LIBSWARM_MALLOC
     86 void bmt_free(bmt_t *bctx) {
     87 	free(bctx->buf);
     88 }
     89 #endif