hivekeys.pro
TEMPLATE = app
TARGET = hivekeys
INCLUDEPATH += .
SOURCES += main.cpp
QT += widgets
LIBS += -lcrypto
main.cpp
#include <QApplication>
#include <QWidget>
#include <QVBoxLayout>
#include <QPushButton>
#include <QLineEdit>
#include <QLabel>
#include <QTextEdit>
#include <QMessageBox>
#include <openssl/sha.h>
#include <openssl/rand.h>
#include <openssl/ec.h>
#include <openssl/obj_mac.h>
#include <openssl/bn.h>
#include <openssl/evp.h>
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
#include <openssl/provider.h>
#endif
#include <vector>
#include <string>
// --- IMPLEMENTAÇÃO DO BASE58 ---
std::string EncodeBase58(const std::vector<unsigned char>& data) {
static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
std::vector<unsigned char> b58((data.size() * 138 / 100) + 1);
size_t length = 0;
for (size_t i = 0; i < data.size(); i++) {
int carry = data[i];
size_t j = 0;
for (auto it = b58.rbegin(); (carry != 0 || j < length) && (it != b58.rend()); ++it, ++j) {
carry += 256 * (*it);
*it = carry % 58;
carry /= 58;
}
length = j;
}
auto it = b58.begin() + (b58.size() - length);
while (it != b58.end() && *it == 0) it++;
std::string str;
int zeroes = 0;
for (size_t i = 0; i < data.size() && data[i] == 0; i++) zeroes++;
str.assign(zeroes, '1');
while (it != b58.end()) str += pszBase58[*(it++)];
return str;
}
// --- CONVERSÃO PARA FORMATO WIF (Privada) ---
std::string PrivKeyToWIF(const std::vector<unsigned char>& privkey) {
std::vector<unsigned char> data;
data.push_back(0x80); // Prefixo para começar com '5'
data.insert(data.end(), privkey.begin(), privkey.end());
unsigned char hash1[SHA256_DIGEST_LENGTH];
SHA256(data.data(), data.size(), hash1);
unsigned char hash2[SHA256_DIGEST_LENGTH];
SHA256(hash1, SHA256_DIGEST_LENGTH, hash2);
data.insert(data.end(), hash2, hash2 + 4);
return EncodeBase58(data);
}
// --- DERIVAÇÃO DA HIVE (Privada e Pública) ---
void GetHiveKeys(const std::string& username, const std::string& password, const std::string& role, std::string& out_wif, std::string& out_pub) {
// 1. Gera a semente
std::string seed = username + role + password;
std::vector<unsigned char> privkey(SHA256_DIGEST_LENGTH);
SHA256((const unsigned char*)seed.c_str(), seed.length(), privkey.data());
out_wif = PrivKeyToWIF(privkey);
// 2. Calcula a Chave Pública usando secp256k1
BIGNUM *priv_bn = BN_bin2bn(privkey.data(), privkey.size(), NULL);
EC_GROUP *group = EC_GROUP_new_by_curve_name(NID_secp256k1);
EC_POINT *pub_point = EC_POINT_new(group);
EC_POINT_mul(group, pub_point, priv_bn, NULL, NULL, NULL);
std::vector<unsigned char> pubkey(33); // Formato Comprimido (33 bytes)
EC_POINT_point2oct(group, pub_point, POINT_CONVERSION_COMPRESSED, pubkey.data(), 33, NULL);
// 3. Checksum da Chave Pública usa RIPEMD-160
unsigned char ripemd_hash[EVP_MAX_MD_SIZE];
unsigned int hash_len;
EVP_MD_CTX *mdctx = EVP_MD_CTX_new();
EVP_DigestInit_ex(mdctx, EVP_ripemd160(), NULL);
EVP_DigestUpdate(mdctx, pubkey.data(), pubkey.size());
EVP_DigestFinal_ex(mdctx, ripemd_hash, &hash_len);
EVP_MD_CTX_free(mdctx);
std::vector<unsigned char> pub_data;
pub_data.insert(pub_data.end(), pubkey.begin(), pubkey.end());
pub_data.insert(pub_data.end(), ripemd_hash, ripemd_hash + 4);
out_pub = "STM" + EncodeBase58(pub_data); // STM é o prefixo padrão da Hive
EC_POINT_free(pub_point);
EC_GROUP_free(group);
BN_free(priv_bn);
}
std::string GenerateMasterPassword() {
std::vector<unsigned char> entropy(32);
RAND_bytes(entropy.data(), 32);
return "P5" + EncodeBase58(entropy);
}
// --- INTERFACE GRÁFICA QT ---
int main(int argc, char *argv[]) {
// Carrega o provedor Legacy para o RIPEMD-160 funcionar no OpenSSL 3.0+
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
OSSL_PROVIDER_load(NULL, "legacy");
OSSL_PROVIDER_load(NULL, "default");
#endif
QApplication app(argc, argv);
QWidget window;
window.setWindowTitle("Gerador Hive Completo (WIF & STM) - RAM Mode");
QVBoxLayout *layout = new QVBoxLayout(&window);
QLabel *lblUser = new QLabel("Nome de Usuário (Obrigatório):");
QLineEdit *inputUser = new QLineEdit();
QLabel *lblMaster = new QLabel("Senha Mestre (P5...):");
QLineEdit *outputMaster = new QLineEdit();
outputMaster->setReadOnly(true);
QLabel *lblKeys = new QLabel("Pares de Chaves (Privada / Pública):");
QTextEdit *outputKeys = new QTextEdit();
outputKeys->setReadOnly(true);
outputKeys->setStyleSheet("font-family: monospace; font-size: 11pt;");
QPushButton *btnGenerate = new QPushButton("Gerar Par de Chaves");
btnGenerate->setStyleSheet("padding: 10px; font-weight: bold;");
layout->addWidget(lblUser);
layout->addWidget(inputUser);
layout->addWidget(lblMaster);
layout->addWidget(outputMaster);
layout->addWidget(lblKeys);
layout->addWidget(outputKeys);
layout->addWidget(btnGenerate);
QObject::connect(btnGenerate, &QPushButton::clicked, [&]() {
std::string username = inputUser->text().toStdString();
if (username.empty()) {
QMessageBox::warning(&window, "Aviso", "Preencha o nome de usuário!");
return;
}
std::string master = GenerateMasterPassword();
outputMaster->setText(QString::fromStdString(master));
std::string owner_wif, owner_pub;
GetHiveKeys(username, master, "owner", owner_wif, owner_pub);
std::string active_wif, active_pub;
GetHiveKeys(username, master, "active", active_wif, active_pub);
std::string posting_wif, posting_pub;
GetHiveKeys(username, master, "posting", posting_wif, posting_pub);
std::string memo_wif, memo_pub;
GetHiveKeys(username, master, "memo", memo_wif, memo_pub);
outputKeys->setText(
"==== OWNER ====\nPRIV: " + QString::fromStdString(owner_wif) + "\nPUB: " + QString::fromStdString(owner_pub) + "\n\n" +
"==== ACTIVE ====\nPRIV: " + QString::fromStdString(active_wif) + "\nPUB: " + QString::fromStdString(active_pub) + "\n\n" +
"==== POSTING ====\nPRIV: " + QString::fromStdString(posting_wif) + "\nPUB: " + QString::fromStdString(posting_pub) + "\n\n" +
"==== MEMO ====\nPRIV: " + QString::fromStdString(memo_wif) + "\nPUB: " + QString::fromStdString(memo_pub)
);
});
window.resize(650, 600);
window.show();
return app.exec();
}
Agora para compilar e rodar
sudo apt install build-essential qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools libssl-dev -y
qmake hivekeys.pro
make
./hivekeys
