LCOV - code coverage report
Current view: top level - flamenco/vm/syscall - fd_vm_syscall_crypto.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 227 0.0 %
Date: 2025-12-06 04:45:29 Functions: 0 4 0.0 %

          Line data    Source code
       1             : #include "fd_vm_syscall.h"
       2             : 
       3             : #include "../../../ballet/bn254/fd_bn254.h"
       4             : #include "../../../ballet/bn254/fd_poseidon.h"
       5             : #include "../../../ballet/secp256k1/fd_secp256k1.h"
       6             : #include "../../runtime/fd_bank.h"
       7             : 
       8             : int
       9             : fd_vm_syscall_sol_alt_bn128_group_op( void *  _vm,
      10             :                                       ulong   group_op,
      11             :                                       ulong   input_addr,
      12             :                                       ulong   input_sz,
      13             :                                       ulong   result_addr,
      14             :                                       FD_PARAM_UNUSED ulong r5,
      15           0 :                                       ulong * _ret ) {
      16             :   /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1509 */
      17           0 :   fd_vm_t * vm  = (fd_vm_t *)_vm;
      18           0 :   ulong     ret = 1UL; /* by default return Ok(1) == error */
      19             : 
      20             :   /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1520-L1549 */
      21           0 :   ulong cost = 0UL;
      22           0 :   ulong output_sz = 0UL;
      23           0 :   switch( group_op ) {
      24             : 
      25           0 :   case FD_VM_SYSCALL_SOL_ALT_BN128_ADD:
      26           0 :     output_sz = FD_VM_SYSCALL_SOL_ALT_BN128_G1_SZ;
      27           0 :     cost = FD_VM_ALT_BN128_ADDITION_COST;
      28           0 :     break;
      29             : 
      30           0 :   case FD_VM_SYSCALL_SOL_ALT_BN128_MUL:
      31           0 :     output_sz = FD_VM_SYSCALL_SOL_ALT_BN128_G1_SZ;
      32           0 :     cost = FD_VM_ALT_BN128_MULTIPLICATION_COST;
      33           0 :     break;
      34             : 
      35           0 :   case FD_VM_SYSCALL_SOL_ALT_BN128_PAIRING:
      36           0 :     output_sz = FD_VM_SYSCALL_SOL_ALT_BN128_PAIRING_OUTPUT_SZ;
      37           0 :     ulong elements_len = input_sz / FD_VM_SYSCALL_SOL_ALT_BN128_PAIRING_INPUT_EL_SZ;
      38           0 :     cost = FD_VM_ALT_BN128_PAIRING_ONE_PAIR_COST_FIRST
      39           0 :       + FD_VM_SHA256_BASE_COST
      40           0 :       + FD_VM_SYSCALL_SOL_ALT_BN128_PAIRING_OUTPUT_SZ;
      41           0 :     cost = fd_ulong_sat_add( cost,
      42           0 :       fd_ulong_sat_mul( FD_VM_ALT_BN128_PAIRING_ONE_PAIR_COST_OTHER,
      43           0 :         fd_ulong_sat_sub( elements_len, 1 ) ) );
      44           0 :     cost = fd_ulong_sat_add( cost, input_sz );
      45           0 :     break;
      46             : 
      47           0 :   default:
      48           0 :     FD_VM_ERR_FOR_LOG_SYSCALL( vm, FD_VM_SYSCALL_ERR_INVALID_ATTRIBUTE );
      49           0 :     return FD_VM_SYSCALL_ERR_INVALID_ATTRIBUTE; /* SyscallError::InvalidAttribute */
      50           0 :   }
      51             : 
      52             :   /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1551 */
      53             : 
      54           0 :   FD_VM_CU_UPDATE( vm, cost );
      55             : 
      56             :   /* https://github.com/anza-xyz/agave/blob/v2.3.1/programs/bpf_loader/src/syscalls/mod.rs#L1660-L1664 */
      57             : 
      58           0 :   fd_vm_haddr_query_t call_result_query = {
      59           0 :     .vaddr    = result_addr,
      60           0 :     .align    = FD_VM_ALIGN_RUST_U8,
      61           0 :     .sz       = output_sz,
      62           0 :     .is_slice = 1,
      63           0 :   };
      64             : 
      65           0 :   fd_vm_haddr_query_t * queries[] = { &call_result_query };
      66           0 :   FD_VM_TRANSLATE_MUT( vm, queries );
      67             : 
      68           0 :   uchar * call_result = call_result_query.haddr;
      69           0 :   uchar const * input = FD_VM_MEM_SLICE_HADDR_LD( vm, input_addr,  FD_VM_ALIGN_RUST_U8, input_sz );
      70             : 
      71             :   /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1567-L1598
      72             :      Note: this implementation is post SIMD-0129, we only support the simplified error codes. */
      73           0 :   switch( group_op ) {
      74             : 
      75           0 :   case FD_VM_SYSCALL_SOL_ALT_BN128_ADD:
      76             :     /* Compute add */
      77           0 :     if( FD_LIKELY( fd_bn254_g1_add_syscall( call_result, input, input_sz )==0 ) ) {
      78           0 :       ret = 0UL; /* success */
      79           0 :     }
      80           0 :     break;
      81             : 
      82           0 :   case FD_VM_SYSCALL_SOL_ALT_BN128_MUL:
      83             :     /* Compute scalar mul */
      84           0 :     if( FD_LIKELY( fd_bn254_g1_scalar_mul_syscall( call_result, input, input_sz,
      85           0 :                                                    FD_FEATURE_ACTIVE_BANK( vm->instr_ctx->bank, fix_alt_bn128_multiplication_input_length ) )==0 ) ) {
      86           0 :       ret = 0UL; /* success */
      87           0 :     }
      88           0 :     break;
      89             : 
      90           0 :   case FD_VM_SYSCALL_SOL_ALT_BN128_PAIRING:
      91             :     /* Compute pairing with length check based on feature gate.
      92             :        https://github.com/anza-xyz/solana-sdk/blob/bn254%40v3.1.2/bn254/src/pairing.rs#L76-L82 */
      93           0 :     if( FD_LIKELY( fd_bn254_pairing_is_one_syscall( call_result, input, input_sz,
      94           0 :                                                     FD_FEATURE_ACTIVE_BANK( vm->instr_ctx->bank, fix_alt_bn128_pairing_length_check ) )==0 ) ) {
      95           0 :       ret = 0UL; /* success */
      96           0 :     }
      97           0 :     break;
      98           0 :   }
      99             : 
     100           0 :   *_ret = ret;
     101           0 :   return FD_VM_SUCCESS; /* Ok(SUCCESS) or Ok(ERROR) */
     102           0 : }
     103             : 
     104             : int
     105             : fd_vm_syscall_sol_alt_bn128_compression( void *  _vm,
     106             :                                          ulong   op,
     107             :                                          ulong   input_addr,
     108             :                                          ulong   input_sz,
     109             :                                          ulong   result_addr,
     110             :                                          FD_PARAM_UNUSED ulong r5,
     111           0 :                                          ulong * _ret ) {
     112             :   /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1776 */
     113           0 :   fd_vm_t * vm  = (fd_vm_t *)_vm;
     114           0 :   ulong     ret = 1UL; /* by default return Ok(1) == error */
     115             : 
     116             :   /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1791-L1811 */
     117           0 :   ulong cost = 0UL;
     118           0 :   ulong output_sz = 0UL;
     119           0 :   switch( op ) {
     120             : 
     121           0 :   case FD_VM_SYSCALL_SOL_ALT_BN128_G1_COMPRESS:
     122           0 :     output_sz = FD_VM_SYSCALL_SOL_ALT_BN128_G1_COMPRESSED_SZ;
     123           0 :     cost = FD_VM_ALT_BN128_G1_COMPRESS;
     124           0 :     break;
     125             : 
     126           0 :   case FD_VM_SYSCALL_SOL_ALT_BN128_G1_DECOMPRESS:
     127           0 :     output_sz = FD_VM_SYSCALL_SOL_ALT_BN128_G1_SZ;
     128           0 :     cost = FD_VM_ALT_BN128_G1_DECOMPRESS;
     129           0 :     break;
     130             : 
     131           0 :   case FD_VM_SYSCALL_SOL_ALT_BN128_G2_COMPRESS:
     132           0 :     output_sz = FD_VM_SYSCALL_SOL_ALT_BN128_G2_COMPRESSED_SZ;
     133           0 :     cost = FD_VM_ALT_BN128_G2_COMPRESS;
     134           0 :     break;
     135             : 
     136           0 :   case FD_VM_SYSCALL_SOL_ALT_BN128_G2_DECOMPRESS:
     137           0 :     output_sz = FD_VM_SYSCALL_SOL_ALT_BN128_G2_SZ;
     138           0 :     cost = FD_VM_ALT_BN128_G2_DECOMPRESS;
     139           0 :     break;
     140             : 
     141           0 :   default:
     142           0 :     FD_VM_ERR_FOR_LOG_SYSCALL( vm, FD_VM_SYSCALL_ERR_INVALID_ATTRIBUTE );
     143           0 :     return FD_VM_SYSCALL_ERR_INVALID_ATTRIBUTE; /* SyscallError::InvalidAttribute */
     144           0 :   }
     145           0 :   cost = fd_ulong_sat_add( cost, FD_VM_SYSCALL_BASE_COST );
     146             : 
     147             :   /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1813 */
     148             : 
     149           0 :   FD_VM_CU_UPDATE( vm, cost );
     150             : 
     151             :   /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1815-L1827 */
     152             : 
     153           0 :   fd_vm_haddr_query_t call_result_query = {
     154           0 :     .vaddr    = result_addr,
     155           0 :     .align    = FD_VM_ALIGN_RUST_U8,
     156           0 :     .sz       = output_sz,
     157           0 :     .is_slice = 1,
     158           0 :   };
     159             : 
     160           0 :   fd_vm_haddr_query_t * queries[] = { &call_result_query };
     161           0 :   FD_VM_TRANSLATE_MUT( vm, queries );
     162             : 
     163           0 :   uchar * call_result = call_result_query.haddr;
     164           0 :   void const * input  = FD_VM_MEM_SLICE_HADDR_LD( vm, input_addr,  FD_VM_ALIGN_RUST_U8, input_sz );
     165             : 
     166             :   /* input and call_result may alias.  Therefore, buffer via out_buf */
     167           0 :   uchar out_buf[128];
     168             : 
     169             :   /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1829-L1891
     170             :      Note: this implementation is post SIMD-0129, we only support the simplified error codes. */
     171           0 :   switch( op ) {
     172             : 
     173           0 :   case FD_VM_SYSCALL_SOL_ALT_BN128_G1_COMPRESS:
     174           0 :     if( FD_UNLIKELY( input_sz!=FD_VM_SYSCALL_SOL_ALT_BN128_G1_SZ ) ) {
     175           0 :       goto soft_error;
     176           0 :     }
     177           0 :     if( FD_LIKELY( fd_bn254_g1_compress( out_buf, fd_type_pun_const(input) ) ) ) {
     178           0 :       fd_memcpy( call_result, out_buf, FD_VM_SYSCALL_SOL_ALT_BN128_G1_COMPRESSED_SZ );
     179           0 :       ret = 0UL; /* success */
     180           0 :     }
     181           0 :     break;
     182             : 
     183           0 :   case FD_VM_SYSCALL_SOL_ALT_BN128_G1_DECOMPRESS:
     184           0 :     if( FD_UNLIKELY( input_sz!=FD_VM_SYSCALL_SOL_ALT_BN128_G1_COMPRESSED_SZ ) ) {
     185           0 :       goto soft_error;
     186           0 :     }
     187           0 :     if( FD_LIKELY( fd_bn254_g1_decompress( out_buf, fd_type_pun_const(input) ) ) ) {
     188           0 :       fd_memcpy( call_result, out_buf, FD_VM_SYSCALL_SOL_ALT_BN128_G1_SZ );
     189           0 :       ret = 0UL; /* success */
     190           0 :     }
     191           0 :     break;
     192             : 
     193           0 :   case FD_VM_SYSCALL_SOL_ALT_BN128_G2_COMPRESS:
     194           0 :     if( FD_UNLIKELY( input_sz!=FD_VM_SYSCALL_SOL_ALT_BN128_G2_SZ ) ) {
     195           0 :       goto soft_error;
     196           0 :     }
     197           0 :     if( FD_LIKELY( fd_bn254_g2_compress( out_buf, fd_type_pun_const(input) ) ) ) {
     198           0 :       fd_memcpy( call_result, out_buf, FD_VM_SYSCALL_SOL_ALT_BN128_G2_COMPRESSED_SZ );
     199           0 :       ret = 0UL; /* success */
     200           0 :     }
     201           0 :     break;
     202             : 
     203           0 :   case FD_VM_SYSCALL_SOL_ALT_BN128_G2_DECOMPRESS:
     204           0 :     if( FD_UNLIKELY( input_sz!=FD_VM_SYSCALL_SOL_ALT_BN128_G2_COMPRESSED_SZ ) ) {
     205           0 :       goto soft_error;
     206           0 :     }
     207           0 :     if( FD_LIKELY( fd_bn254_g2_decompress( out_buf, fd_type_pun_const(input) ) ) ) {
     208           0 :       fd_memcpy( call_result, out_buf, FD_VM_SYSCALL_SOL_ALT_BN128_G2_SZ );
     209           0 :       ret = 0UL; /* success */
     210           0 :     }
     211           0 :     break;
     212           0 :   }
     213             : 
     214           0 : soft_error:
     215           0 :   *_ret = ret;
     216           0 :   return FD_VM_SUCCESS; /* Ok(SUCCESS) or Ok(ERROR) */
     217           0 : }
     218             : 
     219             : int
     220             : fd_vm_syscall_sol_poseidon( void *  _vm,
     221             :                             ulong   params,
     222             :                             ulong   endianness,
     223             :                             ulong   vals_addr,
     224             :                             ulong   vals_len,
     225             :                             ulong   result_addr,
     226           0 :                             ulong * _ret ) {
     227             :   /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1678 */
     228           0 :   fd_vm_t * vm  = (fd_vm_t *)_vm;
     229           0 :   ulong     ret = 1UL; /* by default return Ok(1) == error */
     230             : 
     231             :   /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1688 */
     232             : 
     233           0 :   if( FD_UNLIKELY( params!=0UL ) ) {
     234           0 :     FD_VM_ERR_FOR_LOG_SYSCALL( vm, FD_VM_SYSCALL_ERR_POSEIDON_INVALID_PARAMS );
     235           0 :     return FD_VM_SYSCALL_ERR_POSEIDON_INVALID_PARAMS; /* PoseidonSyscallError::InvalidParameters */
     236           0 :   }
     237             : 
     238             :   /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1689 */
     239             : 
     240           0 :   if( FD_UNLIKELY(
     241           0 :        endianness!=0UL /* Big endian */
     242           0 :     && endianness!=1UL /* Little endian */
     243           0 :   ) ) {
     244           0 :     FD_VM_ERR_FOR_LOG_SYSCALL( vm, FD_VM_SYSCALL_ERR_POSEIDON_INVALID_ENDIANNESS );
     245           0 :     return FD_VM_SYSCALL_ERR_POSEIDON_INVALID_ENDIANNESS; /* PoseidonSyscallError::InvalidEndianness */
     246           0 :   }
     247             : 
     248             :   /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1691-L1698 */
     249             : 
     250           0 :   if( FD_UNLIKELY( vals_len > FD_VM_SYSCALL_SOL_POSEIDON_MAX_VALS ) ) {
     251             :     /* Max msg_sz = 47 - 3 + 20 = 64 < 127 => we can use printf */
     252           0 :     fd_log_collector_printf_dangerous_max_127( vm->instr_ctx,
     253           0 :       "Poseidon hashing %lu sequences is not supported", vals_len );
     254           0 :     FD_VM_ERR_FOR_LOG_SYSCALL( vm, FD_VM_SYSCALL_ERR_INVALID_LENGTH );
     255           0 :     return FD_VM_SYSCALL_ERR_INVALID_LENGTH; /* SyscallError::InvalidLength */
     256           0 :   }
     257             : 
     258             :   /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1700-L1707
     259             :      poseidon_cost(): https://github.com/solana-labs/solana/blob/v1.18.12/program-runtime/src/compute_budget.rs#L211 */
     260             : 
     261             :   /* vals_len^2 * A + C */
     262           0 :   ulong cost = fd_ulong_sat_add(
     263           0 :     fd_ulong_sat_mul(
     264           0 :       fd_ulong_sat_mul( vals_len, vals_len ),
     265           0 :       FD_VM_POSEIDON_COST_COEFFICIENT_A
     266           0 :     ),
     267           0 :     FD_VM_POSEIDON_COST_COEFFICIENT_C
     268           0 :   );
     269             : 
     270             :   /* The following can never happen, left as comment for completeness.
     271             :      if( FD_UNLIKELY( cost == ULONG_MAX ) ) {
     272             :        fd_vm_log_append_printf( vm, "Overflow while calculating the compute cost" );
     273             :        return FD_VM_SYSCALL_ERR_ARITHMETIC_OVERFLOW; // SyscallError::ArithmeticOverflow
     274             :      }
     275             :   */
     276             : 
     277             :   /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1708 */
     278             : 
     279           0 :   FD_VM_CU_UPDATE( vm, cost );
     280             : 
     281             :   /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1710-L1715 */
     282             : 
     283           0 :   fd_vm_haddr_query_t hash_result_query = {
     284           0 :     .vaddr    = result_addr,
     285           0 :     .align    = FD_VM_ALIGN_RUST_U8,
     286           0 :     .sz       = 32UL,
     287           0 :     .is_slice = 1,
     288           0 :   };
     289             : 
     290           0 :   fd_vm_haddr_query_t * queries[] = { &hash_result_query };
     291           0 :   FD_VM_TRANSLATE_MUT( vm, queries );
     292             : 
     293             :   /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1716-L1732 */
     294             : 
     295             :   /* Agave allocates a vector of translated slices (that can return a fatal
     296             :      error), and then computes Poseidon, returning a soft error in case of
     297             :      issues (e.g. invalid input).
     298             : 
     299             :      We must be careful in returning the correct fatal vs soft error.
     300             : 
     301             :      The special case of vals_len==0 returns Ok(1), so for simplicity
     302             :      we capture it explicitly. */
     303             : 
     304           0 :   if( FD_UNLIKELY( !vals_len ) ) {
     305           0 :     goto soft_error;
     306           0 :   }
     307             : 
     308             :   /* First loop to memory map. This can return a fatal error. */
     309           0 :   fd_vm_vec_t const * input_vec_haddr = (fd_vm_vec_t const *)FD_VM_MEM_HADDR_LD( vm, vals_addr, FD_VM_VEC_ALIGN, vals_len*sizeof(fd_vm_vec_t) );
     310           0 :   void const * inputs_haddr[ FD_VM_SYSCALL_SOL_POSEIDON_MAX_VALS ];
     311           0 :   for( ulong i=0UL; i<vals_len; i++ ) {
     312           0 :     inputs_haddr[i] = FD_VM_MEM_SLICE_HADDR_LD( vm, input_vec_haddr[i].addr, FD_VM_ALIGN_RUST_U8, input_vec_haddr[i].len );
     313           0 :   }
     314             : 
     315             :   /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1734-L1750
     316             :      Note: this implementation is post SIMD-0129, we only support the simplified error codes. */
     317             : 
     318             :   /* Second loop to computed Poseidon. This can return a soft error. */
     319           0 :   int big_endian = endianness==0;
     320           0 :   int enforce_padding = FD_FEATURE_ACTIVE_BANK( vm->instr_ctx->bank, poseidon_enforce_padding );
     321           0 :   fd_poseidon_t pos[1];
     322           0 :   fd_poseidon_init( pos, big_endian );
     323             : 
     324           0 :   for( ulong i=0UL; i<vals_len; i++ ) {
     325           0 :     if( FD_UNLIKELY( fd_poseidon_append( pos, inputs_haddr[ i ], input_vec_haddr[i].len, enforce_padding )==NULL ) ) {
     326           0 :       goto soft_error;
     327           0 :     }
     328           0 :   }
     329             : 
     330           0 :   ret = !fd_poseidon_fini( pos, hash_result_query.haddr );
     331             : 
     332           0 : soft_error:
     333           0 :   *_ret = ret;
     334           0 :   return FD_VM_SUCCESS; /* Ok(1) == error */
     335           0 : }
     336             : 
     337             : int
     338             : fd_vm_syscall_sol_secp256k1_recover( /**/            void *  _vm,
     339             :                                      /**/            ulong   hash_vaddr,
     340             :                                      /**/            ulong   recovery_id_val,
     341             :                                      /**/            ulong   signature_vaddr,
     342             :                                      /**/            ulong   result_vaddr,
     343             :                                      FD_PARAM_UNUSED ulong   r5,
     344           0 :                                      /**/            ulong * _ret ) {
     345             :   /* https://github.com/anza-xyz/agave/blob/v1.18.8/programs/bpf_loader/src/syscalls/mod.rs#L810 */
     346           0 :   fd_vm_t * vm = (fd_vm_t *)_vm;
     347             : 
     348             :   /* https://github.com/anza-xyz/agave/blob/v1.18.8/programs/bpf_loader/src/syscalls/mod.rs#L820-L821 */
     349             : 
     350           0 :   FD_VM_CU_UPDATE( vm, FD_VM_SECP256K1_RECOVER_COST );
     351             : 
     352             :   /* https://github.com/anza-xyz/agave/blob/v2.3.1/programs/bpf_loader/src/syscalls/mod.rs#L952-L956 */
     353           0 :   fd_vm_haddr_query_t pubkey_result_query = {
     354           0 :     .vaddr    = result_vaddr,
     355           0 :     .align    = FD_VM_ALIGN_RUST_U8,
     356           0 :     .sz       = 64UL,
     357           0 :     .is_slice = 1,
     358           0 :   };
     359             : 
     360           0 :   fd_vm_haddr_query_t * queries[] = { &pubkey_result_query };
     361           0 :   FD_VM_TRANSLATE_MUT( vm, queries );
     362             : 
     363             :   /* https://github.com/anza-xyz/agave/blob/v2.3.1/programs/bpf_loader/src/syscalls/mod.rs#L957-L968 */
     364             : 
     365           0 :   uchar const * hash = FD_VM_MEM_HADDR_LD( vm, hash_vaddr,      FD_VM_ALIGN_RUST_U8, 32UL );
     366           0 :   uchar const * sig  = FD_VM_MEM_HADDR_LD( vm, signature_vaddr, FD_VM_ALIGN_RUST_U8, 64UL );
     367             : 
     368             :   /* CRITICAL */
     369             : 
     370             :   /* https://github.com/anza-xyz/agave/blob/v1.18.8/programs/bpf_loader/src/syscalls/mod.rs#L842-L853 */
     371             : 
     372             :   /* Secp256k1RecoverError::InvalidHash
     373             :      This can never happen, as `libsecp256k1::Message::parse_slice(hash)`
     374             :      only checks that hash is 32-byte long, and that's by construction.
     375             :      https://github.com/paritytech/libsecp256k1/blob/v0.6.0/src/lib.rs#L657-L665
     376             : 
     377             :      if( FD_UNLIKELY( 0 ) ) {
     378             :        *_ret = 1UL; // Secp256k1RecoverError::InvalidHash
     379             :        return FD_VM_SUCCESS;
     380             :      }
     381             :    */
     382             : 
     383             :   /* Secp256k1RecoverError::InvalidRecoveryId
     384             :      Agave code has 2 checks: the first is a cast from u64 to u8.
     385             :      The second is `libsecp256k1::RecoveryId::parse(adjusted_recover_id_val)` that
     386             :      checks if `adjusted_recover_id_val < 4`.
     387             :      https://github.com/paritytech/libsecp256k1/blob/v0.6.0/src/lib.rs#L674-L680
     388             :   */
     389             : 
     390           0 :   if( FD_UNLIKELY( recovery_id_val >= 4UL ) ) {
     391           0 :     *_ret = 2UL; /* Secp256k1RecoverError::InvalidRecoveryId */
     392           0 :     return FD_VM_SUCCESS;
     393           0 :   }
     394             : 
     395             :   /* Secp256k1RecoverError::InvalidSignature
     396             :      We omit this check, as this is done as part of fd_secp256k1_recover() below,
     397             :      and the return code is the same.
     398             : 
     399             :      In more details, this checks that the signature is valid, i.e. if the
     400             :      signature is represented as two scalars (r, s), it checks that both r
     401             :      and s are canonical scalars.
     402             : 
     403             :      Note the `?` at the end of this line:
     404             :      https://github.com/paritytech/libsecp256k1/blob/v0.6.0/src/lib.rs#L535
     405             :      And following the code, `scalar::check_overflow` is checks that the scalar is valid:
     406             :      https://github.com/paritytech/libsecp256k1/blob/master/core/src/scalar.rs#L70-L87 */
     407             : 
     408             :   /* https://github.com/anza-xyz/agave/blob/v1.18.8/programs/bpf_loader/src/syscalls/mod.rs#L855-L860 */
     409             : 
     410           0 :   uchar secp256k1_pubkey[64];
     411           0 :   if( FD_UNLIKELY( !fd_secp256k1_recover( secp256k1_pubkey, hash, sig, (int)recovery_id_val ) ) ) {
     412           0 :     *_ret = 3UL; /* Secp256k1RecoverError::InvalidSignature */
     413           0 :     return FD_VM_SUCCESS;
     414           0 :   }
     415             : 
     416           0 :   memcpy( pubkey_result_query.haddr, secp256k1_pubkey, 64UL );
     417             : 
     418           0 :   *_ret = 0UL;
     419           0 :   return FD_VM_SUCCESS;
     420           0 : }

Generated by: LCOV version 1.14