Skip to content

Instantly share code, notes, and snippets.

@chfast
Created January 26, 2022 20:38
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save chfast/06fc4596278eccdf5dd2243e316b70ca to your computer and use it in GitHub Desktop.
How to compute Ethereum address from EC private key using OpenSSL
#include <ethash/keccak.hpp>
#include <evmc/hex.hpp>
#include <openssl/ec.h>
#include <openssl/evp.h>
#include <iostream>
#include <dlfcn.h>
int main(int argc, const char* argv[])
{
try
{
const auto dl_h = dlopen("libcrypto.so.1.1", RTLD_LAZY);
if (!dl_h)
return 10;
const auto bn_bin2bn_p = dlsym(dl_h, "BN_bin2bn");
if (!bn_bin2bn_p)
return 11;
using bin2bn_fn = BIGNUM*(const unsigned char* s, int len, BIGNUM* ret);
const auto bin2bn = reinterpret_cast<bin2bn_fn*>(bn_bin2bn_p);
if (argc != 2)
return 1;
const auto privkey = evmc::from_hex(argv[1]);
if (privkey.size() != 32)
return 2;
auto* privkey_bn = bin2bn(privkey.data(), static_cast<int>(privkey.size()), nullptr);
auto* g = EC_GROUP_new_by_curve_name(NID_secp256k1);
auto* pt = EC_POINT_new(g);
const auto r = EC_POINT_mul(g, pt, privkey_bn, nullptr, nullptr, nullptr);
if (r == 0)
return 4;
unsigned char buf[65];
const auto written =
EC_POINT_point2oct(g, pt, POINT_CONVERSION_UNCOMPRESSED, buf, sizeof(buf), nullptr);
if (written != sizeof(buf))
return 5;
if (buf[0] != 0x04)
return 6;
const auto h = ethash::keccak256(&buf[1], 64);
std::cout << evmc::hex({&h.bytes[12], 20});
EC_POINT_free(pt);
BN_free(privkey_bn);
EC_GROUP_free(g);
dlclose(dl_h);
}
catch (...)
{
return 13;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment