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 : }
|