LCOV - code coverage report
Current view: top level - flamenco/vm/syscall - fd_vm_syscall_curve.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 197 491 40.1 %
Date: 2026-02-05 06:00:08 Functions: 4 7 57.1 %

          Line data    Source code
       1             : #include "fd_vm_syscall.h"
       2             : #include "../../runtime/fd_bank.h"
       3             : #include "../../../ballet/ed25519/fd_curve25519.h"
       4             : #include "../../../ballet/ed25519/fd_ristretto255.h"
       5             : #include "../../../ballet/bls/fd_bls12_381.h"
       6             : 
       7             : int
       8             : fd_vm_syscall_sol_curve_validate_point( /**/            void *  _vm,
       9             :                                         /**/            ulong   curve_id,
      10             :                                         /**/            ulong   point_addr,
      11             :                                         FD_PARAM_UNUSED ulong   r3,
      12             :                                         FD_PARAM_UNUSED ulong   r4,
      13             :                                         FD_PARAM_UNUSED ulong   r5,
      14           0 :                                         /**/            ulong * _ret ) {
      15             :   /* https://github.com/anza-xyz/agave/blob/v1.18.8/programs/bpf_loader/src/syscalls/mod.rs#L871 */
      16           0 :   fd_vm_t * vm = (fd_vm_t *)_vm;
      17           0 :   ulong     ret = 1UL; /* by default return Ok(1) == error */
      18             : 
      19             :   /* BLS12-381 syscalls are under feature gate enable_bls12_381_syscall.
      20             :      To clean up the feature gate after activation, just remove this block
      21             :      (the rest of the function will behave correctly). */
      22           0 :   {
      23           0 :     if( FD_UNLIKELY(
      24           0 :       !FD_FEATURE_ACTIVE_BANK( vm->instr_ctx->bank, enable_bls12_381_syscall )
      25           0 :       && ( curve_id==FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G1_BE
      26           0 :         || curve_id==FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G1_LE
      27           0 :         || curve_id==FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G2_BE
      28           0 :         || curve_id==FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G2_LE )
      29           0 :     ) ) {
      30           0 :       FD_VM_ERR_FOR_LOG_SYSCALL( vm, FD_VM_SYSCALL_ERR_INVALID_ATTRIBUTE );
      31           0 :       return FD_VM_SYSCALL_ERR_INVALID_ATTRIBUTE; /* SyscallError::InvalidAttribute */
      32           0 :     }
      33           0 :   }
      34             : 
      35           0 :   uchar const * point = NULL;
      36           0 :   switch( curve_id ) {
      37             : 
      38           0 :   case FD_VM_SYSCALL_SOL_CURVE_CURVE25519_EDWARDS:
      39             : 
      40           0 :     FD_VM_CU_UPDATE( vm, FD_VM_CURVE_EDWARDS_VALIDATE_POINT_COST );
      41           0 :     point = FD_VM_MEM_HADDR_LD( vm, point_addr, FD_VM_ALIGN_RUST_POD_U8_ARRAY, FD_VM_SYSCALL_SOL_CURVE_CURVE25519_POINT_SZ );
      42           0 :     ret = (ulong)!fd_ed25519_point_validate( point ); /* 0 if valid point, 1 if not */
      43           0 :     break;
      44             : 
      45           0 :   case FD_VM_SYSCALL_SOL_CURVE_CURVE25519_RISTRETTO:
      46             : 
      47           0 :     FD_VM_CU_UPDATE( vm, FD_VM_CURVE_RISTRETTO_VALIDATE_POINT_COST );
      48           0 :     point = FD_VM_MEM_HADDR_LD( vm, point_addr, FD_VM_ALIGN_RUST_POD_U8_ARRAY, FD_VM_SYSCALL_SOL_CURVE_CURVE25519_POINT_SZ );
      49           0 :     ret = (ulong)!fd_ristretto255_point_validate( point ); /* 0 if valid point, 1 if not */
      50           0 :     break;
      51             : 
      52           0 : #if FD_HAS_BLST
      53           0 :   case FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G1_BE:
      54           0 :   case FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G1_LE: {
      55             : 
      56           0 :     int big_endian = ( curve_id & 0x80 ) ? 0 : 1;
      57           0 :     FD_VM_CU_UPDATE( vm, FD_VM_CURVE_BLS12_381_G1_VALIDATE_COST );
      58           0 :     point = FD_VM_MEM_HADDR_LD( vm, point_addr, FD_VM_ALIGN_RUST_POD_U8_ARRAY, FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G1_POINT_SZ );
      59           0 :     ret = (ulong)!fd_bls12_381_g1_validate_syscall( point, big_endian ); /* 0 if valid point, 1 if not */
      60           0 :   } break;
      61             : 
      62           0 :   case FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G2_BE:
      63           0 :   case FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G2_LE: {
      64             : 
      65           0 :     int big_endian = ( curve_id & 0x80 ) ? 0 : 1;
      66           0 :     FD_VM_CU_UPDATE( vm, FD_VM_CURVE_BLS12_381_G2_VALIDATE_COST );
      67           0 :     point = FD_VM_MEM_HADDR_LD( vm, point_addr, FD_VM_ALIGN_RUST_POD_U8_ARRAY, FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G2_POINT_SZ );
      68           0 :     ret = (ulong)!fd_bls12_381_g2_validate_syscall( point, big_endian ); /* 0 if valid point, 1 if not */
      69           0 :   } break;
      70           0 : #endif
      71             : 
      72           0 :   default:
      73             :     /* https://github.com/anza-xyz/agave/blob/5b3390b99a6e7665439c623062c1a1dda2803524/programs/bpf_loader/src/syscalls/mod.rs#L919-L928 */
      74           0 :     if( FD_FEATURE_ACTIVE_BANK( vm->instr_ctx->bank, abort_on_invalid_curve ) ) {
      75           0 :       FD_VM_ERR_FOR_LOG_SYSCALL( vm, FD_VM_SYSCALL_ERR_INVALID_ATTRIBUTE );
      76           0 :       return FD_VM_SYSCALL_ERR_INVALID_ATTRIBUTE; /* SyscallError::InvalidAttribute */
      77           0 :     }
      78           0 :   }
      79             : 
      80           0 :   *_ret = ret;
      81           0 :   return FD_VM_SUCCESS;
      82           0 : }
      83             : 
      84             : int
      85             : fd_vm_syscall_sol_curve_group_op( void *  _vm,
      86             :                                   ulong   curve_id,
      87             :                                   ulong   group_op,
      88             :                                   ulong   left_input_addr,
      89             :                                   ulong   right_input_addr,
      90             :                                   ulong   result_point_addr,
      91          15 :                                   ulong * _ret ) {
      92             :   /* https://github.com/anza-xyz/agave/blob/v1.18.8/programs/bpf_loader/src/syscalls/mod.rs#L928 */
      93          15 :   fd_vm_t * vm = (fd_vm_t *)_vm;
      94          15 :   ulong     ret = 1UL; /* by default return Ok(1) == error */
      95             : 
      96             :   /* BLS12-381 syscalls are under feature gate enable_bls12_381_syscall.
      97             :      To clean up the feature gate after activation, just remove this block
      98             :      (the rest of the function will behave correctly). */
      99          15 :   {
     100          15 :     if( FD_UNLIKELY(
     101          15 :       !FD_FEATURE_ACTIVE_BANK( vm->instr_ctx->bank, enable_bls12_381_syscall )
     102          15 :       && ( curve_id==FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G1_BE
     103          15 :         || curve_id==FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G1_LE
     104          15 :         || curve_id==FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G2_BE
     105          15 :         || curve_id==FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G2_LE )
     106          15 :     ) ) {
     107           0 :       FD_VM_ERR_FOR_LOG_SYSCALL( vm, FD_VM_SYSCALL_ERR_INVALID_ATTRIBUTE );
     108           0 :       return FD_VM_SYSCALL_ERR_INVALID_ATTRIBUTE; /* SyscallError::InvalidAttribute */
     109           0 :     }
     110          15 :   }
     111             : 
     112             :   /* Note: we don't strictly follow the Rust implementation, but instead combine
     113             :      common code across switch cases. Similar to fd_vm_syscall_sol_alt_bn128_group_op. */
     114             : 
     115             : /* MATCH_ID_OP allows us to unify 2 switch/case into 1.
     116             :    For better readability, we also temp define EDWARDS, RISTRETTO.
     117             : 
     118             :    The first time we check that both curve_id and group_op are valid
     119             :    with 2 nested switch/case. Using MATCH_ID_OP leads to undesidered
     120             :    edge cases. The second time, when we know that curve_id and group_op
     121             :    are correct, then we can use MATCH_ID_OP and a single switch/case. */
     122          30 : #define MATCH_ID_OP(crv_id,grp_op) ((crv_id << 4) | grp_op)
     123          15 : #define EDWARDS   FD_VM_SYSCALL_SOL_CURVE_CURVE25519_EDWARDS
     124          15 : #define RISTRETTO FD_VM_SYSCALL_SOL_CURVE_CURVE25519_RISTRETTO
     125          15 : #define BLS_G1_BE FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G1_BE
     126          15 : #define BLS_G1_LE FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G1_LE
     127          15 : #define BLS_G2_BE FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G2_BE
     128          15 : #define BLS_G2_LE FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G2_LE
     129             : 
     130          15 :   ulong cost = 0UL;
     131          15 :   ulong inputL_sz = 32UL;
     132          15 :   ulong inputR_sz = 32UL;
     133          15 :   switch( curve_id ) {
     134             : 
     135           0 :   case EDWARDS:
     136           0 :     switch( group_op ) {
     137             : 
     138           0 :     case FD_VM_SYSCALL_SOL_CURVE_ADD:
     139           0 :       cost = FD_VM_CURVE_EDWARDS_ADD_COST;
     140           0 :       break;
     141             : 
     142           0 :     case FD_VM_SYSCALL_SOL_CURVE_SUB:
     143           0 :       cost = FD_VM_CURVE_EDWARDS_SUBTRACT_COST;
     144           0 :       break;
     145             : 
     146           0 :     case FD_VM_SYSCALL_SOL_CURVE_MUL:
     147           0 :       cost = FD_VM_CURVE_EDWARDS_MULTIPLY_COST;
     148           0 :       break;
     149             : 
     150           0 :     default:
     151           0 :       goto invalid_error;
     152           0 :     }
     153           0 :     break;
     154             : 
     155          12 :   case RISTRETTO:
     156          12 :     switch( group_op ) {
     157             : 
     158           6 :     case FD_VM_SYSCALL_SOL_CURVE_ADD:
     159           6 :       cost = FD_VM_CURVE_RISTRETTO_ADD_COST;
     160           6 :       break;
     161             : 
     162           3 :     case FD_VM_SYSCALL_SOL_CURVE_SUB:
     163           3 :       cost = FD_VM_CURVE_RISTRETTO_SUBTRACT_COST;
     164           3 :       break;
     165             : 
     166           3 :     case FD_VM_SYSCALL_SOL_CURVE_MUL:
     167           3 :       cost = FD_VM_CURVE_RISTRETTO_MULTIPLY_COST;
     168           3 :       break;
     169             : 
     170           0 :     default:
     171           0 :       goto invalid_error;
     172          12 :     }
     173          12 :     break;
     174             : 
     175          12 : #if FD_HAS_BLST
     176             :   /* BLS12-381 G1 */
     177          12 :   case BLS_G1_BE:
     178           3 :   case BLS_G1_LE:
     179           3 :     switch( group_op ) {
     180             : 
     181           3 :     case FD_VM_SYSCALL_SOL_CURVE_ADD:
     182           3 :       cost = FD_VM_CURVE_BLS12_381_G1_ADD_COST;
     183           3 :       inputL_sz = FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G1_POINT_SZ;
     184           3 :       inputR_sz = FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G1_POINT_SZ;
     185           3 :       break;
     186             : 
     187           0 :     case FD_VM_SYSCALL_SOL_CURVE_SUB:
     188           0 :       cost = FD_VM_CURVE_BLS12_381_G1_SUB_COST;
     189           0 :       inputL_sz = FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G1_POINT_SZ;
     190           0 :       inputR_sz = FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G1_POINT_SZ;
     191           0 :       break;
     192             : 
     193           0 :     case FD_VM_SYSCALL_SOL_CURVE_MUL:
     194           0 :       cost = FD_VM_CURVE_BLS12_381_G1_MUL_COST;
     195           0 :       inputL_sz = FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G1_POINT_SZ;
     196             :       /* inputR_sz = 32UL // scalar */
     197           0 :       break;
     198             : 
     199           0 :     default:
     200           0 :       goto invalid_error;
     201           3 :     }
     202           3 :     break;
     203             : 
     204             :   /* BLS12-381 G2 */
     205           3 :   case BLS_G2_BE:
     206           0 :   case BLS_G2_LE:
     207           0 :     switch( group_op ) {
     208             : 
     209           0 :     case FD_VM_SYSCALL_SOL_CURVE_ADD:
     210           0 :       cost = FD_VM_CURVE_BLS12_381_G2_ADD_COST;
     211           0 :       inputL_sz = FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G2_POINT_SZ;
     212           0 :       inputR_sz = FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G2_POINT_SZ;
     213           0 :       break;
     214             : 
     215           0 :     case FD_VM_SYSCALL_SOL_CURVE_SUB:
     216           0 :       cost = FD_VM_CURVE_BLS12_381_G2_SUB_COST;
     217           0 :       inputL_sz = FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G2_POINT_SZ;
     218           0 :       inputR_sz = FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G2_POINT_SZ;
     219           0 :       break;
     220             : 
     221           0 :     case FD_VM_SYSCALL_SOL_CURVE_MUL:
     222           0 :       cost = FD_VM_CURVE_BLS12_381_G2_MUL_COST;
     223           0 :       inputL_sz = FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G2_POINT_SZ;
     224             :       /* inputR_sz = 32UL // scalar */
     225           0 :       break;
     226             : 
     227           0 :     default:
     228           0 :       goto invalid_error;
     229           0 :     }
     230           0 :     break;
     231           0 : #endif
     232             : 
     233           0 :   default:
     234           0 :     goto invalid_error;
     235          15 :   }
     236             : 
     237             :   /* https://github.com/anza-xyz/agave/blob/v1.18.8/programs/bpf_loader/src/syscalls/mod.rs#L944-L947 */
     238          30 :   FD_VM_CU_UPDATE( vm, cost );
     239             : 
     240             :   /* https://github.com/anza-xyz/agave/blob/v1.18.8/programs/bpf_loader/src/syscalls/mod.rs#L949-L958 */
     241             : 
     242             :   /* Note: left_input_addr is a point for add, sub, BUT it's a scalar for mul. */
     243          45 :   uchar const * inputL = FD_VM_MEM_HADDR_LD( vm, left_input_addr,  FD_VM_ALIGN_RUST_POD_U8_ARRAY, inputL_sz );
     244          45 :   uchar const * inputR = FD_VM_MEM_HADDR_LD( vm, right_input_addr, FD_VM_ALIGN_RUST_POD_U8_ARRAY, inputR_sz );
     245             : 
     246           0 : #if FD_HAS_BLST
     247          15 :   int big_endian = ( curve_id & 0x80 ) ? 0 : 1;
     248          45 : #endif
     249             : 
     250          45 :   switch( MATCH_ID_OP( curve_id, group_op ) ) {
     251             : 
     252           0 :   case MATCH_ID_OP( EDWARDS, FD_VM_SYSCALL_SOL_CURVE_ADD ): {
     253           0 :     fd_ed25519_point_t p0[1], p1[1], r[1];
     254           0 :     if( FD_UNLIKELY( !fd_ed25519_point_frombytes( p0, inputL ) ) ) {
     255           0 :       goto soft_error;
     256           0 :     }
     257           0 :     if( FD_UNLIKELY( !fd_ed25519_point_frombytes( p1, inputR ) ) ) {
     258           0 :       goto soft_error;
     259           0 :     }
     260             : 
     261           0 :     uchar * result = FD_VM_HADDR_QUERY_U8_ARRAY( vm, result_point_addr, FD_VM_SYSCALL_SOL_CURVE_CURVE25519_POINT_SZ );
     262           0 :     fd_ed25519_point_add( r, p0, p1 );
     263           0 :     fd_ed25519_point_tobytes( result, r );
     264           0 :     ret = 0UL;
     265           0 :     break;
     266           0 :   }
     267             : 
     268           0 :   case MATCH_ID_OP( EDWARDS, FD_VM_SYSCALL_SOL_CURVE_SUB ): {
     269           0 :     fd_ed25519_point_t p0[1], p1[1], r[1];
     270           0 :     if( FD_UNLIKELY( !fd_ed25519_point_frombytes( p0, inputL ) ) ) {
     271           0 :       goto soft_error;
     272           0 :     }
     273           0 :     if( FD_UNLIKELY( !fd_ed25519_point_frombytes( p1, inputR ) ) ) {
     274           0 :       goto soft_error;
     275           0 :     }
     276             : 
     277           0 :     uchar * result = FD_VM_HADDR_QUERY_U8_ARRAY( vm, result_point_addr, FD_VM_SYSCALL_SOL_CURVE_CURVE25519_POINT_SZ );
     278           0 :     fd_ed25519_point_sub( r, p0, p1 );
     279           0 :     fd_ed25519_point_tobytes( result, r );
     280           0 :     ret = 0UL;
     281           0 :     break;
     282           0 :   }
     283             : 
     284           0 :   case MATCH_ID_OP( EDWARDS, FD_VM_SYSCALL_SOL_CURVE_MUL ): {
     285           0 :     fd_ed25519_point_t p[1], r[1];
     286           0 :     if( FD_UNLIKELY( !fd_curve25519_scalar_validate( inputL ) ) ) {
     287           0 :       goto soft_error;
     288           0 :     }
     289           0 :     if( FD_UNLIKELY( !fd_ed25519_point_frombytes( p, inputR ) ) ) {
     290           0 :       goto soft_error;
     291           0 :     }
     292             : 
     293           0 :     uchar * result = FD_VM_HADDR_QUERY_U8_ARRAY( vm, result_point_addr, FD_VM_SYSCALL_SOL_CURVE_CURVE25519_POINT_SZ );
     294           0 :     fd_ed25519_scalar_mul( r, inputL, p );
     295           0 :     fd_ed25519_point_tobytes( result, r );
     296           0 :     ret = 0UL;
     297           0 :     break;
     298           0 :   }
     299             : 
     300           6 :   case MATCH_ID_OP( RISTRETTO, FD_VM_SYSCALL_SOL_CURVE_ADD ): {
     301           6 :     fd_ristretto255_point_t p0[1], p1[1], r[1];
     302           6 :     if( FD_UNLIKELY( !fd_ristretto255_point_frombytes( p0, inputL ) ) ) {
     303           0 :       goto soft_error;
     304           0 :     }
     305           6 :     if( FD_UNLIKELY( !fd_ristretto255_point_frombytes( p1, inputR ) ) ) {
     306           0 :       goto soft_error;
     307           0 :     }
     308             : 
     309           6 :     uchar * result = FD_VM_HADDR_QUERY_U8_ARRAY( vm, result_point_addr, FD_VM_SYSCALL_SOL_CURVE_CURVE25519_POINT_SZ );
     310           6 :     fd_ristretto255_point_add( r, p0, p1 );
     311           6 :     fd_ristretto255_point_tobytes( result, r );
     312           6 :     ret = 0UL;
     313           6 :     break;
     314           6 :   }
     315             : 
     316           3 :   case MATCH_ID_OP( RISTRETTO, FD_VM_SYSCALL_SOL_CURVE_SUB ): {
     317           3 :     fd_ristretto255_point_t p0[1], p1[1], r[1];
     318           3 :     if( FD_UNLIKELY( !fd_ristretto255_point_frombytes( p0, inputL ) ) ) {
     319           0 :       goto soft_error;
     320           0 :     }
     321           3 :     if( FD_UNLIKELY( !fd_ristretto255_point_frombytes( p1, inputR ) ) ) {
     322           0 :       goto soft_error;
     323           0 :     }
     324             : 
     325           3 :     uchar * result = FD_VM_HADDR_QUERY_U8_ARRAY( vm, result_point_addr, FD_VM_SYSCALL_SOL_CURVE_CURVE25519_POINT_SZ );
     326           3 :     fd_ristretto255_point_sub( r, p0, p1 );
     327           3 :     fd_ristretto255_point_tobytes( result, r );
     328           3 :     ret = 0UL;
     329           3 :     break;
     330           3 :   }
     331             : 
     332           3 :   case MATCH_ID_OP( RISTRETTO, FD_VM_SYSCALL_SOL_CURVE_MUL ): {
     333           3 :     fd_ristretto255_point_t p[1], r[1];
     334           3 :     if( FD_UNLIKELY( !fd_curve25519_scalar_validate( inputL ) ) ) {
     335           0 :       goto soft_error;
     336           0 :     }
     337           3 :     if( FD_UNLIKELY( !fd_ristretto255_point_frombytes( p, inputR ) ) ) {
     338           0 :       goto soft_error;
     339           0 :     }
     340             : 
     341           3 :     uchar * result = FD_VM_HADDR_QUERY_U8_ARRAY( vm, result_point_addr, FD_VM_SYSCALL_SOL_CURVE_CURVE25519_POINT_SZ );
     342           3 :     fd_ristretto255_scalar_mul( r, inputL, p );
     343           3 :     fd_ristretto255_point_tobytes( result, r );
     344           3 :     ret = 0UL;
     345           3 :     break;
     346           3 :   }
     347             : 
     348           0 : #if FD_HAS_BLST
     349             :   /* BLS12-381 G1 */
     350           0 :   case MATCH_ID_OP( BLS_G1_BE, FD_VM_SYSCALL_SOL_CURVE_ADD ):
     351           3 :   case MATCH_ID_OP( BLS_G1_LE, FD_VM_SYSCALL_SOL_CURVE_ADD ): {
     352           3 :     uchar * result = FD_VM_HADDR_QUERY_U8_ARRAY( vm, result_point_addr, FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G1_POINT_SZ );
     353             :     /* Compute add */
     354           3 :     if( FD_LIKELY( fd_bls12_381_g1_add_syscall( result, inputL, inputR, big_endian )==0 ) ) {
     355           3 :       ret = 0UL; /* success */
     356           3 :     }
     357           3 :     break;
     358           3 :   }
     359             : 
     360           0 :   case MATCH_ID_OP( BLS_G1_BE, FD_VM_SYSCALL_SOL_CURVE_SUB ):
     361           0 :   case MATCH_ID_OP( BLS_G1_LE, FD_VM_SYSCALL_SOL_CURVE_SUB ): {
     362           0 :     uchar * result = FD_VM_HADDR_QUERY_U8_ARRAY( vm, result_point_addr, FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G1_POINT_SZ );
     363             :     /* Compute sub */
     364           0 :     if( FD_LIKELY( fd_bls12_381_g1_sub_syscall( result, inputL, inputR, big_endian )==0 ) ) {
     365           0 :       ret = 0UL; /* success */
     366           0 :     }
     367           0 :     break;
     368           0 :   }
     369             : 
     370           0 :   case MATCH_ID_OP( BLS_G1_BE, FD_VM_SYSCALL_SOL_CURVE_MUL ):
     371           0 :   case MATCH_ID_OP( BLS_G1_LE, FD_VM_SYSCALL_SOL_CURVE_MUL ): {
     372           0 :     uchar * result = FD_VM_HADDR_QUERY_U8_ARRAY( vm, result_point_addr, FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G1_POINT_SZ );
     373             :     /* Compute mul */
     374           0 :     if( FD_LIKELY( fd_bls12_381_g1_mul_syscall( result, inputL, inputR, big_endian )==0 ) ) {
     375           0 :       ret = 0UL; /* success */
     376           0 :     }
     377           0 :     break;
     378           0 :   }
     379             : 
     380             :   /* BLS12-381 G2 */
     381           0 :   case MATCH_ID_OP( BLS_G2_BE, FD_VM_SYSCALL_SOL_CURVE_ADD ):
     382           0 :   case MATCH_ID_OP( BLS_G2_LE, FD_VM_SYSCALL_SOL_CURVE_ADD ): {
     383           0 :     uchar * result = FD_VM_HADDR_QUERY_U8_ARRAY( vm, result_point_addr, FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G2_POINT_SZ );
     384             :     /* Compute add */
     385           0 :     if( FD_LIKELY( fd_bls12_381_g2_add_syscall( result, inputL, inputR, big_endian )==0 ) ) {
     386           0 :       ret = 0UL; /* success */
     387           0 :     }
     388           0 :     break;
     389           0 :   }
     390             : 
     391           0 :   case MATCH_ID_OP( BLS_G2_BE, FD_VM_SYSCALL_SOL_CURVE_SUB ):
     392           0 :   case MATCH_ID_OP( BLS_G2_LE, FD_VM_SYSCALL_SOL_CURVE_SUB ): {
     393           0 :     uchar * result = FD_VM_HADDR_QUERY_U8_ARRAY( vm, result_point_addr, FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G2_POINT_SZ );
     394             :     /* Compute sub */
     395           0 :     if( FD_LIKELY( fd_bls12_381_g2_sub_syscall( result, inputL, inputR, big_endian )==0 ) ) {
     396           0 :       ret = 0UL; /* success */
     397           0 :     }
     398           0 :     break;
     399           0 :   }
     400             : 
     401           0 :   case MATCH_ID_OP( BLS_G2_BE, FD_VM_SYSCALL_SOL_CURVE_MUL ):
     402           0 :   case MATCH_ID_OP( BLS_G2_LE, FD_VM_SYSCALL_SOL_CURVE_MUL ): {
     403           0 :     uchar * result = FD_VM_HADDR_QUERY_U8_ARRAY( vm, result_point_addr, FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G2_POINT_SZ );
     404             :     /* Compute mul */
     405           0 :     if( FD_LIKELY( fd_bls12_381_g2_mul_syscall( result, inputL, inputR, big_endian )==0 ) ) {
     406           0 :       ret = 0UL; /* success */
     407           0 :     }
     408           0 :     break;
     409           0 :   }
     410           0 : #endif
     411             : 
     412           0 :   default:
     413             :     /* COV: this can never happen because of the previous switch */
     414           0 :     return FD_VM_SYSCALL_ERR_INVALID_ATTRIBUTE; /* SyscallError::InvalidAttribute */
     415          45 :   }
     416             : 
     417          15 : soft_error:
     418          15 :   *_ret = ret;
     419          15 :   return FD_VM_SUCCESS;
     420           0 : #undef MATCH_ID_OP
     421           0 : #undef EDWARDS
     422           0 : #undef RISTRETTO
     423           0 : #undef BLS_G1_BE
     424           0 : #undef BLS_G1_LE
     425           0 : #undef BLS_G2_BE
     426           0 : #undef BLS_G2_LE
     427             : 
     428           0 : invalid_error:
     429             :   /* https://github.com/anza-xyz/agave/blob/5b3390b99a6e7665439c623062c1a1dda2803524/programs/bpf_loader/src/syscalls/mod.rs#L1135-L1156 */
     430           0 :   if( FD_FEATURE_ACTIVE_BANK( vm->instr_ctx->bank, abort_on_invalid_curve ) ) {
     431           0 :     FD_VM_ERR_FOR_LOG_SYSCALL( vm, FD_VM_SYSCALL_ERR_INVALID_ATTRIBUTE );
     432           0 :     return FD_VM_SYSCALL_ERR_INVALID_ATTRIBUTE; /* SyscallError::InvalidAttribute */
     433           0 :   }
     434           0 :   *_ret = 1UL;
     435           0 :   return FD_VM_SUCCESS;
     436           0 : }
     437             : 
     438             : /* multi_scalar_mul_edwards computes a MSM on curve25519.
     439             : 
     440             :    This function is equivalent to
     441             :    zk-token-sdk::edwards::multi_scalar_mul_edwards
     442             : 
     443             :    https://github.com/solana-labs/solana/blob/v1.17.7/zk-token-sdk/src/curve25519/edwards.rs#L116
     444             : 
     445             :    Specifically it takes as input byte arrays and takes care of scalars
     446             :    validation and points decompression.  It then invokes ballet MSM
     447             :    function fd_ed25519_multi_scalar_mul.  To avoid dynamic allocation,
     448             :    the full MSM is done in batches of FD_BALLET_CURVE25519_MSM_BATCH_SZ. */
     449             : 
     450             : static fd_ed25519_point_t *
     451             : multi_scalar_mul_edwards( fd_ed25519_point_t * r,
     452             :                           uchar const *        scalars,
     453             :                           uchar const *        points,
     454           3 :                           ulong                cnt ) {
     455             :   /* Validate all scalars first (fast) */
     456           9 :   for( ulong i=0UL; i<cnt; i++ ) {
     457           6 :     if( FD_UNLIKELY( !fd_curve25519_scalar_validate ( scalars + i*FD_VM_SYSCALL_SOL_CURVE_CURVE25519_SCALAR_SZ ) ) ) {
     458           0 :       return NULL;
     459           0 :     }
     460           6 :   }
     461             : 
     462             :   /* Static allocation of a batch of decompressed points */
     463           3 :   fd_ed25519_point_t tmp[1];
     464           3 :   fd_ed25519_point_t A[ FD_BALLET_CURVE25519_MSM_BATCH_SZ ];
     465             : 
     466           3 :   fd_ed25519_point_set_zero( r );
     467           6 :   for( ulong i=0UL; i<cnt; i+=FD_BALLET_CURVE25519_MSM_BATCH_SZ ) {
     468           3 :     ulong batch_cnt = fd_ulong_min( cnt-i, FD_BALLET_CURVE25519_MSM_BATCH_SZ );
     469             : 
     470             :     /* Decompress (and validate) points */
     471           9 :     for( ulong j=0UL; j<batch_cnt; j++ ) {
     472             :       //TODO: use fd_ed25519_point_frombytes_2x
     473           6 :       if( FD_UNLIKELY( !fd_ed25519_point_frombytes( &A[j], points + j*FD_VM_SYSCALL_SOL_CURVE_CURVE25519_POINT_SZ ) ) ) {
     474           0 :         return NULL;
     475           0 :       }
     476           6 :     }
     477             : 
     478           3 :     fd_ed25519_multi_scalar_mul( tmp, scalars, A, batch_cnt );
     479           3 :     fd_ed25519_point_add( r, r, tmp );
     480           3 :     points  += FD_VM_SYSCALL_SOL_CURVE_CURVE25519_POINT_SZ *batch_cnt;
     481           3 :     scalars += FD_VM_SYSCALL_SOL_CURVE_CURVE25519_SCALAR_SZ*batch_cnt;
     482           3 :   }
     483             : 
     484           3 :   return r;
     485           3 : }
     486             : 
     487             : /* multi_scalar_mul_ristretto computes a MSM on ristretto255.
     488             :    See multi_scalar_mul_edwards for details. */
     489             : 
     490             : static fd_ristretto255_point_t *
     491             : multi_scalar_mul_ristretto( fd_ristretto255_point_t * r,
     492             :                             uchar const *             scalars,
     493             :                             uchar const *             points,
     494           3 :                             ulong                     cnt ) {
     495             :   /* Validate all scalars first (fast) */
     496           9 :   for( ulong i=0UL; i<cnt; i++ ) {
     497           6 :     if( FD_UNLIKELY( !fd_curve25519_scalar_validate ( scalars + i*FD_VM_SYSCALL_SOL_CURVE_CURVE25519_SCALAR_SZ ) ) ) {
     498           0 :       return NULL;
     499           0 :     }
     500           6 :   }
     501             : 
     502             :   /* Static allocation of a batch of decompressed points */
     503           3 :   fd_ristretto255_point_t tmp[1];
     504           3 :   fd_ristretto255_point_t A[ FD_BALLET_CURVE25519_MSM_BATCH_SZ ];
     505             : 
     506           3 :   fd_ristretto255_point_set_zero( r );
     507           6 :   for( ulong i=0UL; i<cnt; i+=FD_BALLET_CURVE25519_MSM_BATCH_SZ ) {
     508           3 :     ulong batch_cnt = fd_ulong_min( cnt-i, FD_BALLET_CURVE25519_MSM_BATCH_SZ );
     509             : 
     510             :     /* Decompress (and validate) points */
     511           9 :     for( ulong j=0UL; j<batch_cnt; j++ ) {
     512             :       //TODO: use fd_ristretto255_point_frombytes_2x
     513           6 :       if( FD_UNLIKELY( !fd_ristretto255_point_frombytes( &A[j], points + j*FD_VM_SYSCALL_SOL_CURVE_CURVE25519_POINT_SZ ) ) ) {
     514           0 :         return NULL;
     515           0 :       }
     516           6 :     }
     517             : 
     518           3 :     fd_ristretto255_multi_scalar_mul( tmp, scalars, A, batch_cnt );
     519           3 :     fd_ristretto255_point_add( r, r, tmp );
     520           3 :     points  += FD_VM_SYSCALL_SOL_CURVE_CURVE25519_POINT_SZ *batch_cnt;
     521           3 :     scalars += FD_VM_SYSCALL_SOL_CURVE_CURVE25519_SCALAR_SZ*batch_cnt;
     522           3 :   }
     523             : 
     524           3 :   return r;
     525           3 : }
     526             : 
     527             : #undef BATCH_MAX
     528             : 
     529             : int
     530             : fd_vm_syscall_sol_curve_multiscalar_mul( void *  _vm,
     531             :                                          ulong   curve_id,
     532             :                                          ulong   scalars_addr,
     533             :                                          ulong   points_addr,
     534             :                                          ulong   points_len,
     535             :                                          ulong   result_point_addr,
     536          15 :                                          ulong * _ret ) {
     537             :   /* https://github.com/anza-xyz/agave/blob/v1.18.8/programs/bpf_loader/src/syscalls/mod.rs#L1129 */
     538          15 :   fd_vm_t * vm = (fd_vm_t *)_vm;
     539          15 :   ulong     ret = 1UL; /* by default return Ok(1) == error */
     540             : 
     541             :   /* https://github.com/anza-xyz/agave/blob/v1.18.8/programs/bpf_loader/src/syscalls/mod.rs#L1143-L1151 */
     542          15 :   if( FD_UNLIKELY( points_len > 512 ) ) {
     543           3 :     FD_VM_ERR_FOR_LOG_SYSCALL( vm, FD_VM_SYSCALL_ERR_INVALID_LENGTH );
     544           3 :     return FD_VM_SYSCALL_ERR_INVALID_LENGTH; /* SyscallError::InvalidLength */
     545           3 :   }
     546             : 
     547             :   /* Note: we don't strictly follow the Rust implementation, but instead combine
     548             :      common code across switch cases. Similar to fd_vm_syscall_sol_alt_bn128_group_op. */
     549             : 
     550          12 :   ulong base_cost = 0UL;
     551          12 :   ulong incremental_cost = 0UL;
     552          12 :   switch( curve_id ) {
     553           6 :   case FD_VM_SYSCALL_SOL_CURVE_CURVE25519_EDWARDS:
     554           6 :     base_cost = FD_VM_CURVE_EDWARDS_MSM_BASE_COST;
     555           6 :     incremental_cost = FD_VM_CURVE_EDWARDS_MSM_INCREMENTAL_COST;
     556           6 :     break;
     557             : 
     558           3 :   case FD_VM_SYSCALL_SOL_CURVE_CURVE25519_RISTRETTO:
     559           3 :     base_cost = FD_VM_CURVE_RISTRETTO_MSM_BASE_COST;
     560           3 :     incremental_cost = FD_VM_CURVE_RISTRETTO_MSM_INCREMENTAL_COST;
     561           3 :     break;
     562             : 
     563           3 :   default:
     564             :     /* https://github.com/anza-xyz/agave/blob/5b3390b99a6e7665439c623062c1a1dda2803524/programs/bpf_loader/src/syscalls/mod.rs#L1262-L1271 */
     565           3 :     if( FD_UNLIKELY( FD_FEATURE_ACTIVE_BANK( vm->instr_ctx->bank, abort_on_invalid_curve ) ) ) {
     566           3 :       FD_VM_ERR_FOR_LOG_SYSCALL( vm, FD_VM_SYSCALL_ERR_INVALID_ATTRIBUTE );
     567           3 :       return FD_VM_SYSCALL_ERR_INVALID_ATTRIBUTE; /* SyscallError::InvalidAttribute */
     568           3 :     }
     569           0 :     goto soft_error;
     570          12 :   }
     571             : 
     572             :   /* https://github.com/anza-xyz/agave/blob/v1.18.8/programs/bpf_loader/src/syscalls/mod.rs#L1155-L1164 */
     573           9 :   ulong cost = fd_ulong_sat_add(
     574           9 :     base_cost,
     575           9 :     fd_ulong_sat_mul(
     576           9 :       incremental_cost,
     577           9 :       fd_ulong_sat_sub( points_len, 1 )
     578           9 :     )
     579           9 :   );
     580           9 :   FD_VM_CU_UPDATE( vm, cost );
     581             : 
     582             :   /* Edge case points_len==0.
     583             :      Agave computes the MSM, that returns the point at infinity, and stores the result.
     584             :      This means that we have to mem map result, and then set the point at infinity,
     585             :      that is 0x0100..00 for Edwards and 0x00..00 for Ristretto. */
     586           9 :   if ( FD_UNLIKELY( points_len==0 ) ) {
     587           3 :     uchar * result = FD_VM_MEM_HADDR_ST( vm, result_point_addr, FD_VM_ALIGN_RUST_POD_U8_ARRAY, FD_VM_SYSCALL_SOL_CURVE_CURVE25519_POINT_SZ );
     588           0 :     memset( result, 0, 32 );
     589           0 :     result[0] = curve_id==FD_VM_SYSCALL_SOL_CURVE_CURVE25519_EDWARDS ? 1 : 0;
     590           0 :     *_ret = 0;
     591           0 :     return FD_VM_SUCCESS;
     592           3 :   }
     593             : 
     594             :   /* https://github.com/anza-xyz/agave/blob/v1.18.8/programs/bpf_loader/src/syscalls/mod.rs#L1166-L1178 */
     595          18 :   uchar const * scalars = FD_VM_MEM_HADDR_LD( vm, scalars_addr, FD_VM_ALIGN_RUST_POD_U8_ARRAY, points_len*FD_VM_SYSCALL_SOL_CURVE_CURVE25519_SCALAR_SZ );
     596          18 :   uchar const * points  = FD_VM_MEM_HADDR_LD( vm, points_addr,  FD_VM_ALIGN_RUST_POD_U8_ARRAY, points_len*FD_VM_SYSCALL_SOL_CURVE_CURVE25519_POINT_SZ );
     597             : 
     598           0 :   switch( curve_id ) {
     599             : 
     600           3 :   case FD_VM_SYSCALL_SOL_CURVE_CURVE25519_EDWARDS: {
     601             :     /* https://github.com/anza-xyz/agave/blob/v1.18.8/programs/bpf_loader/src/syscalls/mod.rs#L1180-L1189 */
     602           3 :     fd_ed25519_point_t _r[1];
     603           3 :     fd_ed25519_point_t * r = multi_scalar_mul_edwards( _r, scalars, points, points_len );
     604             : 
     605           3 :     if( FD_LIKELY( r ) ) {
     606           3 :       uchar * result = FD_VM_HADDR_QUERY_U8_ARRAY( vm, result_point_addr, FD_VM_SYSCALL_SOL_CURVE_CURVE25519_POINT_SZ );
     607           3 :       fd_ed25519_point_tobytes( result, r );
     608           3 :       ret = 0UL;
     609           3 :     }
     610           3 :     break;
     611           3 :   }
     612             : 
     613           3 :   case FD_VM_SYSCALL_SOL_CURVE_CURVE25519_RISTRETTO: {
     614           3 :     fd_ristretto255_point_t _r[1];
     615           3 :     fd_ristretto255_point_t * r = multi_scalar_mul_ristretto( _r, scalars, points, points_len );
     616             : 
     617           3 :     if( FD_LIKELY( r ) ) {
     618           3 :       uchar * result = FD_VM_HADDR_QUERY_U8_ARRAY( vm, result_point_addr, FD_VM_SYSCALL_SOL_CURVE_CURVE25519_POINT_SZ );
     619           3 :       fd_ristretto255_point_tobytes( result, r );
     620           3 :       ret = 0UL;
     621           3 :     }
     622           3 :     break;
     623           3 :   }
     624             : 
     625           3 :   default:
     626             :     /* COV: this can never happen because of the previous switch */
     627           0 :     return FD_VM_SYSCALL_ERR_INVALID_ATTRIBUTE; /* SyscallError::InvalidAttribute */
     628          18 :   }
     629             : 
     630           6 : soft_error:
     631           6 :   *_ret = ret;
     632           6 :   return FD_VM_SUCCESS;
     633          18 : }
     634             : 
     635             : #if FD_HAS_BLST
     636             : 
     637             : int
     638             : fd_vm_syscall_sol_curve_decompress( /**/            void *  _vm,
     639             :                                     /**/            ulong   curve_id,
     640             :                                     /**/            ulong   point_addr,
     641             :                                     /**/            ulong   result_addr,
     642             :                                     FD_PARAM_UNUSED ulong   r4,
     643             :                                     FD_PARAM_UNUSED ulong   r5,
     644           0 :                                     /**/            ulong * _ret ) {
     645             :   /* https://github.com/anza-xyz/agave/blob/691c1195ff29989aa37bbe8750718e176636685b/syscalls/src/lib.rs#L1118 */
     646           0 :   fd_vm_t * vm = (fd_vm_t *)_vm;
     647           0 :   ulong     ret = 1UL; /* by default return Ok(1) == error */
     648             : 
     649           0 :   int big_endian = ( curve_id & 0x80 ) ? 0 : 1;
     650             : 
     651           0 :   uchar const * point = NULL;
     652           0 :   switch( curve_id ) {
     653             : 
     654           0 :   case FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G1_BE:
     655           0 :   case FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G1_LE: {
     656           0 :     FD_VM_CU_UPDATE( vm, FD_VM_CURVE_BLS12_381_G1_DECOMPRESS_COST );
     657           0 :     point = FD_VM_MEM_HADDR_LD( vm, point_addr, FD_VM_ALIGN_RUST_POD_U8_ARRAY, FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G1_POINT_SZ );
     658           0 :     uchar * result = FD_VM_HADDR_QUERY_U8_ARRAY( vm, result_addr, FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G1_POINT_SZ );
     659           0 :     if( FD_LIKELY( fd_bls12_381_g1_decompress_syscall( result, point, big_endian )==0 ) ) {
     660           0 :       ret = 0UL; /* success */
     661           0 :     }
     662           0 :   } break;
     663             : 
     664           0 :   case FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G2_BE:
     665           0 :   case FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G2_LE: {
     666           0 :     FD_VM_CU_UPDATE( vm, FD_VM_CURVE_BLS12_381_G2_DECOMPRESS_COST );
     667           0 :     point = FD_VM_MEM_HADDR_LD( vm, point_addr, FD_VM_ALIGN_RUST_POD_U8_ARRAY, FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G2_POINT_SZ );
     668           0 :     uchar * result = FD_VM_HADDR_QUERY_U8_ARRAY( vm, result_addr, FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G2_POINT_SZ );
     669           0 :     if( FD_LIKELY( fd_bls12_381_g2_decompress_syscall( result, point, big_endian )==0 ) ) {
     670           0 :       ret = 0UL; /* success */
     671           0 :     }
     672           0 :   } break;
     673             : 
     674           0 :   default:
     675           0 :     FD_VM_ERR_FOR_LOG_SYSCALL( vm, FD_VM_SYSCALL_ERR_INVALID_ATTRIBUTE );
     676           0 :     return FD_VM_SYSCALL_ERR_INVALID_ATTRIBUTE; /* SyscallError::InvalidAttribute */
     677           0 :   }
     678             : 
     679           0 :   *_ret = ret;
     680           0 :   return FD_VM_SUCCESS;
     681           0 : }
     682             : 
     683             : int
     684             : fd_vm_syscall_sol_curve_pairing_map( /**/            void *  _vm,
     685             :                                      /**/            ulong   curve_id,
     686             :                                      /**/            ulong   num_pairs,
     687             :                                      FD_PARAM_UNUSED ulong   g1_points_addr,
     688             :                                      FD_PARAM_UNUSED ulong   g2_points_addr,
     689             :                                      FD_PARAM_UNUSED ulong   result_addr,
     690           0 :                                      /**/            ulong * _ret ) {
     691             :   /* https://github.com/anza-xyz/agave/blob/691c1195ff29989aa37bbe8750718e176636685b/syscalls/src/lib.rs#L1805 */
     692           0 :   fd_vm_t * vm = (fd_vm_t *)_vm;
     693           0 :   ulong     ret = 1UL; /* by default return Ok(1) == error */
     694             : 
     695           0 :   int big_endian = ( curve_id & 0x80 ) ? 0 : 1;
     696             : 
     697           0 :   switch( curve_id ) {
     698             : 
     699           0 :   case FD_VM_SYSCALL_SOL_CURVE_BLS12_381_BE:
     700           0 :   case FD_VM_SYSCALL_SOL_CURVE_BLS12_381_LE: {
     701             : 
     702           0 :     ulong cost = fd_ulong_sat_add( FD_VM_CURVE_BLS12_381_PAIRING_BASE_COST,
     703           0 :       fd_ulong_sat_mul( FD_VM_CURVE_BLS12_381_PAIRING_INCR_COST,
     704           0 :         fd_ulong_sat_sub( num_pairs, 1 ) ) );
     705           0 :     FD_VM_CU_UPDATE( vm, cost );
     706             : 
     707           0 :     ulong total_g1_sz = fd_ulong_sat_mul( FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G1_POINT_SZ, num_pairs );
     708           0 :     uchar const * g1_points = FD_VM_MEM_HADDR_LD( vm, g1_points_addr, FD_VM_ALIGN_RUST_POD_U8_ARRAY, total_g1_sz );
     709             : 
     710           0 :     ulong total_g2_sz = fd_ulong_sat_mul( FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G2_POINT_SZ, num_pairs );
     711           0 :     uchar const * g2_points = FD_VM_MEM_HADDR_LD( vm, g2_points_addr, FD_VM_ALIGN_RUST_POD_U8_ARRAY, total_g2_sz );
     712             : 
     713           0 :     uchar * result = FD_VM_HADDR_QUERY_U8_ARRAY( vm, result_addr, FD_VM_SYSCALL_SOL_CURVE_BLS12_381_GT_ELE_SZ );
     714           0 :     if( FD_LIKELY( fd_bls12_381_pairing_syscall( result, g1_points, g2_points, num_pairs, big_endian )==0 ) ) {
     715           0 :       ret = 0UL; /* success */
     716           0 :     }
     717           0 :   } break;
     718             : 
     719           0 :   default:
     720           0 :     FD_VM_ERR_FOR_LOG_SYSCALL( vm, FD_VM_SYSCALL_ERR_INVALID_ATTRIBUTE );
     721           0 :     return FD_VM_SYSCALL_ERR_INVALID_ATTRIBUTE; /* SyscallError::InvalidAttribute */
     722           0 :   }
     723             : 
     724           0 :   *_ret = ret;
     725           0 :   return FD_VM_SUCCESS;
     726           0 : }
     727             : 
     728             : #endif

Generated by: LCOV version 1.14