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