Last active
June 21, 2023 13:59
-
-
Save CrackerHax/a7eae0ab0bea0184cdeaef35f79f1386 to your computer and use it in GitHub Desktop.
C++ ethereum ecRecover function using libsecp256k1 (with recovery module enabled) and keccak-tiny. Returns public eth address from signed message. Used to prove ownership of an eth address for logging in, etc.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "keccak-tiny.h" | |
#include "secp256k1.h" | |
#include "secp256k1_recovery.h" | |
std::string bytes_to_hex_string(const uint8_t *str, const uint64_t s) | |
{ | |
std::ostringstream ret; | |
for (size_t i = 0; i < s; ++i) | |
ret << std::hex << std::setfill('0') << std::setw(2) << std::nouppercase << (int) str[i]; | |
return ret.str(); | |
} | |
std::string hex_to_string(const std::string& input) | |
{ | |
static const char* const lut = "0123456789abcdef"; | |
size_t len = input.length(); | |
if (len & 1) throw std::invalid_argument("odd length"); | |
std::string output; | |
output.reserve(len / 2); | |
for (size_t i = 0; i < len; i += 2) | |
{ | |
char a = input[i]; | |
const char* p = std::lower_bound(lut, lut + 16, a); | |
if (*p != a) throw std::invalid_argument("not a hex digit"); | |
char b = input[i + 1]; | |
const char* q = std::lower_bound(lut, lut + 16, b); | |
if (*q != b) throw std::invalid_argument("not a hex digit"); | |
output.push_back(((p - lut) << 4) | (q - lut)); | |
} | |
return output; | |
} | |
std::string ecrecover(std::string sig, std::string msg) // hex-encoded sig, plain text msg | |
{ | |
std::string _sig = hex_to_string(sig.substr(2)); // strip 0x | |
if(_sig.size() != 65) | |
return ("0x00000000000000000000000000000000"); | |
int v = _sig[64]; | |
_sig = _sig.substr(0,64); | |
if(v>3) | |
v-=27; | |
auto* ctx = secp256k1_context_create( SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY ); | |
secp256k1_ecdsa_recoverable_signature rawSig; | |
if(!secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rawSig, (unsigned char*)_sig.data(), v)) | |
return ("0x00000000000000000000000000000000"); | |
std::array<uint8_t,32> hash; | |
keccak_256(hash.data(), hash.size(), (unsigned char*)msg.data(), msg.length()); // hash message | |
msg = string("\x19")+"Ethereum Signed Message:\n32"+string(hash.begin(),hash.end()); // wrap message hash | |
keccak_256(hash.data(), hash.size(), (unsigned char*)msg.data(), msg.length()); // hash wrapped message hash | |
secp256k1_pubkey rawPubkey; | |
if(!secp256k1_ecdsa_recover(ctx, &rawPubkey, &rawSig, hash.data())) // 32 bit hash | |
return ("0x00000000000000000000000000000000"); | |
std::array<uint8_t,65> pubkey; | |
size_t biglen = 65; | |
secp256k1_ec_pubkey_serialize(ctx, pubkey.data(), &biglen, &rawPubkey, SECP256K1_EC_UNCOMPRESSED); | |
std::string out = std::string(pubkey.begin(),pubkey.end()).substr(1); | |
keccak_256(hash.data(), hash.size(), (const unsigned char*)out.data(), out.length()); | |
return("0x"+bytes_to_hex_string(hash.data(),hash.size()).substr(24)); | |
} |
Would you be willing to share your included files? Got a project I'm working on and been struggling to implement this functionality. I can't find this tiny-keccak or the secp256k files.
I believe these are the ones I used:
https://github.com/urbit/secp256k1
https://github.com/coruus/keccak-tiny
GitHub - coruus/keccak-tiny: A tiny implementation of SHA-3, SHAKE, Keccak, and sha3sum
|
|
|
| | |
|
|
|
| |
GitHub - coruus/keccak-tiny: A tiny implementation of SHA-3, SHAKE, Kecc...
A tiny implementation of SHA-3, SHAKE, Keccak, and sha3sum - GitHub - coruus/keccak-tiny: A tiny implementation ...
|
|
|
On Wednesday, March 16, 2022, 01:44:48 PM MST, Daniel Taghavi ***@***.***> wrote:
@dtaghavi commented on this gist.
You got this keccak-tiny somewhere?
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.
You are receiving this because you authored the thread.Message ID: ***@***.***>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Would you be willing to share your included files? Got a project I'm working on and been struggling to implement this functionality.
I can't find this tiny-keccak or the secp256k files.