Line data Source code
1 : #include "fd_secp256k1.h" 2 : 3 : #include <secp256k1.h> 4 : #include <secp256k1_recovery.h> 5 : 6 : void * 7 : fd_secp256k1_recover( void * public_key, 8 : void const * msg_hash, 9 : void const * sig, 10 60765 : int recovery_id ) { 11 60765 : secp256k1_ecdsa_recoverable_signature recoverable_sig; 12 60765 : secp256k1_pubkey internal_public_key; 13 60765 : uchar serialized_public_key[ 65 ]; 14 60765 : size_t public_key_len = 65; 15 : 16 : /* Avoid panic in secp256k1_ecdsa_recoverable_signature_parse_compact 17 : https://github.com/bitcoin-core/secp256k1/blob/v0.5.0/src/modules/recovery/main_impl.h#L46 18 : ARG_CHECK(recid >= 0 && recid <= 3); */ 19 60765 : if ( FD_UNLIKELY( !(recovery_id >= 0 && recovery_id <= 3) ) ) { 20 : /* COV: the callers do the same check */ 21 48 : return NULL; 22 48 : } 23 : 24 60717 : if( FD_UNLIKELY( !secp256k1_ecdsa_recoverable_signature_parse_compact( secp256k1_context_static, 25 60717 : &recoverable_sig, (uchar const *) sig, 26 60717 : recovery_id ) ) ) { 27 6 : return NULL; 28 6 : } 29 : 30 60711 : if( FD_UNLIKELY( !secp256k1_ecdsa_recover( secp256k1_context_static, &internal_public_key, 31 60711 : &recoverable_sig, msg_hash ) ) ) { 32 30042 : return NULL; 33 30042 : } 34 : 35 30669 : if( FD_UNLIKELY( !secp256k1_ec_pubkey_serialize( secp256k1_context_static, serialized_public_key, &public_key_len, 36 30669 : &internal_public_key, SECP256K1_EC_UNCOMPRESSED ) ) ) { 37 : /* COV: the output of secp256k1_ecdsa_recover should always serialize */ 38 0 : return NULL; 39 0 : } 40 : 41 : /* Skip 1st byte: libsecp256k1 prepends 0x04 to the public key 42 : https://github.com/bitcoin-core/secp256k1/blob/v0.5.0/src/eckey_impl.h#L49 */ 43 30669 : return fd_memcpy(public_key, &serialized_public_key[1], 64); 44 30669 : }