Line data Source code
1 : #include "fd_keccak256.h" 2 : #include "fd_keccak256_private.h" 3 : 4 : ulong 5 0 : fd_keccak256_align( void ) { 6 0 : return FD_KECCAK256_ALIGN; 7 0 : } 8 : 9 : ulong 10 0 : fd_keccak256_footprint( void ) { 11 0 : return FD_KECCAK256_FOOTPRINT; 12 0 : } 13 : 14 : void * 15 0 : fd_keccak256_new( void * shmem ) { 16 0 : fd_keccak256_t * sha = (fd_keccak256_t *)shmem; 17 : 18 0 : if( FD_UNLIKELY( !shmem ) ) { 19 0 : FD_LOG_WARNING(( "NULL shmem" )); 20 0 : return NULL; 21 0 : } 22 : 23 0 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shmem, fd_keccak256_align() ) ) ) { 24 0 : FD_LOG_WARNING(( "misaligned shmem" )); 25 0 : return NULL; 26 0 : } 27 : 28 0 : ulong footprint = fd_keccak256_footprint(); 29 : 30 0 : fd_memset( sha, 0, footprint ); 31 : 32 0 : FD_COMPILER_MFENCE(); 33 0 : FD_VOLATILE( sha->magic ) = FD_KECCAK256_MAGIC; 34 0 : FD_COMPILER_MFENCE(); 35 : 36 0 : return (void *)sha; 37 0 : } 38 : 39 : fd_keccak256_t * 40 0 : fd_keccak256_join( void * shsha ) { 41 : 42 0 : if( FD_UNLIKELY( !shsha ) ) { 43 0 : FD_LOG_WARNING(( "NULL shsha" )); 44 0 : return NULL; 45 0 : } 46 : 47 0 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shsha, fd_keccak256_align() ) ) ) { 48 0 : FD_LOG_WARNING(( "misaligned shsha" )); 49 0 : return NULL; 50 0 : } 51 : 52 0 : fd_keccak256_t * sha = (fd_keccak256_t *)shsha; 53 : 54 0 : if( FD_UNLIKELY( sha->magic!=FD_KECCAK256_MAGIC ) ) { 55 0 : FD_LOG_WARNING(( "bad magic" )); 56 0 : return NULL; 57 0 : } 58 : 59 0 : return sha; 60 0 : } 61 : 62 : void * 63 0 : fd_keccak256_leave( fd_keccak256_t * sha ) { 64 : 65 0 : if( FD_UNLIKELY( !sha ) ) { 66 0 : FD_LOG_WARNING(( "NULL sha" )); 67 0 : return NULL; 68 0 : } 69 : 70 0 : return (void *)sha; 71 0 : } 72 : 73 : void * 74 0 : fd_keccak256_delete( void * shsha ) { 75 : 76 0 : if( FD_UNLIKELY( !shsha ) ) { 77 0 : FD_LOG_WARNING(( "NULL shsha" )); 78 0 : return NULL; 79 0 : } 80 : 81 0 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shsha, fd_keccak256_align() ) ) ) { 82 0 : FD_LOG_WARNING(( "misaligned shsha" )); 83 0 : return NULL; 84 0 : } 85 : 86 0 : fd_keccak256_t * sha = (fd_keccak256_t *)shsha; 87 : 88 0 : if( FD_UNLIKELY( sha->magic!=FD_KECCAK256_MAGIC ) ) { 89 0 : FD_LOG_WARNING(( "bad magic" )); 90 0 : return NULL; 91 0 : } 92 : 93 0 : FD_COMPILER_MFENCE(); 94 0 : FD_VOLATILE( sha->magic ) = 0UL; 95 0 : FD_COMPILER_MFENCE(); 96 : 97 0 : return (void *)sha; 98 0 : } 99 : 100 : fd_keccak256_t * 101 121 : fd_keccak256_init( fd_keccak256_t * sha ) { 102 121 : fd_memset( sha->state, 0, sizeof( sha->state ) ); 103 : 104 121 : sha->padding_start = 0; 105 : 106 121 : return sha; 107 121 : } 108 : 109 : fd_keccak256_t * 110 : fd_keccak256_append( fd_keccak256_t * sha, 111 : void const * _data, 112 279 : ulong sz ) { 113 : 114 : /* If no data to append, we are done */ 115 : 116 279 : if( FD_UNLIKELY( !sz ) ) return sha; /* optimize for non-trivial append */ 117 : 118 : /* Unpack inputs */ 119 : 120 279 : ulong * state = sha->state; 121 279 : uchar * state_bytes = (uchar*) sha->state; 122 279 : ulong padding_start = sha->padding_start; 123 : 124 279 : uchar const * data = (uchar const *)_data; 125 : 126 279 : ulong state_idx = padding_start; 127 4096 : for( ulong i = 0; i < sz; i++ ) { 128 3817 : state_bytes[state_idx] ^= data[i]; 129 3817 : state_idx++; 130 3817 : if( state_idx >= FD_KECCAK256_RATE ) { 131 0 : fd_keccak256_core(state); 132 0 : state_idx = 0; 133 0 : } 134 3817 : } 135 : 136 279 : sha->padding_start = state_idx; 137 : 138 279 : return sha; 139 279 : } 140 : 141 : void * 142 : fd_keccak256_fini( fd_keccak256_t * sha, 143 115 : void * hash ) { 144 : 145 : /* Unpack inputs */ 146 : 147 115 : ulong * state = sha->state; 148 115 : uchar * state_bytes = (uchar*) sha->state; 149 115 : ulong padding_start = sha->padding_start; 150 : 151 : 152 : /* Append the terminating message byte */ 153 : 154 115 : state_bytes[padding_start] ^= (uchar)0x01; 155 115 : state_bytes[FD_KECCAK256_RATE-1] ^= (uchar)0x80; 156 115 : fd_keccak256_core(state); 157 : 158 : /* Copy the result into hash */ 159 : 160 115 : fd_memcpy(hash, state, FD_KECCAK256_OUT_SZ); 161 115 : return hash; 162 115 : } 163 : 164 : void * 165 : fd_keccak256_hash( void const * _data, 166 : ulong sz, 167 62 : void * _hash ) { 168 62 : fd_keccak256_t sha; 169 62 : fd_keccak256_init( &sha ); 170 62 : fd_keccak256_append( &sha, _data, sz ); 171 62 : fd_keccak256_fini( &sha, _hash ); 172 : 173 : 174 62 : return _hash; 175 62 : } 176 : 177 : #undef fd_keccak256_core