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