Last active
November 26, 2025 12:56
-
-
Save thecompez/d63b38f8d9900d27719074f481b3a653 to your computer and use it in GitHub Desktop.
Revisions
-
thecompez revised this gist
Nov 26, 2025 . 1 changed file with 18 additions and 0 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -132,3 +132,21 @@ std::string toChecksum(S address) { } return "0x"+out; } Usage example: import eth.checksum; auto main() -> int { std::vector<std::string> addresses = { "0x...", "0x..." }; for(const auto &a : addresses) { std::cout << "Checksum: " << toChecksum(a) << "\n"; } return 0; } -
thecompez created this gist
Nov 26, 2025 .There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,134 @@ module; import <array>; import <string>; import <string_view>; import <iostream>; import <algorithm>; import <cctype>; import <sstream>; import <iomanip>; import <concepts>; import <vector>; export module eth.checksum; /* ========================= Utility ========================= */ constexpr int hexCharToInt(const char c) noexcept { if(c >= '0' && c <= '9') return c - '0'; if(c >= 'a' && c <= 'f') return c - 'a' + 10; if(c >= 'A' && c <= 'F') return c - 'A' + 10; return 0; } constexpr char safeToUpper(const char c) noexcept { if(c >= 'a' && c <= 'z') return c - 'a' + 'A'; return c; } constexpr char safeToLower(const char c) noexcept { if(c >= 'A' && c <= 'Z') return c - 'A' + 'a'; return c; } /* ========================= Keccak-256 Implementation ========================= */ export class Keccak256 { static constexpr std::array<uint64_t, 24> RC = { 0x0000000000000001ULL,0x0000000000008082ULL,0x800000000000808aULL,0x8000000080008000ULL, 0x000000000000808bULL,0x0000000080000001ULL,0x8000000080008081ULL,0x8000000000008009ULL, 0x000000000000008aULL,0x0000000000000088ULL,0x0000000080008009ULL,0x000000008000000aULL, 0x000000008000808bULL,0x800000000000008bULL,0x8000000000008089ULL,0x8000000000008003ULL, 0x8000000000008002ULL,0x8000000000000080ULL,0x000000000000800aULL,0x800000008000000aULL, 0x8000000080008081ULL,0x8000000000008080ULL,0x0000000080000001ULL,0x8000000080008008ULL }; static constexpr uint64_t ROL(const uint64_t x, const uint8_t n) noexcept { return (x << n) | (x >> (64 - n)); } public: static std::string hash(const std::string_view input) { constexpr size_t r = 136; uint64_t st[5][5]{}; std::string msg(input); msg.push_back(0x01); while((msg.size() % r) != r - 1) msg.push_back(0x00); msg.push_back(0x80); for(size_t o = 0; o < msg.size(); o += r) { for(int i=0;i<17;i++){ uint64_t v=0; for(int b=0;b<8;b++) v|= static_cast<uint64_t>(static_cast<uint8_t>(msg[o + i * 8 + b])) <<(8*b); st[i%5][i/5]^=v; } for(int rnd=0;rnd<24;rnd++){ uint64_t B[5][5]{}, C[5]{}, D[5]{}; for(int x=0;x<5;x++) C[x]=st[x][0]^st[x][1]^st[x][2]^st[x][3]^st[x][4]; for(int x=0;x<5;x++) D[x]=C[(x+4)%5]^ROL(C[(x+1)%5],1); for(int x=0;x<5;x++) for(int y=0;y<5;y++) st[x][y]^=D[x]; constexpr uint8_t ROTC[5][5]={ { 0,36, 3,41,18},{ 1,44,10,45, 2},{62, 6,43,15,61}, {28,55,25,21,56},{27,20,39, 8,14} }; for(int x=0;x<5;x++) for(int y=0;y<5;y++) B[y][(2*x+3*y)%5]=ROL(st[x][y],ROTC[x][y]); for(int x=0;x<5;x++) for(int y=0;y<5;y++) st[x][y]=B[x][y]^((~B[(x+1)%5][y])&B[(x+2)%5][y]); st[0][0]^=RC[rnd]; } } std::ostringstream out; for(int i=0;i<4;i++){ uint64_t v=st[i%5][i/5]; for(int b=0;b<8;b++) out << std::hex << std::setfill('0') << std::setw(2) << ((v >> (8*b)) & 0xff); } return out.str(); } }; /* ========================= EIP-55 Checksum ========================= */ export template<typename T> concept StringLike = requires(T a) { { std::string(a) } -> std::convertible_to<std::string>; }; export template<StringLike S> std::string toChecksum(S address) { std::string addr(address); if(addr.rfind("0x",0)==0) addr=addr.substr(2); std::string lower; lower.reserve(addr.size()); for (const char c : addr) lower += safeToLower(c); const std::string hash=Keccak256::hash(lower); std::string out; out.reserve(addr.size()); for(size_t i=0;i<lower.size();i++){ if(std::isalpha(lower[i]) && hexCharToInt(hash[i]) >= 8) out += safeToUpper(lower[i]); else out += lower[i]; } return "0x"+out; }