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 60027 : int recovery_id ) { 11 60027 : secp256k1_ecdsa_recoverable_signature recoverable_sig; 12 60027 : secp256k1_pubkey internal_public_key; 13 60027 : uchar serialized_public_key[ 65 ]; 14 60027 : 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 60027 : if ( FD_UNLIKELY( !(recovery_id >= 0 && recovery_id <= 3) ) ) { 20 : /* COV: the callers do the same check */ 21 9 : return NULL; 22 9 : } 23 : 24 60018 : if( FD_UNLIKELY( !secp256k1_ecdsa_recoverable_signature_parse_compact( secp256k1_context_static, 25 60018 : &recoverable_sig, (uchar const *) sig, 26 60018 : recovery_id ) ) ) { 27 0 : return NULL; 28 0 : } 29 : 30 60018 : if( FD_UNLIKELY( !secp256k1_ecdsa_recover( secp256k1_context_static, &internal_public_key, 31 60018 : &recoverable_sig, msg_hash ) ) ) { 32 30006 : return NULL; 33 30006 : } 34 : 35 30012 : if( FD_UNLIKELY( !secp256k1_ec_pubkey_serialize( secp256k1_context_static, serialized_public_key, &public_key_len, 36 30012 : &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 30012 : return fd_memcpy(public_key, &serialized_public_key[1], 64); 44 30012 : }