LCOV - code coverage report
Current view: top level - disco/keyguard - fd_keyguard_client.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 84 0.0 %
Date: 2026-10-22 18:10:43 Functions: 0 7 0.0 %

          Line data    Source code
       1             : #include "fd_keyguard_client.h"
       2             : #include "fd_keyguard.h"
       3             : #include "../../ballet/bls/fd_bls.h"
       4             : 
       5             : #include "../../tango/mcache/fd_mcache.h"
       6             : #include "../../tango/dcache/fd_dcache.h"
       7             : 
       8             : static inline void
       9             : fd_keyguard_client_publish( fd_keyguard_client_t * client,
      10             :                             ulong                  sig,
      11           0 :                             ulong                  sign_data_len ) {
      12           0 : #if FD_HAS_AVX
      13           0 :   fd_mcache_publish_avx( client->request, client->request_depth, client->request_seq, sig, client->request_chunk, sign_data_len, 0UL, 0UL, 0UL );
      14             : #elif FD_HAS_ARM
      15             :   fd_mcache_publish_arm( client->request, client->request_depth, client->request_seq, sig, client->request_chunk, sign_data_len, 0UL, 0UL, 0UL );
      16             : #else
      17             :   fd_mcache_publish( client->request, client->request_depth, client->request_seq, sig, client->request_chunk, sign_data_len, 0UL, 0UL, 0UL );
      18             : #endif
      19           0 : }
      20             : 
      21             : void *
      22             : fd_keyguard_client_new( void *           shmem,
      23             :                         fd_frag_meta_t * request_mcache,
      24             :                         uchar *          request_dcache,
      25             :                         fd_frag_meta_t * response_mcache,
      26             :                         uchar *          response_dcache,
      27             :                         ulong            request_mtu,
      28             :                         ulong            response_mtu,
      29             :                         fd_sleep_t *     sleep,
      30             :                         ulong            request_link_id,
      31           0 :                         ulong            sign_tile_id ) {
      32           0 :   fd_keyguard_client_t * client = (fd_keyguard_client_t*)shmem;
      33             : 
      34           0 :   client->sleep           = sign_tile_id!=ULONG_MAX ? sleep : NULL;
      35           0 :   client->request_link_id = request_link_id;
      36           0 :   client->wake.w          = sign_tile_id>>6;
      37           0 :   client->wake.mask       = 1UL<<(sign_tile_id&63UL);
      38             : 
      39           0 :   client->request        = request_mcache;
      40           0 :   client->request_depth  = fd_mcache_depth( request_mcache );
      41           0 :   client->request_seq    = 0UL;
      42           0 :   client->request_mem    = fd_wksp_containing( request_dcache );
      43           0 :   client->request_chunk0 = fd_dcache_compact_chunk0( client->request_mem, request_dcache );
      44           0 :   client->request_wmark  = fd_dcache_compact_wmark( client->request_mem, request_dcache, request_mtu );
      45           0 :   client->request_chunk  = client->request_chunk0;
      46           0 :   client->request_mtu    = request_mtu;
      47             : 
      48           0 :   client->response        = response_mcache;
      49           0 :   client->response_depth  = fd_mcache_depth( response_mcache );
      50           0 :   client->response_seq    = 0UL;
      51           0 :   client->response_mem    = fd_wksp_containing( response_dcache );
      52           0 :   client->response_chunk0 = fd_dcache_compact_chunk0( client->response_mem, response_dcache );
      53           0 :   client->response_wmark  = fd_dcache_compact_wmark( client->response_mem, response_dcache, response_mtu );
      54           0 :   client->response_mtu    = response_mtu;
      55             : 
      56           0 :   return shmem;
      57           0 : }
      58             : 
      59             : /* fd_keyguard_client_sign_sz is the common request/response path.
      60             :    signature_sz is the response size for the request sig, including
      61             :    public-key queries. */
      62             : 
      63             : static void
      64             : fd_keyguard_client_sign_sz( fd_keyguard_client_t * client,
      65             :                             uchar *                signature,
      66             :                             ulong                  signature_sz,
      67             :                             uchar const *          sign_data,
      68             :                             ulong                  sign_data_len,
      69           0 :                             ulong                  sig ) {
      70           0 :   FD_TEST( sign_data_len<=client->request_mtu );
      71             : 
      72           0 :   uchar * dst = fd_chunk_to_laddr( client->request_mem, client->request_chunk );
      73           0 :   fd_memcpy( dst, sign_data, sign_data_len );
      74             : 
      75           0 :   fd_keyguard_client_publish( client, sig, sign_data_len );
      76           0 :   client->request_seq   = fd_seq_inc( client->request_seq, 1UL );
      77           0 :   client->request_chunk = fd_dcache_compact_next( client->request_chunk, sign_data_len, client->request_chunk0, client->request_wmark );
      78             : 
      79           0 :   if( FD_UNLIKELY( client->sleep ) ) {
      80           0 :     __atomic_store_n( &client->sleep->seq_mirror[ client->request_link_id ], client->request_seq, __ATOMIC_RELEASE );
      81           0 :     fd_sleep_wake_check( client->sleep, &client->wake, 1UL );
      82           0 :   }
      83             : 
      84           0 :   fd_frag_meta_t meta;
      85           0 :   fd_frag_meta_t const * mline;
      86           0 :   ulong seq_found;
      87           0 :   long seq_diff;
      88           0 :   ulong poll_max = ULONG_MAX;
      89           0 :   FD_MCACHE_WAIT( &meta, mline, seq_found, seq_diff, poll_max, client->response, client->response_depth, client->response_seq );
      90           0 :   if( FD_UNLIKELY( !poll_max ) ) FD_LOG_ERR(( "sign request timed out while polling" ));
      91           0 :   if( FD_UNLIKELY( seq_diff ) ) FD_LOG_ERR(( "sign request was overrun while polling" ));
      92           0 :   FD_HW_MFENCE_LD();
      93             : 
      94             :   /* Chunk is in shared memory and might be be written to by an
      95             :      attacking tile after we validate it, so load once. */
      96           0 :   ulong chunk = FD_VOLATILE_CONST( mline->chunk );
      97           0 :   FD_TEST( chunk>=client->response_chunk0 && chunk<=client->response_wmark );
      98             : 
      99           0 :   FD_TEST( signature_sz<=client->response_mtu );
     100           0 :   uchar * src = fd_chunk_to_laddr( client->response_mem, chunk );
     101           0 :   fd_memcpy( signature, src, signature_sz );
     102             : 
     103           0 :   FD_HW_MFENCE_LD();
     104           0 :   seq_found = fd_frag_meta_seq_query( mline );
     105           0 :   if( FD_UNLIKELY( fd_seq_ne( seq_found, client->response_seq ) ) ) FD_LOG_ERR(( "sign request was overrun while reading" ));
     106           0 :   client->response_seq = fd_seq_inc( client->response_seq, 1UL );
     107           0 : }
     108             : 
     109             : void
     110             : fd_keyguard_client_sign( fd_keyguard_client_t * client,
     111             :                          uchar *                signature,
     112             :                          uchar const *          sign_data,
     113             :                          ulong                  sign_data_len,
     114           0 :                          int                    sign_type ) {
     115           0 :   ulong signature_sz;
     116           0 :   switch( sign_type ) {
     117           0 :     case FD_KEYGUARD_SIGN_TYPE_BLS:        signature_sz = FD_BLS_SIG_SZ;            break;
     118           0 :     case FD_KEYGUARD_SIGN_TYPE_BLS_PUBKEY: signature_sz = FD_BLS_PUB_COMPRESSED_SZ; break;
     119           0 :     default:                               signature_sz = FD_ED25519_SIG_SZ;        break;
     120           0 :   }
     121           0 :   fd_keyguard_client_sign_sz( client, signature, signature_sz, sign_data, sign_data_len, (ulong)(uint)sign_type );
     122           0 : }
     123             : 
     124             : void
     125             : fd_keyguard_client_ag_vote_sign( fd_keyguard_client_t * client,
     126             :                                  uchar *                signature,
     127             :                                  ulong                  authority_idx,
     128             :                                  uchar const *          sign_data,
     129           0 :                                  ulong                  sign_data_len ) {
     130           0 :   FD_CHECK_CRIT( authority_idx==ULONG_MAX || authority_idx<FD_KEYGUARD_AUTH_VOTERS_MAX, "unexpected authorized voter index" );
     131             : 
     132             :   /* Same encoding as fd_keyguard_client_vote_txn_sign. */
     133             : 
     134           0 :   ulong sig = (ulong)FD_KEYGUARD_SIGN_TYPE_BLS;
     135           0 :   if( authority_idx!=ULONG_MAX ) sig |= (1UL << 32) | (authority_idx << 33);
     136           0 :   fd_keyguard_client_sign_sz( client, signature, FD_BLS_SIG_SZ, sign_data, sign_data_len, sig );
     137           0 : }
     138             : 
     139             : void
     140             : fd_keyguard_client_bls_pubkey( fd_keyguard_client_t * client,
     141             :                                uchar *                public_key,
     142           0 :                                ulong                  authority_idx ) {
     143           0 :   FD_CHECK_CRIT( authority_idx==ULONG_MAX || authority_idx<FD_KEYGUARD_AUTH_VOTERS_MAX, "unexpected authorized voter index" );
     144           0 :   fd_keyguard_client_sign( client, public_key, (uchar const *)&authority_idx, sizeof(authority_idx), FD_KEYGUARD_SIGN_TYPE_BLS_PUBKEY );
     145           0 : }
     146             : 
     147             : void
     148             : fd_keyguard_client_vote_txn_sign( fd_keyguard_client_t * client,
     149             :                                   uchar *                signatures,
     150             :                                   ulong                  authority_idx,
     151             :                                   uchar const *          sign_data,
     152           0 :                                   ulong                  sign_data_len ) {
     153           0 :   FD_CHECK_CRIT( sign_data_len<=client->request_mtu, "the request is too large and will not fit in the mtu" );
     154           0 :   FD_CHECK_CRIT( authority_idx==ULONG_MAX || authority_idx<FD_KEYGUARD_AUTH_VOTERS_MAX, "unexpected authorized voter index" );
     155             : 
     156             :   /* In the signature of the message we use the lower 32 bits to
     157             :      indicate the sign type.  We can use the upper 32 bits to encode if
     158             :      a second signature is needed and what index the authorized voter
     159             :      that a signature is needed from.
     160             :      The least significant bit of the upper 32 is 1 if a second
     161             :      signature is needed.  The next 4 least significant bits of the
     162             :      upper 32 are used to encode the index of the authorized voter
     163             :      where the index is [0,16). */
     164             : 
     165           0 :   ulong sig = 0UL;
     166           0 :   if( authority_idx!=ULONG_MAX ) sig |= (1UL << 32) | (authority_idx << 33);
     167           0 :   ulong signatures_sz = fd_ulong_if( authority_idx!=ULONG_MAX, 2UL*FD_ED25519_SIG_SZ, FD_ED25519_SIG_SZ );
     168           0 :   fd_keyguard_client_sign_sz( client, signatures, signatures_sz, sign_data, sign_data_len, sig );
     169           0 : }

Generated by: LCOV version 1.14