LCOV - code coverage report
Current view: top level - ballet/sha512 - fd_sha512.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 176 240 73.3 %
Date: 2024-11-13 11:58:15 Functions: 10 13 76.9 %

          Line data    Source code
       1             : #include "fd_sha512.h"
       2             : 
       3             : ulong
       4          15 : fd_sha512_align( void ) {
       5          15 :   return FD_SHA512_ALIGN;
       6          15 : }
       7             : 
       8             : ulong
       9          15 : fd_sha512_footprint( void ) {
      10          15 :   return FD_SHA512_FOOTPRINT;
      11          15 : }
      12             : 
      13             : void *
      14        2370 : fd_sha512_new( void * shmem ) {
      15        2370 :   fd_sha512_t * sha = (fd_sha512_t *)shmem;
      16             : 
      17        2370 :   if( FD_UNLIKELY( !shmem ) ) {
      18           3 :     FD_LOG_WARNING(( "NULL shmem" ));
      19           3 :     return NULL;
      20           3 :   }
      21             : 
      22        2367 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shmem, fd_sha512_align() ) ) ) {
      23           3 :     FD_LOG_WARNING(( "misaligned shmem" ));
      24           3 :     return NULL;
      25           3 :   }
      26             : 
      27        2364 :   ulong footprint = fd_sha512_footprint();
      28             : 
      29        2364 :   fd_memset( sha, 0, footprint );
      30             : 
      31        2364 :   FD_COMPILER_MFENCE();
      32        2364 :   FD_VOLATILE( sha->magic ) = FD_SHA512_MAGIC;
      33        2364 :   FD_COMPILER_MFENCE();
      34             : 
      35        2364 :   return (void *)sha;
      36        2367 : }
      37             : 
      38             : fd_sha512_t *
      39        2337 : fd_sha512_join( void * shsha ) {
      40             : 
      41        2337 :   if( FD_UNLIKELY( !shsha ) ) {
      42           3 :     FD_LOG_WARNING(( "NULL shsha" ));
      43           3 :     return NULL;
      44           3 :   }
      45             : 
      46        2334 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shsha, fd_sha512_align() ) ) ) {
      47           3 :     FD_LOG_WARNING(( "misaligned shsha" ));
      48           3 :     return NULL;
      49           3 :   }
      50             : 
      51        2331 :   fd_sha512_t * sha = (fd_sha512_t *)shsha;
      52             : 
      53        2331 :   if( FD_UNLIKELY( sha->magic!=FD_SHA512_MAGIC ) ) {
      54           0 :     FD_LOG_WARNING(( "bad magic" ));
      55           0 :     return NULL;
      56           0 :   }
      57             : 
      58        2331 :   return sha;
      59        2331 : }
      60             : 
      61             : void *
      62          30 : fd_sha512_leave( fd_sha512_t * sha ) {
      63             : 
      64          30 :   if( FD_UNLIKELY( !sha ) ) {
      65           3 :     FD_LOG_WARNING(( "NULL sha" ));
      66           3 :     return NULL;
      67           3 :   }
      68             : 
      69          27 :   return (void *)sha;
      70          30 : }
      71             : 
      72             : void *
      73          33 : fd_sha512_delete( void * shsha ) {
      74             : 
      75          33 :   if( FD_UNLIKELY( !shsha ) ) {
      76           3 :     FD_LOG_WARNING(( "NULL shsha" ));
      77           3 :     return NULL;
      78           3 :   }
      79             : 
      80          30 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shsha, fd_sha512_align() ) ) ) {
      81           3 :     FD_LOG_WARNING(( "misaligned shsha" ));
      82           3 :     return NULL;
      83           3 :   }
      84             : 
      85          27 :   fd_sha512_t * sha = (fd_sha512_t *)shsha;
      86             : 
      87          27 :   if( FD_UNLIKELY( sha->magic!=FD_SHA512_MAGIC ) ) {
      88           0 :     FD_LOG_WARNING(( "bad magic" ));
      89           0 :     return NULL;
      90           0 :   }
      91             : 
      92          27 :   FD_COMPILER_MFENCE();
      93          27 :   FD_VOLATILE( sha->magic ) = 0UL;
      94          27 :   FD_COMPILER_MFENCE();
      95             : 
      96          27 :   return (void *)sha;
      97          27 : }
      98             : 
      99             : #ifndef FD_SHA512_CORE_IMPL
     100             : #if FD_HAS_AVX
     101             : #define FD_SHA512_CORE_IMPL 1
     102             : #else
     103             : #define FD_SHA512_CORE_IMPL 0
     104             : #endif
     105             : #endif
     106             : 
     107             : #if FD_SHA512_CORE_IMPL==0
     108             : 
     109             : /* The implementation below was derived from OpenSSL's sha512
     110             :    implementation (Apache 2 licensed).  See in particular:
     111             : 
     112             :      https://github.com/openssl/openssl/blob/master/crypto/sha/sha512.c
     113             : 
     114             :    (link valid circa 2022-Oct).  It has been made more strict with more
     115             :    extensive implementation documentation, has been simplified and has
     116             :    been streamlined specifically for use inside Firedancer base machine
     117             :    model (no machine specific capabilities required).
     118             : 
     119             :    In particular, fd_sha512_core_ref is based on OpenSSL's
     120             :    OPENSSL_SMALL_FOOTPRINT SHA-512 implementation (Apache licensed).
     121             :    This should work anywhere but it is not the highest performance
     122             :    implementation possible.
     123             : 
     124             :    It is also straightforward to replace these implementations with HPC
     125             :    implementations that target specific machine capabilities without
     126             :    requiring any changes to caller code. */
     127             : 
     128             : static void
     129             : fd_sha512_core_ref( ulong *       state,        /* 64-byte aligned, 8 entries */
     130             :                     uchar const * block,        /* ideally 128-byte aligned (but not required), 128*block_cnt in size */
     131             :                     ulong         block_cnt ) { /* positive */
     132             : 
     133             :   static ulong const K[80] = {
     134             :     0x428a2f98d728ae22UL, 0x7137449123ef65cdUL, 0xb5c0fbcfec4d3b2fUL, 0xe9b5dba58189dbbcUL,
     135             :     0x3956c25bf348b538UL, 0x59f111f1b605d019UL, 0x923f82a4af194f9bUL, 0xab1c5ed5da6d8118UL,
     136             :     0xd807aa98a3030242UL, 0x12835b0145706fbeUL, 0x243185be4ee4b28cUL, 0x550c7dc3d5ffb4e2UL,
     137             :     0x72be5d74f27b896fUL, 0x80deb1fe3b1696b1UL, 0x9bdc06a725c71235UL, 0xc19bf174cf692694UL,
     138             :     0xe49b69c19ef14ad2UL, 0xefbe4786384f25e3UL, 0x0fc19dc68b8cd5b5UL, 0x240ca1cc77ac9c65UL,
     139             :     0x2de92c6f592b0275UL, 0x4a7484aa6ea6e483UL, 0x5cb0a9dcbd41fbd4UL, 0x76f988da831153b5UL,
     140             :     0x983e5152ee66dfabUL, 0xa831c66d2db43210UL, 0xb00327c898fb213fUL, 0xbf597fc7beef0ee4UL,
     141             :     0xc6e00bf33da88fc2UL, 0xd5a79147930aa725UL, 0x06ca6351e003826fUL, 0x142929670a0e6e70UL,
     142             :     0x27b70a8546d22ffcUL, 0x2e1b21385c26c926UL, 0x4d2c6dfc5ac42aedUL, 0x53380d139d95b3dfUL,
     143             :     0x650a73548baf63deUL, 0x766a0abb3c77b2a8UL, 0x81c2c92e47edaee6UL, 0x92722c851482353bUL,
     144             :     0xa2bfe8a14cf10364UL, 0xa81a664bbc423001UL, 0xc24b8b70d0f89791UL, 0xc76c51a30654be30UL,
     145             :     0xd192e819d6ef5218UL, 0xd69906245565a910UL, 0xf40e35855771202aUL, 0x106aa07032bbd1b8UL,
     146             :     0x19a4c116b8d2d0c8UL, 0x1e376c085141ab53UL, 0x2748774cdf8eeb99UL, 0x34b0bcb5e19b48a8UL,
     147             :     0x391c0cb3c5c95a63UL, 0x4ed8aa4ae3418acbUL, 0x5b9cca4f7763e373UL, 0x682e6ff3d6b2b8a3UL,
     148             :     0x748f82ee5defb2fcUL, 0x78a5636f43172f60UL, 0x84c87814a1f0ab72UL, 0x8cc702081a6439ecUL,
     149             :     0x90befffa23631e28UL, 0xa4506cebde82bde9UL, 0xbef9a3f7b2c67915UL, 0xc67178f2e372532bUL,
     150             :     0xca273eceea26619cUL, 0xd186b8c721c0c207UL, 0xeada7dd6cde0eb1eUL, 0xf57d4f7fee6ed178UL,
     151             :     0x06f067aa72176fbaUL, 0x0a637dc5a2c898a6UL, 0x113f9804bef90daeUL, 0x1b710b35131c471bUL,
     152             :     0x28db77f523047d84UL, 0x32caab7b40c72493UL, 0x3c9ebe0a15c9bebcUL, 0x431d67c49c100d4cUL,
     153             :     0x4cc5d4becb3e42b6UL, 0x597f299cfc657e2aUL, 0x5fcb6fab3ad6faecUL, 0x6c44198c4a475817UL
     154             :   };
     155             : 
     156             : # define ROTR       fd_ulong_rotate_right
     157             : # define Sigma0(x)  (ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39))
     158             : # define Sigma1(x)  (ROTR((x),14) ^ ROTR((x),18) ^ ROTR((x),41))
     159             : # define sigma0(x)  (ROTR((x), 1) ^ ROTR((x), 8) ^ ((x)>>7))
     160             : # define sigma1(x)  (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6))
     161             : # define Ch(x,y,z)  (((x) & (y)) ^ ((~(x)) & (z)))
     162             : # define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
     163             : 
     164             :   ulong const * W = (ulong const *)block;
     165             :   do {
     166             :     ulong a = state[0];
     167             :     ulong b = state[1];
     168             :     ulong c = state[2];
     169             :     ulong d = state[3];
     170             :     ulong e = state[4];
     171             :     ulong f = state[5];
     172             :     ulong g = state[6];
     173             :     ulong h = state[7];
     174             : 
     175             :     ulong X[16];
     176             : 
     177             :     ulong i;
     178             :     for( i=0UL; i<16UL; i++ ) {
     179             :       X[i] = fd_ulong_bswap( W[i] );
     180             :       ulong T1 = X[i] + h + Sigma1(e) + Ch(e, f, g) + K[i];
     181             :       ulong T2 = Sigma0(a) + Maj(a, b, c);
     182             :       h = g;
     183             :       g = f;
     184             :       f = e;
     185             :       e = d + T1;
     186             :       d = c;
     187             :       c = b;
     188             :       b = a;
     189             :       a = T1 + T2;
     190             :     }
     191             :     for( ; i<80UL; i++ ) {
     192             :       ulong s0 = X[(i +  1UL) & 0x0fUL];
     193             :       ulong s1 = X[(i + 14UL) & 0x0fUL];
     194             :       s0 = sigma0(s0);
     195             :       s1 = sigma1(s1);
     196             :       X[i & 0xfUL] += s0 + s1 + X[(i + 9UL) & 0xfUL];
     197             :       ulong T1 = X[i & 0xfUL ] + h + Sigma1(e) + Ch(e, f, g) + K[i];
     198             :       ulong T2 = Sigma0(a) + Maj(a, b, c);
     199             :       h = g;
     200             :       g = f;
     201             :       f = e;
     202             :       e = d + T1;
     203             :       d = c;
     204             :       c = b;
     205             :       b = a;
     206             :       a = T1 + T2;
     207             :     }
     208             : 
     209             :     state[0] += a;
     210             :     state[1] += b;
     211             :     state[2] += c;
     212             :     state[3] += d;
     213             :     state[4] += e;
     214             :     state[5] += f;
     215             :     state[6] += g;
     216             :     state[7] += h;
     217             : 
     218             :     W += 16UL;
     219             :   } while( --block_cnt );
     220             : 
     221             : # undef ROTR
     222             : # undef Sigma0
     223             : # undef Sigma1
     224             : # undef sigma0
     225             : # undef sigma1
     226             : # undef Ch
     227             : # undef Maj
     228             : 
     229             : }
     230             : 
     231             : #define fd_sha512_core fd_sha512_core_ref
     232             : 
     233             : #elif FD_SHA512_CORE_IMPL==1
     234             : 
     235             : __attribute__((sysv_abi))
     236             : void
     237             : fd_sha512_core_avx2( ulong *       state,       /* 64-byte aligned, 8 entries */
     238             :                      uchar const * block,       /* ideally 128-byte aligned (but not required), 128*block_cnt in size */
     239             :                      ulong         block_cnt ); /* positive */
     240             : 
     241    18618416 : #define fd_sha512_core fd_sha512_core_avx2
     242             : 
     243             : #else
     244             : #error "Unsupported FD_SHA512_CORE_IMPL"
     245             : #endif
     246             : 
     247             : fd_sha512_t *
     248           0 : fd_sha384_init( fd_sha512_t * sha ) {
     249             :   /* sha->buf d/c */
     250           0 :   sha->state[0]   = 0xcbbb9d5dc1059ed8UL;
     251           0 :   sha->state[1]   = 0x629a292a367cd507UL;
     252           0 :   sha->state[2]   = 0x9159015a3070dd17UL;
     253           0 :   sha->state[3]   = 0x152fecd8f70e5939UL;
     254           0 :   sha->state[4]   = 0x67332667ffc00b31UL;
     255           0 :   sha->state[5]   = 0x8eb44a8768581511UL;
     256           0 :   sha->state[6]   = 0xdb0c2e0d64f98fa7UL;
     257           0 :   sha->state[7]   = 0x47b5481dbefa4fa4UL;
     258           0 :   sha->buf_used   = 0U;
     259           0 :   sha->bit_cnt_lo = 0UL;
     260           0 :   sha->bit_cnt_hi = 0UL;
     261           0 :   return sha;
     262           0 : }
     263             : 
     264             : fd_sha512_t *
     265     8346819 : fd_sha512_init( fd_sha512_t * sha ) {
     266             :   /* sha->buf d/c */
     267     8346819 :   sha->state[0]   = 0x6a09e667f3bcc908UL;
     268     8346819 :   sha->state[1]   = 0xbb67ae8584caa73bUL;
     269     8346819 :   sha->state[2]   = 0x3c6ef372fe94f82bUL;
     270     8346819 :   sha->state[3]   = 0xa54ff53a5f1d36f1UL;
     271     8346819 :   sha->state[4]   = 0x510e527fade682d1UL;
     272     8346819 :   sha->state[5]   = 0x9b05688c2b3e6c1fUL;
     273     8346819 :   sha->state[6]   = 0x1f83d9abfb41bd6bUL;
     274     8346819 :   sha->state[7]   = 0x5be0cd19137e2179UL;
     275     8346819 :   sha->buf_used   = 0U;
     276     8346819 :   sha->bit_cnt_lo = 0UL;
     277     8346819 :   sha->bit_cnt_hi = 0UL;
     278     8346819 :   return sha;
     279     8346819 : }
     280             : 
     281             : fd_sha512_t *
     282             : fd_sha512_append( fd_sha512_t * sha,
     283             :                   void const *  _data,
     284    16458567 :                   ulong         sz ) {
     285             : 
     286             :   /* If no data to append, we are done */
     287             : 
     288    16458567 :   if( FD_UNLIKELY( !sz ) ) return sha; /* optimize for non-trivial append */
     289             : 
     290             :   /* Unpack inputs */
     291             : 
     292    16458258 :   ulong * state      = sha->state;
     293    16458258 :   uchar * buf        = sha->buf;
     294    16458258 :   ulong   buf_used   = sha->buf_used;
     295    16458258 :   ulong   bit_cnt_lo = sha->bit_cnt_lo;
     296    16458258 :   ulong   bit_cnt_hi = sha->bit_cnt_hi;
     297             : 
     298    16458258 :   uchar const * data = (uchar const *)_data;
     299             : 
     300             :   /* Update bit_cnt */
     301             :   /* FIXME: could accumulate bytes here and do bit conversion in append */
     302             : 
     303    16458258 :   ulong new_bit_cnt_lo = bit_cnt_lo + (sz<< 3);
     304    16458258 :   ulong new_bit_cnt_hi = bit_cnt_hi + (sz>>61) + (ulong)(new_bit_cnt_lo<bit_cnt_lo);
     305             : 
     306    16458258 :   sha->bit_cnt_lo = new_bit_cnt_lo;
     307    16458258 :   sha->bit_cnt_hi = new_bit_cnt_hi;
     308             : 
     309             :   /* Handle buffered bytes from previous appends */
     310             : 
     311    16458258 :   if( FD_UNLIKELY( buf_used ) ) { /* optimized for well aligned use of append */
     312             : 
     313             :     /* If the append isn't large enough to complete the current block,
     314             :        buffer these bytes too and return */
     315             : 
     316     6725697 :     ulong buf_rem = FD_SHA512_PRIVATE_BUF_MAX - buf_used; /* In (0,FD_SHA512_PRIVATE_BUF_MAX) */
     317     6725697 :     if( FD_UNLIKELY( sz < buf_rem ) ) { /* optimize for large append */
     318     5466318 :       fd_memcpy( buf + buf_used, data, sz );
     319     5466318 :       sha->buf_used = buf_used + sz;
     320     5466318 :       return sha;
     321     5466318 :     }
     322             : 
     323             :     /* Otherwise, buffer enough leading bytes of data to complete the
     324             :        block, update the hash and then continue processing any remaining
     325             :        bytes of data. */
     326             : 
     327     1259379 :     fd_memcpy( buf + buf_used, data, buf_rem );
     328     1259379 :     data += buf_rem;
     329     1259379 :     sz   -= buf_rem;
     330             : 
     331     1259379 :     fd_sha512_core( state, buf, 1UL );
     332     1259379 :     sha->buf_used = 0UL;
     333     1259379 :   }
     334             : 
     335             :   /* Append the bulk of the data */
     336             : 
     337    10991940 :   ulong block_cnt = sz >> FD_SHA512_PRIVATE_LG_BUF_MAX;
     338    10991940 :   if( FD_LIKELY( block_cnt ) ) fd_sha512_core( state, data, block_cnt ); /* optimized for large append */
     339             : 
     340             :   /* Buffer any leftover bytes */
     341             : 
     342    10991940 :   buf_used = sz & (FD_SHA512_PRIVATE_BUF_MAX-1UL); /* In [0,FD_SHA512_PRIVATE_BUF_MAX) */
     343    10991940 :   if( FD_UNLIKELY( buf_used ) ) { /* optimized for well aligned use of append */
     344     7846182 :     fd_memcpy( buf, data + (block_cnt << FD_SHA512_PRIVATE_LG_BUF_MAX), buf_used );
     345     7846182 :     sha->buf_used = buf_used; /* In (0,FD_SHA512_PRIVATE_BUF_MAX) */
     346     7846182 :   }
     347             : 
     348    10991940 :   return sha;
     349    16458258 : }
     350             : 
     351             : void *
     352             : fd_sha512_fini( fd_sha512_t * sha,
     353     6586839 :                 void *        _hash ) {
     354             : 
     355             :   /* Unpack inputs */
     356             : 
     357     6586839 :   ulong * state      = sha->state;
     358     6586839 :   uchar * buf        = sha->buf;
     359     6586839 :   ulong   buf_used   = sha->buf_used; /* In [0,FD_SHA512_PRIVATE_BUF_MAX) */
     360     6586839 :   ulong   bit_cnt_lo = sha->bit_cnt_lo;
     361     6586839 :   ulong   bit_cnt_hi = sha->bit_cnt_hi;
     362             : 
     363             :   /* Append the terminating message byte */
     364             : 
     365     6586839 :   buf[ buf_used ] = (uchar)0x80;
     366     6586839 :   buf_used++;
     367             : 
     368             :   /* If there isn't enough room to save the message length in bits at
     369             :      the end of the in progress block, clear the rest of the in progress
     370             :      block, update the hash and start a new block. */
     371             : 
     372     6586839 :   if( FD_UNLIKELY( buf_used > FD_SHA512_PRIVATE_BUF_MAX-16UL ) ) { /* optimize for well aligned use of append */
     373          18 :     fd_memset( buf + buf_used, 0, FD_SHA512_PRIVATE_BUF_MAX-buf_used );
     374          18 :     fd_sha512_core( state, buf, 1UL );
     375          18 :     buf_used = 0UL;
     376          18 :   }
     377             : 
     378             :   /* Clear in progress block up to last 128-bits, append the message
     379             :      size in bytes in the last 128-bits of the in progress block and
     380             :      update the hash to finalize it. */
     381             : 
     382     6586839 :   fd_memset( buf + buf_used, 0, FD_SHA512_PRIVATE_BUF_MAX-16UL-buf_used );
     383     6586839 :   *((ulong *)(buf+FD_SHA512_PRIVATE_BUF_MAX-16UL)) = fd_ulong_bswap( bit_cnt_hi );
     384     6586839 :   *((ulong *)(buf+FD_SHA512_PRIVATE_BUF_MAX- 8UL)) = fd_ulong_bswap( bit_cnt_lo );
     385     6586839 :   fd_sha512_core( state, buf, 1UL );
     386             : 
     387             :   /* Unpack the result into md (annoying bswaps here) */
     388             : 
     389     6586839 :   ulong * hash = (ulong *)_hash;
     390     6586839 :   hash[0] = fd_ulong_bswap( state[0] );
     391     6586839 :   hash[1] = fd_ulong_bswap( state[1] );
     392     6586839 :   hash[2] = fd_ulong_bswap( state[2] );
     393     6586839 :   hash[3] = fd_ulong_bswap( state[3] );
     394     6586839 :   hash[4] = fd_ulong_bswap( state[4] );
     395     6586839 :   hash[5] = fd_ulong_bswap( state[5] );
     396     6586839 :   hash[6] = fd_ulong_bswap( state[6] );
     397     6586839 :   hash[7] = fd_ulong_bswap( state[7] );
     398     6586839 :   return _hash;
     399     6586839 : }
     400             : 
     401             : void *
     402             : fd_sha384_fini( fd_sha512_t * sha,
     403           0 :                 void *        _hash ) {
     404           0 :   uchar hash[ FD_SHA512_HASH_SZ ] __attribute__((aligned(64)));
     405           0 :   fd_sha512_fini( sha, hash );
     406           0 :   memcpy( _hash, hash, FD_SHA384_HASH_SZ );
     407           0 :   return _hash;
     408           0 : }
     409             : 
     410             : void *
     411             : fd_sha512_hash( void const * _data,
     412             :                 ulong        sz,
     413     3830664 :                 void *       _hash ) {
     414     3830664 :   uchar const * data = (uchar const *)_data;
     415             : 
     416             :   /* This is just the above streamlined to eliminate all the overheads
     417             :      to support incremental hashing. */
     418             : 
     419     3830664 :   uchar buf[ FD_SHA512_PRIVATE_BUF_MAX ] __attribute__((aligned(128)));
     420     3830664 :   ulong state[8] __attribute__((aligned(64)));
     421             : 
     422     3830664 :   state[0] = 0x6a09e667f3bcc908UL;
     423     3830664 :   state[1] = 0xbb67ae8584caa73bUL;
     424     3830664 :   state[2] = 0x3c6ef372fe94f82bUL;
     425     3830664 :   state[3] = 0xa54ff53a5f1d36f1UL;
     426     3830664 :   state[4] = 0x510e527fade682d1UL;
     427     3830664 :   state[5] = 0x9b05688c2b3e6c1fUL;
     428     3830664 :   state[6] = 0x1f83d9abfb41bd6bUL;
     429     3830664 :   state[7] = 0x5be0cd19137e2179UL;
     430             : 
     431     3830664 :   ulong block_cnt = sz >> FD_SHA512_PRIVATE_LG_BUF_MAX;
     432     3830664 :   if( FD_LIKELY( block_cnt ) ) fd_sha512_core( state, data, block_cnt );
     433             : 
     434     3830664 :   ulong buf_used = sz & (FD_SHA512_PRIVATE_BUF_MAX-1UL);
     435     3830664 :   if( FD_UNLIKELY( buf_used ) ) fd_memcpy( buf, data + (block_cnt << FD_SHA512_PRIVATE_LG_BUF_MAX), buf_used );
     436     3830664 :   buf[ buf_used ] = (uchar)0x80;
     437     3830664 :   buf_used++;
     438             : 
     439     3830664 :   if( FD_UNLIKELY( buf_used > (FD_SHA512_PRIVATE_BUF_MAX-16UL) ) ) {
     440      287778 :     fd_memset( buf + buf_used, 0, FD_SHA512_PRIVATE_BUF_MAX-buf_used );
     441      287778 :     fd_sha512_core( state, buf, 1UL );
     442      287778 :     buf_used = 0UL;
     443      287778 :   }
     444             : 
     445     3830664 :   ulong bit_cnt_lo = sz<< 3;
     446     3830664 :   ulong bit_cnt_hi = sz>>61;
     447     3830664 :   fd_memset( buf + buf_used, 0, FD_SHA512_PRIVATE_BUF_MAX-16UL-buf_used );
     448     3830664 :   *((ulong *)(buf+FD_SHA512_PRIVATE_BUF_MAX-16UL)) = fd_ulong_bswap( bit_cnt_hi );
     449     3830664 :   *((ulong *)(buf+FD_SHA512_PRIVATE_BUF_MAX- 8UL)) = fd_ulong_bswap( bit_cnt_lo );
     450     3830664 :   fd_sha512_core( state, buf, 1UL );
     451             : 
     452     3830664 :   ulong * hash = (ulong *)_hash;
     453     3830664 :   hash[0] = fd_ulong_bswap( state[0] );
     454     3830664 :   hash[1] = fd_ulong_bswap( state[1] );
     455     3830664 :   hash[2] = fd_ulong_bswap( state[2] );
     456     3830664 :   hash[3] = fd_ulong_bswap( state[3] );
     457     3830664 :   hash[4] = fd_ulong_bswap( state[4] );
     458     3830664 :   hash[5] = fd_ulong_bswap( state[5] );
     459     3830664 :   hash[6] = fd_ulong_bswap( state[6] );
     460     3830664 :   hash[7] = fd_ulong_bswap( state[7] );
     461     3830664 :   return _hash;
     462     3830664 : }
     463             : 
     464             : void *
     465             : fd_sha384_hash( void const * _data,
     466             :                 ulong        sz,
     467           0 :                 void *       _hash ) {
     468           0 :   uchar const * data = (uchar const *)_data;
     469             : 
     470             :   /* This is just the above streamlined to eliminate all the overheads
     471             :      to support incremental hashing. */
     472             : 
     473           0 :   uchar buf[ FD_SHA512_PRIVATE_BUF_MAX ] __attribute__((aligned(128)));
     474           0 :   ulong state[8] __attribute__((aligned(64)));
     475             : 
     476           0 :   state[0] = 0xcbbb9d5dc1059ed8UL;
     477           0 :   state[1] = 0x629a292a367cd507UL;
     478           0 :   state[2] = 0x9159015a3070dd17UL;
     479           0 :   state[3] = 0x152fecd8f70e5939UL;
     480           0 :   state[4] = 0x67332667ffc00b31UL;
     481           0 :   state[5] = 0x8eb44a8768581511UL;
     482           0 :   state[6] = 0xdb0c2e0d64f98fa7UL;
     483           0 :   state[7] = 0x47b5481dbefa4fa4UL;
     484             : 
     485           0 :   ulong block_cnt = sz >> FD_SHA512_PRIVATE_LG_BUF_MAX;
     486           0 :   if( FD_LIKELY( block_cnt ) ) fd_sha512_core( state, data, block_cnt );
     487             : 
     488           0 :   ulong buf_used = sz & (FD_SHA512_PRIVATE_BUF_MAX-1UL);
     489           0 :   if( FD_UNLIKELY( buf_used ) ) fd_memcpy( buf, data + (block_cnt << FD_SHA512_PRIVATE_LG_BUF_MAX), buf_used );
     490           0 :   buf[ buf_used ] = (uchar)0x80;
     491           0 :   buf_used++;
     492             : 
     493           0 :   if( FD_UNLIKELY( buf_used > (FD_SHA512_PRIVATE_BUF_MAX-16UL) ) ) {
     494           0 :     fd_memset( buf + buf_used, 0, FD_SHA512_PRIVATE_BUF_MAX-buf_used );
     495           0 :     fd_sha512_core( state, buf, 1UL );
     496           0 :     buf_used = 0UL;
     497           0 :   }
     498             : 
     499           0 :   ulong bit_cnt_lo = sz<< 3;
     500           0 :   ulong bit_cnt_hi = sz>>61;
     501           0 :   fd_memset( buf + buf_used, 0, FD_SHA512_PRIVATE_BUF_MAX-16UL-buf_used );
     502           0 :   *((ulong *)(buf+FD_SHA512_PRIVATE_BUF_MAX-16UL)) = fd_ulong_bswap( bit_cnt_hi );
     503           0 :   *((ulong *)(buf+FD_SHA512_PRIVATE_BUF_MAX- 8UL)) = fd_ulong_bswap( bit_cnt_lo );
     504           0 :   fd_sha512_core( state, buf, 1UL );
     505             : 
     506           0 :   ulong * hash = (ulong *)_hash;
     507           0 :   hash[0] = fd_ulong_bswap( state[0] );
     508           0 :   hash[1] = fd_ulong_bswap( state[1] );
     509           0 :   hash[2] = fd_ulong_bswap( state[2] );
     510           0 :   hash[3] = fd_ulong_bswap( state[3] );
     511           0 :   hash[4] = fd_ulong_bswap( state[4] );
     512           0 :   hash[5] = fd_ulong_bswap( state[5] );
     513           0 :   return _hash;
     514           0 : }
     515             : 
     516             : #undef fd_sha512_core
     517             : 

Generated by: LCOV version 1.14