Line data Source code
1 : #ifndef HEADER_fd_src_ballet_lthash_fd_lthash_h 2 : #define HEADER_fd_src_ballet_lthash_fd_lthash_h 3 : 4 : /* LtHash provides APIs for lattice-based incremental hash based on blake3. 5 : https://eprint.iacr.org/2019/227 6 : */ 7 : 8 : #include "../blake3/fd_blake3.h" 9 : 10 : #define FD_LTHASH_ALIGN (64UL) /* sufficient for AVX512 */ 11 924 : #define FD_LTHASH_LEN_BYTES (2048UL) 12 947100 : #define FD_LTHASH_LEN_ELEMS (1024UL) 13 : 14 : union __attribute__((aligned(FD_LTHASH_ALIGN))) fd_lthash_value { 15 : uchar bytes[FD_LTHASH_LEN_BYTES]; 16 : ushort words[FD_LTHASH_LEN_ELEMS]; 17 : }; 18 : typedef union fd_lthash_value fd_lthash_value_t; 19 : 20 : FD_PROTOTYPES_BEGIN 21 : 22 : static inline fd_lthash_value_t * 23 : fd_lthash_fini( fd_blake3_t * sha, 24 0 : fd_lthash_value_t * hash ) { 25 0 : return fd_blake3_fini_2048( sha, hash->bytes ); 26 0 : } 27 : 28 : static inline fd_lthash_value_t * 29 924 : fd_lthash_zero( fd_lthash_value_t * r ) { 30 924 : return fd_memset( r->bytes, 0, FD_LTHASH_LEN_BYTES ); 31 924 : } 32 : 33 : static inline int 34 0 : fd_lthash_is_zero( fd_lthash_value_t const * r ) { 35 0 : for ( ulong i=0; i<FD_LTHASH_LEN_ELEMS; i++ ) { 36 0 : if( r->words[i] != 0 ) { 37 0 : return 0; /* not zero */ 38 0 : } 39 0 : } 40 0 : 41 0 : return 1; 42 0 : } 43 : 44 : static inline fd_lthash_value_t * 45 : fd_lthash_add( fd_lthash_value_t * restrict r, 46 462 : fd_lthash_value_t const * restrict a ) { 47 473550 : for ( ulong i=0; i<FD_LTHASH_LEN_ELEMS; i++ ) { 48 473088 : r->words[i] = (ushort)( r->words[i] + a->words[i] ); 49 473088 : } 50 462 : return r; 51 462 : } 52 : 53 : static inline fd_lthash_value_t * 54 : fd_lthash_sub( fd_lthash_value_t * restrict r, 55 462 : fd_lthash_value_t const * restrict a ) { 56 473550 : for ( ulong i=0; i<FD_LTHASH_LEN_ELEMS; i++ ) { 57 473088 : r->words[i] = (ushort)( r->words[i] - a->words[i] ); 58 473088 : } 59 462 : return r; 60 462 : } 61 : 62 : #define FD_LTHASH_ENC_32_BUF( _x, _y ) __extension__({ \ 63 : if( FD_UNLIKELY( _x == NULL ) ) { \ 64 : strcpy(_y, "<NULL>"); \ 65 : } else { \ 66 : uchar _blake3_hash[FD_HASH_FOOTPRINT]; \ 67 : fd_blake3_hash(_x, FD_LTHASH_LEN_BYTES, _blake3_hash ); \ 68 : fd_base58_encode_32( _blake3_hash, NULL, _y ); \ 69 : } \ 70 : }) 71 : 72 : #define FD_LTHASH_ENC_32_ALLOCA( x ) __extension__({ \ 73 : char *_out = (char *)fd_alloca_check( 1UL, FD_BASE58_ENCODED_32_SZ ); \ 74 : FD_LTHASH_ENC_32_BUF(x, _out); \ 75 : _out; \ 76 : }) 77 : 78 : FD_PROTOTYPES_END 79 : 80 : #endif /* HEADER_fd_src_ballet_lthash_fd_lthash_h */