LCOV - code coverage report
Current view: top level - flamenco/runtime/program - fd_zk_elgamal_proof_program.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 226 240 94.2 %
Date: 2026-03-19 18:19:27 Functions: 3 3 100.0 %

          Line data    Source code
       1             : #include "fd_zk_elgamal_proof_program.h"
       2             : #include "../fd_executor.h"
       3             : #include "../fd_borrowed_account.h"
       4             : #include "../fd_system_ids.h"
       5             : #include "../../log_collector/fd_log_collector.h"
       6             : #include "../../../ballet/zksdk/fd_zksdk.h"
       7             : 
       8             : /* fd_zksdk_process_verify_proof is equivalent to process_verify_proof()
       9             :    and calls specific functions inside zksdk/instructions/ to verify each
      10             :    individual ZKP.
      11             :    https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L35 */
      12             : int
      13         139 : fd_zksdk_process_verify_proof( fd_exec_instr_ctx_t * ctx ) {
      14             :   /* This initial code is Firedancer-only, we just need to initialize variables.
      15             :      Agave code is referenced via comments. */
      16         139 :   int err;
      17         139 :   uchar const * instr_data    = ctx->instr->data;
      18         139 :   ushort        instr_acc_cnt = ctx->instr->acct_cnt;
      19         139 :   uchar         instr_id      = instr_data[0]; /* instr_data_sz already checked by the caller */
      20             : 
      21             :   /* Buffer to store ProofContextStateMeta (header) followed by a proof context
      22             :      (the largest context is for batched_grouped_ciphertext_3_handles_validity). */
      23         139 :   const ulong CTX_META_SZ = sizeof(fd_zksdk_proof_ctx_state_meta_t);
      24         139 :   const ulong MAX_CTX_SZ  = sizeof(fd_zksdk_batched_grp_ciph_3h_val_context_t);
      25         139 :   uchar context_state_data[ CTX_META_SZ+MAX_CTX_SZ ];
      26             : 
      27             :   /* Specific instruction function */
      28         139 :   int (*fd_zksdk_instr_verify_proof)( void const *, void const * ) = NULL;
      29         139 :   switch( instr_id ) {
      30          38 :   case FD_ZKSDK_INSTR_VERIFY_ZERO_CIPHERTEXT:
      31          38 :     fd_zksdk_instr_verify_proof = &fd_zksdk_instr_verify_proof_zero_ciphertext;
      32          38 :     break;
      33          18 :   case FD_ZKSDK_INSTR_VERIFY_CIPHERTEXT_CIPHERTEXT_EQUALITY:
      34          18 :     fd_zksdk_instr_verify_proof = &fd_zksdk_instr_verify_proof_ciphertext_ciphertext_equality;
      35          18 :     break;
      36           6 :   case FD_ZKSDK_INSTR_VERIFY_CIPHERTEXT_COMMITMENT_EQUALITY:
      37           6 :     fd_zksdk_instr_verify_proof = &fd_zksdk_instr_verify_proof_ciphertext_commitment_equality;
      38           6 :     break;
      39           6 :   case FD_ZKSDK_INSTR_VERIFY_PUBKEY_VALIDITY:
      40           6 :     fd_zksdk_instr_verify_proof = &fd_zksdk_instr_verify_proof_pubkey_validity;
      41           6 :     break;
      42          11 :   case FD_ZKSDK_INSTR_VERIFY_PERCENTAGE_WITH_CAP:
      43          11 :     fd_zksdk_instr_verify_proof = &fd_zksdk_instr_verify_proof_percentage_with_cap;
      44          11 :     break;
      45          12 :   case FD_ZKSDK_INSTR_VERIFY_BATCHED_RANGE_PROOF_U64:
      46          12 :     fd_zksdk_instr_verify_proof = &fd_zksdk_instr_verify_proof_batched_range_proof_u64;
      47          12 :     break;
      48          12 :   case FD_ZKSDK_INSTR_VERIFY_BATCHED_RANGE_PROOF_U128:
      49          12 :     fd_zksdk_instr_verify_proof = &fd_zksdk_instr_verify_proof_batched_range_proof_u128;
      50          12 :     break;
      51          12 :   case FD_ZKSDK_INSTR_VERIFY_BATCHED_RANGE_PROOF_U256:
      52          12 :     fd_zksdk_instr_verify_proof = &fd_zksdk_instr_verify_proof_batched_range_proof_u256;
      53          12 :     break;
      54           6 :   case FD_ZKSDK_INSTR_VERIFY_GROUPED_CIPHERTEXT_2_HANDLES_VALIDITY:
      55           6 :     fd_zksdk_instr_verify_proof = &fd_zksdk_instr_verify_proof_grouped_ciphertext_2_handles_validity;
      56           6 :     break;
      57           6 :   case FD_ZKSDK_INSTR_VERIFY_BATCHED_GROUPED_CIPHERTEXT_2_HANDLES_VALIDITY:
      58           6 :     fd_zksdk_instr_verify_proof = &fd_zksdk_instr_verify_proof_batched_grouped_ciphertext_2_handles_validity;
      59           6 :     break;
      60           6 :   case FD_ZKSDK_INSTR_VERIFY_GROUPED_CIPHERTEXT_3_HANDLES_VALIDITY:
      61           6 :     fd_zksdk_instr_verify_proof = &fd_zksdk_instr_verify_proof_grouped_ciphertext_3_handles_validity;
      62           6 :     break;
      63           6 :   case FD_ZKSDK_INSTR_VERIFY_BATCHED_GROUPED_CIPHERTEXT_3_HANDLES_VALIDITY:
      64           6 :     fd_zksdk_instr_verify_proof = &fd_zksdk_instr_verify_proof_batched_grouped_ciphertext_3_handles_validity;
      65           6 :     break;
      66           0 :   default:
      67           0 :     return FD_EXECUTOR_INSTR_ERR_INVALID_INSTR_DATA;
      68         139 :   }
      69             : 
      70             :   /* Note: this check is redundant and can't error out
      71             :      https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L41
      72             :      the caller already does the same:
      73             :      https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L190 */
      74             : 
      75             :   /* https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L45 */
      76         139 :   ushort accessed_accounts = 0U;
      77             : 
      78             :   /* Note: instr_id is guaranteed to be valid, to access values in the arrays. */
      79         139 :   ulong context_sz = fd_zksdk_context_sz[instr_id];
      80         139 :   ulong proof_data_sz = context_sz + fd_zksdk_proof_sz[instr_id];
      81         139 :   uchar const * context = NULL;
      82             : 
      83             :   /* if instruction data is exactly 5 bytes, then read proof from an account
      84             :      https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L48 */
      85         139 :   if( ctx->instr->data_sz == FD_ZKSDK_INSTR_DATA_LENGTH_WITH_PROOF_ACCOUNT ) {
      86             :     /* Case 1. Proof data from account data. */
      87             : 
      88             :     /* Borrow the proof data account.
      89             :        https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L49-L50 */
      90          46 :     fd_guarded_borrowed_account_t proof_data_acc = {0};
      91          46 :     FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, 0UL, &proof_data_acc );
      92             : 
      93             :     /* https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L51 */
      94          45 :     accessed_accounts = 1U;
      95             : 
      96             :     /* https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L53-L64
      97             :        Note: it doesn't look like Agave code can throw any error. */
      98          45 :     uint proof_data_offset = fd_uint_load_4( &instr_data[1] );
      99             : 
     100             :     /* https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L65-L68
     101             :        Note: explcit cast to ulong just to call out that there can't be overflow */
     102          45 :     if( (ulong)proof_data_offset+proof_data_sz > fd_borrowed_account_get_data_len( &proof_data_acc ) ) {
     103           3 :       return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA;
     104           3 :     }
     105             : 
     106             :     /* https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L69-L72
     107             :        Note: this should never fail, the proofs are just bytes, and we tested that the size is valid */
     108          42 :     uchar const * proof_acc_data = fd_borrowed_account_get_data( &proof_data_acc );
     109          42 :     context = &proof_acc_data[proof_data_offset];
     110             : 
     111          93 :   } else {
     112             :     /* Case 2. Proof data from ix data. */
     113             : 
     114             :     /* https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L81-L85
     115             :        Note: instr_id is guaranteed to be valid, to access values in the arrays. */
     116          93 :     if( ctx->instr->data_sz != 1 + proof_data_sz ) {
     117           2 :       fd_log_collector_msg_literal( ctx, "invalid proof data" );
     118           2 :       return FD_EXECUTOR_INSTR_ERR_INVALID_INSTR_DATA;
     119           2 :     }
     120          91 :     context = instr_data + 1;
     121          91 :   }
     122             : 
     123             :   /* Verify individual ZKP
     124             :      https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L74-L77
     125             :      https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L86-L89 */
     126             : 
     127             :   /* TODO: we probably need an extra check to validate the length of sigma proofs,
     128             :      see: https://github.com/solana-program/zk-elgamal-proof/pull/244
     129             :      However this check seems to be redundant for the case of ix data, and
     130             :      seems to be missing only for accounts. It's also unclear what the result should be,
     131             :      need to have explicit tests. */
     132         133 :   void const * proof = context + fd_zksdk_context_sz[instr_id];
     133         133 :   err = (*fd_zksdk_instr_verify_proof)( context, proof );
     134         133 :   if( FD_UNLIKELY( err ) ) {
     135             :     //TODO: full log, including err
     136          54 :     fd_log_collector_msg_literal( ctx, "proof verification failed" );
     137          54 :     return FD_EXECUTOR_INSTR_ERR_INVALID_INSTR_DATA;
     138          54 :   }
     139             : 
     140             :   /* Create context state if we have both proof_context and authority accounts.
     141             :      https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L95-L98 */
     142          79 :   if( instr_acc_cnt >= accessed_accounts + 2U ) {
     143             :     /* Obtain the context_state_authority by borrowing the account temporarily in a local scope.
     144             :        https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L100-L102 */
     145          44 :     fd_pubkey_t context_state_authority[1];
     146          44 :     do {
     147          44 :       fd_guarded_borrowed_account_t _acc = {0};
     148          44 :       FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, (ushort)(accessed_accounts+1), &_acc );
     149          44 :       *context_state_authority = *_acc.pubkey;
     150          44 :     } while(0);
     151             : 
     152             :     /* Borrow the proof context account
     153             :        https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L104-L105 */
     154          44 :     fd_guarded_borrowed_account_t proof_context_acc = {0};
     155          44 :     FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, accessed_accounts, &proof_context_acc );
     156             : 
     157             :     /* https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L107-L109 */
     158          44 :     if( FD_UNLIKELY( !fd_memeq( fd_borrowed_account_get_owner( &proof_context_acc ), &fd_solana_zk_elgamal_proof_program_id, sizeof(fd_pubkey_t) ) ) ) {
     159           4 :       return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_OWNER;
     160           4 :     }
     161             : 
     162             :     /* https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L111-L112 */
     163          40 :     if( FD_UNLIKELY( fd_borrowed_account_get_data_len( &proof_context_acc ) < CTX_META_SZ ) ) {
     164             :       /* https://github.com/solana-program/zk-elgamal-proof/blob/zk-sdk%40v5.0.1/zk-sdk/src/zk_elgamal_proof_program/state.rs#L83 */
     165           2 :       return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA;
     166           2 :     }
     167             : 
     168             :     /* https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L114-L116 */
     169          38 :     if( FD_UNLIKELY( fd_borrowed_account_get_data( &proof_context_acc )[32] != 0 ) ) {
     170           2 :       return FD_EXECUTOR_INSTR_ERR_ACC_ALREADY_INITIALIZED;
     171           2 :     }
     172             : 
     173             :     /* https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L118-L119 */
     174          36 :     fd_memcpy( context_state_data, context_state_authority, sizeof(fd_pubkey_t) ); /* context_state_data[0..31] */
     175          36 :     context_state_data[ 32 ] = instr_id;                                           /* context_state_data[32] */
     176          36 :     fd_memcpy( context_state_data+CTX_META_SZ, context, context_sz );              /* context_state_data[33..] */
     177             : 
     178             :     /* https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L121-L123 */
     179          36 :     ulong context_state_data_sx = CTX_META_SZ + context_sz;
     180          36 :     if( FD_UNLIKELY( fd_borrowed_account_get_data_len( &proof_context_acc ) != context_state_data_sx ) ) {
     181           2 :       return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA;
     182           2 :     }
     183             : 
     184             :     /* https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L125 */
     185          34 :     err = fd_borrowed_account_set_data_from_slice( &proof_context_acc, context_state_data, context_state_data_sx );
     186          34 :     if( FD_UNLIKELY( err ) ) {
     187           1 :       return err;
     188           1 :     }
     189          34 :   }
     190             : 
     191             :   /* https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L126 */
     192          68 :   return FD_EXECUTOR_INSTR_SUCCESS;
     193          79 : }
     194             : 
     195             : /* fd_zksdk_process_close_proof_context is equivalent to process_close_proof_context()
     196             :    https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L131 */
     197             : int
     198           8 : fd_zksdk_process_close_proof_context( fd_exec_instr_ctx_t * ctx ) {
     199           8 : #define ACC_IDX_PROOF (0UL)
     200           8 : #define ACC_IDX_DEST  (1UL)
     201           8 : #define ACC_IDX_OWNER (2UL)
     202           8 :   fd_pubkey_t owner_pubkey[1];
     203           8 :   fd_pubkey_t proof_pubkey[1];
     204           8 :   fd_pubkey_t dest_pubkey[1];
     205             : 
     206             :   /* Note: this check is redundant and can't error out
     207             :      https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L133
     208             :      the caller already does the same:
     209             :      https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L190 */
     210             : 
     211             :   /* Obtain the owner pubkey by borrowing the owner account in local scope.
     212             :      https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L135-L141 */
     213           8 :   do {
     214           8 :     fd_guarded_borrowed_account_t owner_acc = {0};
     215           8 :     int instr_err_code = 0;
     216           8 :     if( FD_UNLIKELY( !fd_instr_acc_is_signer_idx( ctx->instr, ACC_IDX_OWNER, &instr_err_code ) ) ) {
     217           1 :       if( FD_UNLIKELY( !!instr_err_code ) ) return instr_err_code;
     218           1 :       return FD_EXECUTOR_INSTR_ERR_MISSING_REQUIRED_SIGNATURE;
     219           1 :     }
     220             : 
     221           7 :     FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, ACC_IDX_OWNER, &owner_acc );
     222           7 :     *owner_pubkey = *owner_acc.pubkey;
     223             :     /* implicit drop of borrowed owner_acc */
     224           7 :   } while (0);
     225             : 
     226             :   /* Allocate space for borrowed accounts */
     227           7 :   fd_guarded_borrowed_account_t proof_acc = {0};
     228           7 :   fd_guarded_borrowed_account_t dest_acc  = {0};
     229             : 
     230             :   /* Obtain the proof account pubkey by borrowing the proof account.
     231             :      https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L143 */
     232           7 :   FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK(ctx, ACC_IDX_PROOF, &proof_acc );
     233           7 :   *proof_pubkey = *proof_acc.pubkey;
     234           7 :   fd_borrowed_account_drop( &proof_acc );
     235             : 
     236             :   /* Obtain the dest account pubkey by borrowing the dest account.
     237             :      https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L144 */
     238           7 :   FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, ACC_IDX_DEST, &dest_acc );
     239           7 :   *dest_pubkey = *dest_acc.pubkey;
     240           7 :   fd_borrowed_account_drop( &dest_acc );
     241             : 
     242             :   /* https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L145-L147 */
     243           7 :   if( FD_UNLIKELY( fd_memeq( proof_pubkey, dest_pubkey, sizeof(fd_pubkey_t) ) ) ) {
     244           1 :     return FD_EXECUTOR_INSTR_ERR_INVALID_INSTR_DATA;
     245           1 :   }
     246             : 
     247             :   /* Re-borrow the proof account.
     248             :      https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L149 */
     249           6 :   FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK(ctx, ACC_IDX_PROOF, &proof_acc );
     250             : 
     251             :   /* Check that the proof context account is owned by the zk-elgamal-proof program.
     252             :      https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L150-L152 */
     253           6 :   if( FD_UNLIKELY( !fd_memeq( fd_borrowed_account_get_owner( &proof_acc ), &fd_solana_zk_elgamal_proof_program_id, sizeof(fd_pubkey_t) ) ) ) {
     254           1 :     return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_OWNER;
     255           1 :   }
     256             : 
     257             :   /* https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L153-L154
     258             :      Note: data also contains context data, but we only need the initial 33 bytes. */
     259           5 :   if( FD_UNLIKELY( fd_borrowed_account_get_data_len( &proof_acc ) < sizeof(fd_zksdk_proof_ctx_state_meta_t) ) ) {
     260           1 :     return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA;
     261           1 :   }
     262           4 :   fd_zksdk_proof_ctx_state_meta_t const * proof_ctx_state_meta = fd_type_pun_const( fd_borrowed_account_get_data( &proof_acc ) );
     263             : 
     264             :   /* Check that the proof context account is initialized (proof_type != 0).
     265             :      ProofType::Uninitialized = 0
     266             :      https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L155-L157 */
     267           4 :   if( FD_UNLIKELY( proof_ctx_state_meta->proof_type == 0 ) ) {
     268           2 :     return FD_EXECUTOR_INSTR_ERR_UNINITIALIZED_ACCOUNT;
     269           2 :   }
     270             : 
     271             :   /* https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L159 */
     272           2 :   fd_pubkey_t const * expected_owner_addr = (fd_pubkey_t const *)proof_ctx_state_meta->ctx_state_authority;
     273             : 
     274             :   /* https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L161-L163 */
     275           2 :   if( FD_UNLIKELY( !fd_memeq( owner_pubkey, expected_owner_addr, sizeof(fd_pubkey_t) ) ) ) {
     276           1 :     return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_OWNER;
     277           1 :   }
     278             : 
     279             :   /* Re-borrow the dest account.
     280             :      https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L165 */
     281           1 :   FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, ACC_IDX_DEST, &dest_acc );
     282             : 
     283             :   /* https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L166-L169 */
     284           1 :   int err = 0;
     285           1 :   err = fd_borrowed_account_checked_add_lamports( &dest_acc, fd_borrowed_account_get_lamports( &proof_acc ) );
     286           1 :   if( FD_UNLIKELY( err ) ) {
     287           0 :     return err;
     288           0 :   }
     289           1 :   err = fd_borrowed_account_set_lamports( &proof_acc, 0UL );
     290           1 :   if( FD_UNLIKELY( err ) ) {
     291           0 :     return err;
     292           0 :   }
     293           1 :   err = fd_borrowed_account_set_data_length( &proof_acc, 0UL );
     294           1 :   if( FD_UNLIKELY( err ) ) {
     295           0 :     return err;
     296           0 :   }
     297           1 :   err = fd_borrowed_account_set_owner( &proof_acc, &fd_solana_system_program_id );
     298           1 :   if( FD_UNLIKELY( err ) ) {
     299           0 :     return err;
     300           0 :   }
     301             : 
     302             :   /* https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L171 */
     303           1 :   return FD_EXECUTOR_INSTR_SUCCESS;
     304           1 : }
     305             : 
     306             : /*
     307             :  * ZK ElGamal Proof Program
     308             :  */
     309             : 
     310             : /* https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L174 */
     311             : int
     312         266 : fd_executor_zk_elgamal_proof_program_execute( fd_exec_instr_ctx_t * ctx ) {
     313             :   /* https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L175-L187 */
     314         266 :   if( FD_LIKELY(  FD_FEATURE_ACTIVE_BANK( ctx->bank, disable_zk_elgamal_proof_program )
     315         266 :               && !FD_FEATURE_ACTIVE_BANK( ctx->bank, reenable_zk_elgamal_proof_program ) ) ) {
     316          98 :     fd_log_collector_msg_literal( ctx, "zk-elgamal-proof program is temporarily disabled" );
     317          98 :     return FD_EXECUTOR_INSTR_ERR_INVALID_INSTR_DATA;
     318          98 :   }
     319             : 
     320         168 :   uchar const * instr_data    = ctx->instr->data;
     321         168 :   ulong         instr_data_sz = ctx->instr->data_sz;
     322             : 
     323             :   /* https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L189-L193 */
     324         168 :   if( FD_UNLIKELY( instr_data_sz==0UL ) ) {
     325           0 :     return FD_EXECUTOR_INSTR_ERR_INVALID_INSTR_DATA;
     326           0 :   }
     327             : 
     328         168 :   switch( instr_data[0] ) {
     329           9 :   case FD_ZKSDK_INSTR_CLOSE_CONTEXT_STATE:
     330             :     /* https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L196-L202 */
     331           9 :     FD_EXEC_CU_UPDATE( ctx, FD_ZKSDK_INSTR_CLOSE_CONTEXT_STATE_COMPUTE_UNITS );
     332           8 :     fd_log_collector_msg_literal( ctx, "CloseContextState" );
     333           8 :     return fd_zksdk_process_close_proof_context( ctx );
     334             : 
     335          40 :   case FD_ZKSDK_INSTR_VERIFY_ZERO_CIPHERTEXT:
     336             :     /* https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L203-L207 */
     337          40 :     FD_EXEC_CU_UPDATE( ctx, FD_ZKSDK_INSTR_VERIFY_ZERO_CIPHERTEXT_COMPUTE_UNITS );
     338          38 :     fd_log_collector_msg_literal( ctx, "VerifyZeroCiphertext" );
     339          38 :     break;
     340             : 
     341          21 :   case FD_ZKSDK_INSTR_VERIFY_CIPHERTEXT_CIPHERTEXT_EQUALITY:
     342          21 :     FD_EXEC_CU_UPDATE( ctx, FD_ZKSDK_INSTR_VERIFY_CIPHERTEXT_CIPHERTEXT_EQUALITY_COMPUTE_UNITS );
     343          18 :     fd_log_collector_msg_literal( ctx, "VerifyCiphertextCiphertextEquality" );
     344          18 :     break;
     345             : 
     346           7 :   case FD_ZKSDK_INSTR_VERIFY_CIPHERTEXT_COMMITMENT_EQUALITY:
     347           7 :     FD_EXEC_CU_UPDATE( ctx, FD_ZKSDK_INSTR_VERIFY_CIPHERTEXT_COMMITMENT_EQUALITY_COMPUTE_UNITS );
     348           6 :     fd_log_collector_msg_literal( ctx, "VerifyCiphertextCommitmentEquality" );
     349           6 :     break;
     350             : 
     351           7 :   case FD_ZKSDK_INSTR_VERIFY_PUBKEY_VALIDITY:
     352           7 :     FD_EXEC_CU_UPDATE( ctx, FD_ZKSDK_INSTR_VERIFY_PUBKEY_VALIDITY_COMPUTE_UNITS );
     353           6 :     fd_log_collector_msg_literal( ctx, "VerifyPubkeyValidity" );
     354           6 :     break;
     355             : 
     356          13 :   case FD_ZKSDK_INSTR_VERIFY_PERCENTAGE_WITH_CAP:
     357          13 :     FD_EXEC_CU_UPDATE( ctx, FD_ZKSDK_INSTR_VERIFY_PERCENTAGE_WITH_CAP_COMPUTE_UNITS );
     358          11 :     fd_log_collector_msg_literal( ctx, "VerifyPercentageWithCap" );
     359          11 :     break;
     360             : 
     361          14 :   case FD_ZKSDK_INSTR_VERIFY_BATCHED_RANGE_PROOF_U64:
     362          14 :     FD_EXEC_CU_UPDATE( ctx, FD_ZKSDK_INSTR_VERIFY_BATCHED_RANGE_PROOF_U64_COMPUTE_UNITS );
     363          12 :     fd_log_collector_msg_literal( ctx, "VerifyBatchedRangeProofU64" );
     364          12 :     break;
     365             : 
     366          14 :   case FD_ZKSDK_INSTR_VERIFY_BATCHED_RANGE_PROOF_U128:
     367          14 :     FD_EXEC_CU_UPDATE( ctx, FD_ZKSDK_INSTR_VERIFY_BATCHED_RANGE_PROOF_U128_COMPUTE_UNITS );
     368          12 :     fd_log_collector_msg_literal( ctx, "VerifyBatchedRangeProofU128" );
     369          12 :     break;
     370             : 
     371          14 :   case FD_ZKSDK_INSTR_VERIFY_BATCHED_RANGE_PROOF_U256:
     372          14 :     FD_EXEC_CU_UPDATE( ctx, FD_ZKSDK_INSTR_VERIFY_BATCHED_RANGE_PROOF_U256_COMPUTE_UNITS );
     373          12 :     fd_log_collector_msg_literal( ctx, "VerifyBatchedRangeProofU256" );
     374          12 :     break;
     375             : 
     376           7 :   case FD_ZKSDK_INSTR_VERIFY_GROUPED_CIPHERTEXT_2_HANDLES_VALIDITY:
     377           7 :     FD_EXEC_CU_UPDATE( ctx, FD_ZKSDK_INSTR_VERIFY_GROUPED_CIPHERTEXT_2_HANDLES_VALIDITY_COMPUTE_UNITS );
     378           6 :     fd_log_collector_msg_literal( ctx, "VerifyGroupedCiphertext2HandlesValidity" );
     379           6 :     break;
     380             : 
     381           7 :   case FD_ZKSDK_INSTR_VERIFY_BATCHED_GROUPED_CIPHERTEXT_2_HANDLES_VALIDITY:
     382           7 :     FD_EXEC_CU_UPDATE( ctx, FD_ZKSDK_INSTR_VERIFY_BATCHED_GROUPED_CIPHERTEXT_2_HANDLES_VALIDITY_COMPUTE_UNITS );
     383           6 :     fd_log_collector_msg_literal( ctx, "VerifyBatchedGroupedCiphertext2HandlesValidity" );
     384           6 :     break;
     385             : 
     386           7 :   case FD_ZKSDK_INSTR_VERIFY_GROUPED_CIPHERTEXT_3_HANDLES_VALIDITY:
     387           7 :     FD_EXEC_CU_UPDATE( ctx, FD_ZKSDK_INSTR_VERIFY_GROUPED_CIPHERTEXT_3_HANDLES_VALIDITY_COMPUTE_UNITS );
     388           6 :     fd_log_collector_msg_literal( ctx, "VerifyGroupedCiphertext3HandlesValidity" );
     389           6 :     break;
     390             : 
     391           7 :   case FD_ZKSDK_INSTR_VERIFY_BATCHED_GROUPED_CIPHERTEXT_3_HANDLES_VALIDITY:
     392           7 :     FD_EXEC_CU_UPDATE( ctx, FD_ZKSDK_INSTR_VERIFY_BATCHED_GROUPED_CIPHERTEXT_3_HANDLES_VALIDITY_COMPUTE_UNITS );
     393           6 :     fd_log_collector_msg_literal( ctx, "VerifyBatchedGroupedCiphertext3HandlesValidity" );
     394           6 :     break;
     395             : 
     396           0 :   default:
     397             :     /* Invalid instruction discriminator.
     398             :        https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L192-L193 */
     399           0 :     return FD_EXECUTOR_INSTR_ERR_INVALID_INSTR_DATA;
     400         168 :   }
     401             : 
     402             :   /* All verify instructions call process_verify_proof.
     403             :      https://github.com/anza-xyz/agave/blob/v4.0.0-alpha.0/programs/zk-elgamal-proof/src/lib.rs#L208-L210 (and similar for each instruction) */
     404         139 :   return fd_zksdk_process_verify_proof( ctx );
     405         168 : }

Generated by: LCOV version 1.14