Line data Source code
1 : #include "../fd_zksdk_private.h" 2 : 3 : /* https://github.com/solana-program/zk-elgamal-proof/blob/zk-sdk%40v5.0.1/zk-sdk/src/sigma_proofs/pubkey_validity.rs#L128 */ 4 : static inline void 5 : pubkey_validity_hash_context( fd_zksdk_transcript_t * transcript, 6 6 : uchar const pubkey[ 32 ] ) { 7 6 : fd_zksdk_transcript_append_pubkey( transcript, FD_TRANSCRIPT_LITERAL("pubkey"), pubkey ); 8 6 : } 9 : 10 : /* https://github.com/solana-program/zk-elgamal-proof/blob/zk-sdk%40v5.0.1/zk-sdk/src/sigma_proofs/pubkey_validity.rs#L91 */ 11 : static inline int 12 : fd_zksdk_verify_proof_pubkey_validity( 13 : fd_zksdk_pubkey_validity_proof_t const * proof, 14 : uchar const pubkey[ 32 ], 15 6 : fd_zksdk_transcript_t * transcript ) { 16 : /* 17 : We need to verify the following equivalence: 18 : z H =?= c P + Y 19 : or: 20 : Y =?= z H - c P 21 : */ 22 : 23 : /* Validate all inputs */ 24 6 : uchar scalars[ 2 * 32 ]; 25 6 : fd_ristretto255_point_t points[2]; 26 6 : fd_ristretto255_point_t y[1]; 27 6 : fd_ristretto255_point_t res[1]; 28 : 29 : /* https://github.com/solana-program/zk-elgamal-proof/blob/zk-sdk%40v5.0.1/zk-sdk/src/sigma_proofs/pubkey_validity.rs#L96-L97 */ 30 6 : pubkey_validity_hash_context( transcript, pubkey ); 31 6 : fd_zksdk_transcript_domsep_pubkey_proof( transcript ); 32 : 33 : /* https://github.com/solana-program/zk-elgamal-proof/blob/zk-sdk%40v5.0.1/zk-sdk/src/sigma_proofs/pubkey_validity.rs#L102-L104 */ 34 6 : if( FD_UNLIKELY( fd_memeq( pubkey, fd_ristretto255_compressed_zero, 32 ) ) ) { 35 0 : return FD_ZKSDK_VERIFY_PROOF_ERROR; 36 0 : } 37 : 38 : /* Validate scalar and decompress all points. 39 : Note: Agave does this in various places, but any failure simply results in an invalid proof. */ 40 6 : if( FD_UNLIKELY( fd_curve25519_scalar_validate( proof->z )==NULL ) ) { 41 0 : return FD_ZKSDK_VERIFY_PROOF_ERROR; 42 0 : } 43 : 44 6 : fd_ristretto255_point_set( &points[0], fd_zksdk_basepoint_H ); 45 6 : if( FD_UNLIKELY( fd_ristretto255_point_decompress( &points[1], pubkey )==NULL ) ) { 46 1 : return FD_ZKSDK_VERIFY_PROOF_ERROR; 47 1 : } 48 5 : if( FD_UNLIKELY( fd_ristretto255_point_decompress( y, proof->y )==NULL ) ) { 49 0 : return FD_ZKSDK_VERIFY_PROOF_ERROR; 50 0 : } 51 : 52 : /* Finalize transcript and extract challenges 53 : https://github.com/solana-program/zk-elgamal-proof/blob/zk-sdk%40v5.0.1/zk-sdk/src/sigma_proofs/pubkey_validity.rs#L107-L108 */ 54 5 : int val = FD_TRANSCRIPT_SUCCESS; 55 5 : val |= fd_zksdk_transcript_validate_and_append_point( transcript, FD_TRANSCRIPT_LITERAL("Y"), proof->y); 56 5 : if( FD_UNLIKELY( val != FD_TRANSCRIPT_SUCCESS ) ) { 57 0 : return FD_ZKSDK_VERIFY_PROOF_ERROR; 58 0 : } 59 : 60 5 : uchar c[ 32 ]; 61 5 : fd_zksdk_transcript_challenge_scalar( c, transcript, FD_TRANSCRIPT_LITERAL("c") ); 62 : 63 : /* https://github.com/solana-program/zk-elgamal-proof/blob/zk-sdk%40v5.0.1/zk-sdk/src/sigma_proofs/pubkey_validity.rs#L111-L119 64 : Note: we use a slightly different MSM but they're equivalent. */ 65 : 66 : /* Compute scalars */ 67 5 : fd_curve25519_scalar_set( &scalars[ 0*32 ], proof->z ); // z 68 5 : fd_curve25519_scalar_neg( &scalars[ 1*32 ], c ); // -c 69 : 70 : /* Compute the final MSM */ 71 5 : fd_ristretto255_multi_scalar_mul( res, scalars, points, 2 ); 72 : 73 : /* https://github.com/solana-program/zk-elgamal-proof/blob/zk-sdk%40v5.0.1/zk-sdk/src/sigma_proofs/pubkey_validity.rs#L121-L125 */ 74 5 : if( FD_LIKELY( fd_ristretto255_point_eq( res, y ) ) ) { 75 4 : return FD_ZKSDK_VERIFY_PROOF_SUCCESS; 76 4 : } 77 1 : return FD_ZKSDK_VERIFY_PROOF_ERROR; 78 5 : } 79 : 80 : /* https://github.com/solana-program/zk-elgamal-proof/blob/zk-sdk%40v5.0.1/zk-sdk/src/zk_elgamal_proof_program/proof_data/pubkey_validity.rs#L73 */ 81 : int 82 6 : fd_zksdk_instr_verify_proof_pubkey_validity( void const * _context, void const * _proof ) { 83 6 : fd_zksdk_transcript_t transcript[1]; 84 6 : fd_zksdk_transcript_init( transcript, FD_TRANSCRIPT_LITERAL("pubkey-validity-instruction") ); 85 : 86 6 : fd_zksdk_pubkey_validity_context_t const * context = _context; 87 6 : fd_zksdk_pubkey_validity_proof_t const * proof = _proof; 88 6 : return fd_zksdk_verify_proof_pubkey_validity( 89 6 : proof, 90 6 : context->pubkey, 91 6 : transcript 92 6 : ); 93 6 : }