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 int
43 0 : fd_lthash_is_zero( fd_lthash_value_t const * r ) {
44 0 : for ( ulong i=0; i<FD_LTHASH_LEN_ELEMS; i++ ) {
45 0 : if( r->words[i] != 0 ) {
46 0 : return 0; /* not zero */
47 0 : }
48 0 : }
49 0 :
50 0 : return 1;
51 0 : }
52 :
53 : static inline fd_lthash_value_t *
54 : fd_lthash_add( fd_lthash_value_t * restrict r,
55 0 : fd_lthash_value_t const * restrict a ) {
56 0 : for ( ulong i=0; i<FD_LTHASH_LEN_ELEMS; i++ ) {
57 0 : r->words[i] = (ushort)( r->words[i] + a->words[i] );
58 0 : }
59 0 : return r;
60 0 : }
61 :
62 : static inline fd_lthash_value_t *
63 : fd_lthash_sub( fd_lthash_value_t * restrict r,
64 0 : fd_lthash_value_t const * restrict a ) {
65 0 : for ( ulong i=0; i<FD_LTHASH_LEN_ELEMS; i++ ) {
66 0 : r->words[i] = (ushort)( r->words[i] - a->words[i] );
67 0 : }
68 0 : return r;
69 0 : }
70 :
71 : static inline void
72 0 : fd_lthash_hash( fd_lthash_value_t const * r, uchar hash[ static 32] ) {
73 0 : ulong *p = (ulong *) r->bytes;
74 0 : for ( ulong i=0; i<(FD_LTHASH_LEN_BYTES / sizeof(ulong)); i++ ) {
75 0 : if (*p++ != 0) {
76 0 : fd_blake3_t b3[1];
77 0 : fd_blake3_init ( b3 );
78 0 : fd_blake3_append( b3, r->bytes, FD_LTHASH_LEN_BYTES );
79 0 : fd_blake3_fini ( b3, hash );
80 0 : return;
81 0 : }
82 0 : }
83 :
84 0 : fd_memset(hash, 0, 32);
85 0 : }
86 :
87 : #define FD_LTHASH_ENC_32_BUF( _x, _y ) __extension__({ \
88 : if( FD_UNLIKELY( _x == NULL ) ) { \
89 : strcpy(_y, "<NULL>"); \
90 : } else { \
91 : uchar _hash[32]; \
92 : fd_lthash_hash(_x, _hash); \
93 : fd_base58_encode_32( _hash, NULL, _y ); \
94 : } \
95 : })
96 :
97 : #define FD_LTHASH_ENC_32_ALLOCA( x ) __extension__({ \
98 : char *_out = (char *)fd_alloca_check( 1UL, FD_BASE58_ENCODED_32_SZ ); \
99 : FD_LTHASH_ENC_32_BUF(x, _out); \
100 : _out; \
101 : })
102 :
103 : #define FD_LTHASH_ADD( x, y, z ) __extension__({ \
104 : char _b[FD_BASE58_ENCODED_32_SZ]; \
105 : FD_LTHASH_ENC_32_BUF(x, _b); \
106 : fd_lthash_add( 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_add, %s, %s, %s", z, _b, _c, _d)); \
112 : })
113 :
114 : #define FD_LTHASH_SUB( x, y, z ) __extension__({ \
115 : char _b[FD_BASE58_ENCODED_32_SZ]; \
116 : FD_LTHASH_ENC_32_BUF(x, _b); \
117 : fd_lthash_sub( x, y ); \
118 : char _c[FD_BASE58_ENCODED_32_SZ]; \
119 : FD_LTHASH_ENC_32_BUF(y, _c); \
120 : char _d[FD_BASE58_ENCODED_32_SZ]; \
121 : FD_LTHASH_ENC_32_BUF(x, _d); \
122 : FD_LOG_NOTICE(("%s, fd_lthash_sub, %s, %s, %s", z, _b, _c, _d)); \
123 : })
124 :
125 : #define FD_LTHASH_ADD_2( x, y ) __extension__({ \
126 : fd_lthash_add( x, y ); \
127 : })
128 :
129 : #define FD_LTHASH_SUB_2( x, y ) __extension__({ \
130 : fd_lthash_sub( x, y ); \
131 : })
132 :
133 :
134 : FD_PROTOTYPES_END
135 :
136 : #endif /* HEADER_fd_src_ballet_lthash_fd_lthash_h */
|