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

Generated by: LCOV version 1.14