bool recover_public(const secp256k1_context* context, byte_array<Size>& out, const recoverable_signature& recoverable, const hash_digest& hash) { secp256k1_pubkey pubkey; secp256k1_ecdsa_recoverable_signature sign; const auto recovery_id = static_cast<int>(recoverable.recovery_id); return secp256k1_ecdsa_recoverable_signature_parse_compact(context, &sign, recoverable.signature.data(), recovery_id) == 1 && secp256k1_ecdsa_recover(context, &pubkey, &sign, hash.data()) == 1 && serialize(context, out, pubkey); }
void bench_recover(void* arg) { int i; bench_recover_t *data = (bench_recover_t*)arg; secp256k1_pubkey_t pubkey; unsigned char pubkeyc[33]; for (i = 0; i < 20000; i++) { int j; int pubkeylen = 33; secp256k1_ecdsa_recoverable_signature_t sig; CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(data->ctx, &sig, data->sig, i % 2)); CHECK(secp256k1_ecdsa_recover(data->ctx, data->msg, &sig, &pubkey)); CHECK(secp256k1_ec_pubkey_serialize(data->ctx, pubkeyc, &pubkeylen, &pubkey, 1)); for (j = 0; j < 32; j++) { data->sig[j + 32] = data->msg[j]; /* Move former message to S. */ data->msg[j] = data->sig[j]; /* Move former R to message. */ data->sig[j] = pubkeyc[j + 1]; /* Move recovered pubkey X coordinate to R (which must be a valid X coordinate). */ } } }