LCOV - code coverage report
Current view: top level - choreo/votor - ag_bls_serde.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 117 117 100.0 %
Date: 2026-09-17 04:28:31 Functions: 10 10 100.0 %

          Line data    Source code
       1             : #include "ag_bls_serde.h"
       2             : 
       3         354 : #define FAIL( cond, err ) do { if( FD_UNLIKELY( cond ) ) return AG_BLS_DE_ERR_##err; } while( 0 )
       4             : 
       5          81 : #define BASE2_BITMAP (0)
       6          75 : #define BASE3_BITMAP (1)
       7             : 
       8             : static ulong
       9         432 : agg_bit_cnt( fd_bls_agg_t const * agg ) {
      10         432 :   return fd_ulong_min( FD_BLS_SET_MAX, fd_bls_set_last( agg->set )+1UL );
      11         432 : }
      12             : 
      13             : ulong
      14         123 : ag_bls_agg_ser_sz( fd_bls_agg_t const * agg ) {
      15         123 :   return AG_BLS_AGG_SER_SZ( agg_bit_cnt( agg ) );
      16         123 : }
      17             : 
      18             : ulong
      19             : ag_bls_agg_pair_ser_sz( fd_bls_agg_t const * agg,
      20          81 :                         fd_bls_agg_t const * agg_fb ) {
      21          81 :   return AG_BLS_AGG_PAIR_SER_SZ( fd_ulong_max( agg_bit_cnt( agg ), agg_bit_cnt( agg_fb ) ) );
      22          81 : }
      23             : 
      24             : ulong
      25             : ag_bls_agg_ser( fd_bls_agg_t const * agg,
      26          63 :                 uchar *              buf ) {
      27             : 
      28          63 :   ulong bit_cnt = agg_bit_cnt( agg );
      29             : 
      30          63 :   ag_bls_agg_serde_t serde[1];
      31          63 :   serde->version = (uchar)BASE2_BITMAP;
      32          63 :   serde->bit_cnt = (ushort)bit_cnt;
      33          63 :   serde->payload    = NULL;
      34          63 :   serde->payload_sz = ag_bls_agg_ser_sz( agg ) - AG_BLS_AGG_HDR_SZ;
      35             : 
      36          63 :   ulong off = 0UL;
      37          63 :   buf[ off ] = serde->version;                 off += sizeof(uchar);
      38          63 :   FD_STORE( ushort, buf+off, serde->bit_cnt ); off += sizeof(ushort);
      39             : 
      40          63 :   uchar * payload = buf+off;
      41          63 :   fd_memset( payload, 0, serde->payload_sz );
      42        6633 :   for( ulong i=0UL; i<bit_cnt; i++ ) {
      43        6570 :     if( FD_LIKELY( fd_bls_set_test( agg->set, i ) ) ) payload[ i>>3 ] |= (uchar)( 1U << (i&7U) );
      44        6570 :   }
      45          63 :   off += serde->payload_sz;
      46             : 
      47          63 :   return off;
      48          63 : }
      49             : 
      50             : ulong
      51             : ag_bls_agg_pair_ser( fd_bls_agg_t const * agg,
      52             :                      fd_bls_agg_t const * agg_fb,
      53          42 :                      uchar *              buf ) {
      54             : 
      55          42 :   ulong bit_cnt = fd_ulong_max( agg_bit_cnt( agg ), agg_bit_cnt( agg_fb ) );
      56             : 
      57          42 :   ag_bls_agg_serde_t serde[1];
      58          42 :   serde->version = (uchar)BASE3_BITMAP;
      59          42 :   serde->bit_cnt = (ushort)bit_cnt;
      60          42 :   serde->payload    = NULL;
      61          42 :   serde->payload_sz = ag_bls_agg_pair_ser_sz( agg, agg_fb ) - AG_BLS_AGG_HDR_SZ;
      62             : 
      63          42 :   ulong off = 0UL;
      64          42 :   buf[ off ] = serde->version;                 off += sizeof(uchar);
      65          42 :   FD_STORE( ushort, buf+off, serde->bit_cnt ); off += sizeof(ushort);
      66             : 
      67          42 :   uchar * payload = buf+off;
      68        2505 :   for( ulong chunk=0UL; chunk<serde->payload_sz; chunk++ ) {
      69        2463 :     ulong start_bit = chunk*5UL;
      70        2463 :     ulong end_bit   = fd_ulong_min( start_bit+5UL, bit_cnt );
      71        2463 :     uint  block     = 0U;
      72        2463 :     uint  place     = 1U;
      73       14751 :     for( ulong i=start_bit; i<end_bit; i++ ) {
      74       12288 :       uint digit = fd_bls_set_test( agg->set,    i ) ? 1U
      75       12288 :                  : fd_bls_set_test( agg_fb->set, i ) ? 2U : 0U;
      76       12288 :       block += digit*place;
      77       12288 :       place *= 3U;
      78       12288 :     }
      79        2463 :     payload[ chunk ] = (uchar)block;
      80        2463 :   }
      81          42 :   off += serde->payload_sz;
      82             : 
      83          42 :   return off;
      84          42 : }
      85             : 
      86             : static int
      87             : bitmap_hdr( ag_bls_agg_serde_t * serde,
      88             :             uchar const *        buf,
      89         126 :             ulong                buf_sz ) {
      90         126 :   FAIL( buf_sz<AG_BLS_AGG_HDR_SZ, SZ );
      91             : 
      92         108 :   serde->version    = buf[ 0 ];
      93         108 :   serde->bit_cnt    = FD_LOAD( ushort, buf+1UL );
      94         108 :   serde->payload    = buf+AG_BLS_AGG_HDR_SZ;
      95         108 :   serde->payload_sz = buf_sz-AG_BLS_AGG_HDR_SZ;
      96             : 
      97         108 :   return AG_BLS_DE_SUCCESS;
      98         126 : }
      99             : 
     100             : static int
     101             : base2_de( fd_bls_agg_t *             agg,
     102          57 :           ag_bls_agg_serde_t const * serde ) {
     103          57 :   ulong bit_cnt = (ulong)serde->bit_cnt;
     104          57 :   FAIL( bit_cnt>FD_BLS_SET_MAX,                                            SZ    );
     105          54 :   FAIL( serde->payload_sz!=AG_BLS_AGG_SER_SZ( bit_cnt )-AG_BLS_AGG_HDR_SZ, INVAL );
     106             : 
     107          48 :   memset( agg, 0, sizeof(fd_bls_agg_t) ); /* zero is the point at infinity */
     108             : 
     109       12636 :   for( ulong i=0UL; i<bit_cnt; i++ ) {
     110       12588 :     if( FD_LIKELY( (serde->payload[ i>>3 ] >> (i&7U)) & 1U ) ) fd_bls_set_insert( agg->set, i );
     111       12588 :   }
     112          48 :   return AG_BLS_DE_SUCCESS;
     113          54 : }
     114             : 
     115             : static int
     116             : base3_de( fd_bls_agg_t *             agg,
     117             :           fd_bls_agg_t *             agg_fb,
     118          33 :           ag_bls_agg_serde_t const * serde ) {
     119          33 :   ulong bit_cnt   = (ulong)serde->bit_cnt;
     120          33 :   ulong chunk_cnt = AG_BLS_AGG_PAIR_SER_SZ( bit_cnt )-AG_BLS_AGG_HDR_SZ;
     121          33 :   FAIL( bit_cnt>FD_BLS_SET_MAX, SZ );
     122          30 :   FAIL( serde->payload_sz!=chunk_cnt, INVAL );
     123             : 
     124          30 :   memset( agg,  0, sizeof(fd_bls_agg_t) ); /* zero is the point at infinity */
     125          30 :   memset( agg_fb, 0, sizeof(fd_bls_agg_t) );
     126             : 
     127        2472 :   for( ulong chunk=0UL; chunk<chunk_cnt; chunk++ ) {
     128        2442 :     uint  block     = (uint)serde->payload[ chunk ];
     129        2442 :     ulong start_bit = chunk*5UL;
     130        2442 :     ulong end_bit   = fd_ulong_min( start_bit+5UL, bit_cnt );
     131       14631 :     for( ulong i=start_bit; i<end_bit; i++ ) {
     132       12189 :       uint digit = block % 3U; block /= 3U;
     133       12189 :       if(      FD_LIKELY  ( digit==1U ) ) fd_bls_set_insert( agg->set,    i );
     134        3099 :       else if( FD_UNLIKELY( digit==2U ) ) fd_bls_set_insert( agg_fb->set, i );
     135       12189 :     }
     136        2442 :   }
     137          30 :   return AG_BLS_DE_SUCCESS;
     138          30 : }
     139             : 
     140             : int
     141             : ag_bls_agg_de( fd_bls_agg_t * agg,
     142             :                uchar const *  buf,
     143          63 :                ulong          buf_sz ) {
     144          63 :   ag_bls_agg_serde_t serde[1];
     145             : 
     146          63 :   int err = bitmap_hdr( serde, buf, buf_sz );
     147          63 :   if( FD_UNLIKELY( err                       ) ) return err;
     148          54 :   FAIL( serde->version!=BASE2_BITMAP, INVAL );
     149             : 
     150          39 :   return base2_de( agg, serde );
     151          54 : }
     152             : 
     153             : int
     154             : ag_bls_agg_pair_de( fd_bls_agg_t * agg,
     155             :                     fd_bls_agg_t * agg_fb,
     156             :                     uchar const *  buf,
     157          63 :                     ulong          buf_sz ) {
     158          63 :   ag_bls_agg_serde_t serde[1];
     159             : 
     160          63 :   int err = bitmap_hdr( serde, buf, buf_sz );
     161          63 :   if( FD_UNLIKELY( err ) ) return err;
     162             : 
     163          54 :   switch( serde->version ) {
     164          18 :   case BASE2_BITMAP:
     165          18 :     err = base2_de( agg, serde );
     166          18 :     if( FD_UNLIKELY( err ) ) return err;
     167          18 :     memset( agg_fb, 0, sizeof(fd_bls_agg_t) );
     168          18 :     return AG_BLS_DE_SUCCESS;
     169          33 :   case BASE3_BITMAP:
     170          33 :     return base3_de( agg, agg_fb, serde );
     171           3 :   default:
     172           3 :     return AG_BLS_DE_ERR_INVAL;
     173          54 :   }
     174          54 : }

Generated by: LCOV version 1.14