Line data Source code
1 : #ifndef HEADER_fd_src_flamenco_progcache_fd_progcache_xid_h 2 : #define HEADER_fd_src_flamenco_progcache_fd_progcache_xid_h 3 : 4 : #include "../fd_flamenco_base.h" 5 : 6 3687 : #define FD_PROGCACHE_TXN_IDX_NULL ((ulong)UINT_MAX) 7 : 8 : /* fd_progcache_rec_key_hash provides a family of hashes that hash the key 9 : pointed to by k to a uniform quasi-random 64-bit integer. seed 10 : selects the particular hash function to use and can be an arbitrary 11 : 64-bit value. Returns the hash. The hash functions are high quality 12 : but not cryptographically secure. Assumes k is in the caller's 13 : address space and valid. */ 14 : 15 : #if FD_HAS_INT128 16 : 17 : /* If the target has fast uint128, fd_progcache_rec_key_hash is seeded 18 : xxHash3 with 64-bit output size. (open source BSD licensed) */ 19 : 20 : static inline ulong 21 6600 : fd_pc_xxh3_mul128_fold64( ulong lhs, ulong rhs ) { 22 6600 : uint128 product = (uint128)lhs * (uint128)rhs; 23 6600 : return (ulong)product ^ (ulong)( product>>64 ); 24 6600 : } 25 : 26 : static inline ulong 27 : fd_pc_xxh3_mix16b( ulong i0, ulong i1, 28 : ulong s0, ulong s1, 29 6600 : ulong seed ) { 30 6600 : return fd_pc_xxh3_mul128_fold64( i0 ^ (s0 + seed), i1 ^ (s1 - seed) ); 31 6600 : } 32 : 33 : FD_FN_PURE static inline ulong 34 : fd_progcache_rec_key_hash1( uchar const key[ 32 ], 35 3300 : ulong seed ) { 36 3300 : ulong k0 = FD_LOAD( ulong, key+ 0 ); 37 3300 : ulong k1 = FD_LOAD( ulong, key+ 8 ); 38 3300 : ulong k2 = FD_LOAD( ulong, key+16 ); 39 3300 : ulong k3 = FD_LOAD( ulong, key+24 ); 40 3300 : ulong acc = 32 * 0x9E3779B185EBCA87ULL; 41 3300 : acc += fd_pc_xxh3_mix16b( k0, k1, 0xbe4ba423396cfeb8UL, 0x1cad21f72c81017cUL, seed ); 42 3300 : acc += fd_pc_xxh3_mix16b( k2, k3, 0xdb979083e96dd4deUL, 0x1f67b3b7a4a44072UL, seed ); 43 3300 : acc = acc ^ (acc >> 37); 44 3300 : acc *= 0x165667919E3779F9ULL; 45 3300 : acc = acc ^ (acc >> 32); 46 3300 : return acc; 47 3300 : } 48 : 49 : FD_FN_PURE static inline ulong 50 : fd_progcache_rec_key_hash( fd_pubkey_t const * k, 51 3300 : ulong seed ) { 52 3300 : return fd_progcache_rec_key_hash1( k->uc, seed ); 53 3300 : } 54 : 55 : #else 56 : 57 : /* If the target does not support xxHash3, fallback to the 'old' key 58 : hash function. 59 : 60 : FIXME This version is vulnerable to HashDoS */ 61 : 62 : FD_FN_PURE static inline ulong 63 : fd_progcache_rec_key_hash1( uchar const key[ 32 ], 64 : ulong seed ) { 65 : /* tons of ILP */ 66 : return (fd_ulong_hash( seed ^ (1UL<<0) ^ FD_LOAD( ulong, key+ 0 ) ) ^ 67 : fd_ulong_hash( seed ^ (1UL<<1) ^ FD_LOAD( ulong, key+ 8 ) ) ) ^ 68 : (fd_ulong_hash( seed ^ (1UL<<2) ^ FD_LOAD( ulong, key+16 ) ) ^ 69 : fd_ulong_hash( seed ^ (1UL<<3) ^ FD_LOAD( ulong, key+24 ) ) ); 70 : } 71 : 72 : FD_FN_PURE static inline ulong 73 : fd_progcache_rec_key_hash( fd_pubkey_t const * k, 74 : ulong seed ) { 75 : return fd_progcache_rec_key_hash1( k->uc, seed ); 76 : } 77 : 78 : #endif /* FD_HAS_INT128 */ 79 : 80 : #endif /* HEADER_fd_src_flamenco_progcache_fd_progcache_xid_h */