@@ -831,6 +831,35 @@ int secp256k1_silentpayments_recipient_create_output_pubkey(const secp256k1_cont
831831 return secp256k1_silentpayments_create_output_pubkey (ctx , output_xonly , shared_secret33 , spend_pubkey , k );
832832}
833833
834+ int secp256k1_silentpayments_verify_proof (const secp256k1_context * ctx , const unsigned char * shared_secret33 , const unsigned char * proof64 , const secp256k1_pubkey * recipient_scan_pubkey , const secp256k1_silentpayments_prevouts_summary * prevouts_summary )
835+ {
836+ secp256k1_scalar s ;
837+ secp256k1_scalar e ;
838+ secp256k1_pubkey pk ;
839+ secp256k1_ge pubkey_sum ;
840+ secp256k1_ge scan_pubkey ;
841+ secp256k1_ge shared_secret ;
842+ size_t pubkeylen = 33 ;
843+ unsigned char pubkey33 [33 ];
844+ int ret = 1 ;
845+
846+ VERIFY_CHECK (ctx != NULL );
847+ ARG_CHECK (shared_secret33 != NULL );
848+ ARG_CHECK (proof64 != NULL );
849+ ARG_CHECK (recipient_scan_pubkey != NULL );
850+ ARG_CHECK (prevouts_summary != NULL );
851+
852+ ret &= secp256k1_silentpayments_recipient_prevouts_summary_serialize (ctx , pubkey33 , prevouts_summary );
853+ ret &= secp256k1_ec_pubkey_parse (ctx , & pk , pubkey33 , pubkeylen );
854+ ret &= secp256k1_pubkey_load (ctx , & pubkey_sum , & pk );
855+ ret &= secp256k1_pubkey_load (ctx , & scan_pubkey , recipient_scan_pubkey );
856+ ret &= secp256k1_ec_pubkey_parse (ctx , & pk , shared_secret33 , pubkeylen );
857+ ret &= secp256k1_pubkey_load (ctx , & shared_secret , & pk );
858+ secp256k1_scalar_set_b32 (& s , proof64 , NULL );
859+ secp256k1_scalar_set_b32 (& e , proof64 + 32 , NULL );
860+ ret &= secp256k1_dleq_verify (& s , & e , & pubkey_sum , & scan_pubkey , & shared_secret , NULL );
861+ return ret ;
862+ }
834863
835864void secp256k1_silentpayments_dleq_data_serialize (unsigned char * output , const secp256k1_silentpayments_dleq_data * dleq_data ) {
836865 memcpy (output , dleq_data -> shared_secret , 33 );
0 commit comments