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 "../fd_ballet_base.h"
9 : #include "../blake3/fd_blake3.h"
10 :
11 0 : #define FD_LTHASH_ALIGN (FD_BLAKE3_ALIGN)
12 0 : #define FD_LTHASH_LEN_BYTES (2048UL)
13 0 : #define FD_LTHASH_LEN_ELEMS (1024UL)
14 :
15 : union __attribute__((aligned(FD_LTHASH_ALIGN))) fd_lthash_value {
16 : uchar bytes[FD_LTHASH_LEN_BYTES];
17 : ushort words[FD_LTHASH_LEN_ELEMS];
18 : };
19 : typedef union fd_lthash_value fd_lthash_value_t;
20 :
21 0 : #define FD_LTHASH_VALUE_ALIGN (FD_LTHASH_ALIGN)
22 0 : #define FD_LTHASH_VALUE_FOOTPRINT sizeof(fd_lthash_value_t)
23 :
24 : #define fd_lthash_t fd_blake3_t
25 :
26 : FD_PROTOTYPES_BEGIN
27 :
28 : #define fd_lthash_init fd_blake3_init
29 : #define fd_lthash_append fd_blake3_append
30 :
31 : static inline fd_lthash_value_t *
32 : fd_lthash_fini( fd_lthash_t * sha,
33 0 : fd_lthash_value_t * hash ) {
34 0 : return fd_blake3_fini_varlen( sha, hash->bytes, FD_LTHASH_LEN_BYTES );
35 0 : }
36 :
37 : static inline fd_lthash_value_t *
38 0 : fd_lthash_zero( fd_lthash_value_t * r ) {
39 0 : return fd_memset( r->bytes, 0, FD_LTHASH_LEN_BYTES );
40 0 : }
41 :
42 : static inline fd_lthash_value_t *
43 : fd_lthash_add( fd_lthash_value_t * restrict r,
44 0 : fd_lthash_value_t const * restrict a ) {
45 0 : for ( ulong i=0; i<FD_LTHASH_LEN_ELEMS; i++ ) {
46 0 : r->words[i] = (ushort)( r->words[i] + a->words[i] );
47 0 : }
48 0 : return r;
49 0 : }
50 :
51 : static inline fd_lthash_value_t *
52 : fd_lthash_sub( fd_lthash_value_t * restrict r,
53 0 : fd_lthash_value_t const * restrict a ) {
54 0 : for ( ulong i=0; i<FD_LTHASH_LEN_ELEMS; i++ ) {
55 0 : r->words[i] = (ushort)( r->words[i] - a->words[i] );
56 0 : }
57 0 : return r;
58 0 : }
59 :
60 : static inline void
61 0 : fd_lthash_hash( fd_lthash_value_t const * r, uchar hash[ static 32] ) {
62 0 : ulong *p = (ulong *) r->bytes;
63 0 : for ( ulong i=0; i<(FD_LTHASH_LEN_BYTES / sizeof(ulong)); i++ ) {
64 0 : if (*p++ != 0) {
65 0 : fd_blake3_t b3[1];
66 0 : fd_blake3_init ( b3 );
67 0 : fd_blake3_append( b3, r->bytes, FD_LTHASH_LEN_BYTES );
68 0 : fd_blake3_fini ( b3, hash );
69 0 : return;
70 0 : }
71 0 : }
72 :
73 0 : fd_memset(hash, 0, 32);
74 0 : }
75 :
76 : #define FD_LTHASH_ENC_32_BUF( _x, _y ) __extension__({ \
77 : if( FD_UNLIKELY( _x == NULL ) ) { \
78 : strcpy(_y, "<NULL>"); \
79 : } else { \
80 : uchar _hash[32]; \
81 : fd_lthash_hash(_x, _hash); \
82 : fd_base58_encode_32( _hash, NULL, _y ); \
83 : } \
84 : })
85 :
86 : #define FD_LTHASH_ENC_32_ALLOCA( x ) __extension__({ \
87 : char *_out = (char *)fd_alloca_check( 1UL, FD_BASE58_ENCODED_32_SZ ); \
88 : FD_LTHASH_ENC_32_BUF(x, _out); \
89 : _out; \
90 : })
91 :
92 : #define FD_LTHASH_ADD( x, y, z ) __extension__({ \
93 : char _b[FD_BASE58_ENCODED_32_SZ]; \
94 : FD_LTHASH_ENC_32_BUF(x, _b); \
95 : fd_lthash_add( x, y ); \
96 : char _c[FD_BASE58_ENCODED_32_SZ]; \
97 : FD_LTHASH_ENC_32_BUF(y, _c); \
98 : char _d[FD_BASE58_ENCODED_32_SZ]; \
99 : FD_LTHASH_ENC_32_BUF(x, _d); \
100 : FD_LOG_NOTICE(("%s, fd_lthash_add, %s, %s, %s", z, _b, _c, _d)); \
101 : })
102 :
103 : #define FD_LTHASH_SUB( x, y, z ) __extension__({ \
104 : char _b[FD_BASE58_ENCODED_32_SZ]; \
105 : FD_LTHASH_ENC_32_BUF(x, _b); \
106 : fd_lthash_sub( x, y ); \
107 : char _c[FD_BASE58_ENCODED_32_SZ]; \
108 : FD_LTHASH_ENC_32_BUF(y, _c); \
109 : char _d[FD_BASE58_ENCODED_32_SZ]; \
110 : FD_LTHASH_ENC_32_BUF(x, _d); \
111 : FD_LOG_NOTICE(("%s, fd_lthash_sub, %s, %s, %s", z, _b, _c, _d)); \
112 : })
113 :
114 : #define FD_LTHASH_ADD_2( x, y ) __extension__({ \
115 : fd_lthash_add( x, y ); \
116 : })
117 :
118 : #define FD_LTHASH_SUB_2( x, y ) __extension__({ \
119 : fd_lthash_sub( x, y ); \
120 : })
121 :
122 :
123 : FD_PROTOTYPES_END
124 :
125 : #endif /* HEADER_fd_src_ballet_lthash_fd_lthash_h */
|