#include #include #include #include #include #include #include #include static QByteArray toHex(const unsigned char* data, int len) { return QByteArray(reinterpret_cast(data), len).toHex(); } int main(int argc, char* argv[]) { QCoreApplication app(argc, argv); #if OPENSSL_VERSION_NUMBER < 0x10100000L OpenSSL_add_all_algorithms(); #endif QTextStream out(stdout); QTextStream err(stderr); unsigned char encKey[32]; if (RAND_bytes(encKey, sizeof(encKey)) != 1) { err << "Failed to generate encryption key\n"; return 1; } EVP_PKEY_CTX* kctx = EVP_PKEY_CTX_new_id(EVP_PKEY_ED25519, nullptr); if (!kctx) { err << "EVP_PKEY_CTX_new_id failed\n"; return 1; } if (EVP_PKEY_keygen_init(kctx) != 1) { err << "EVP_PKEY_keygen_init failed\n"; EVP_PKEY_CTX_free(kctx); return 1; } EVP_PKEY* pkey = nullptr; if (EVP_PKEY_keygen(kctx, &pkey) != 1) { err << "EVP_PKEY_keygen failed\n"; EVP_PKEY_CTX_free(kctx); return 1; } EVP_PKEY_CTX_free(kctx); unsigned char sk[32]; unsigned char pk[32]; size_t skLen = sizeof(sk); size_t pkLen = sizeof(pk); if (EVP_PKEY_get_raw_private_key(pkey, sk, &skLen) != 1 || skLen != 32) { err << "Failed to extract Ed25519 private key\n"; EVP_PKEY_free(pkey); return 1; } if (EVP_PKEY_get_raw_public_key(pkey, pk, &pkLen) != 1 || pkLen != 32) { err << "Failed to extract Ed25519 public key\n"; EVP_PKEY_free(pkey); return 1; } EVP_PKEY_free(pkey); QJsonObject root; root["encKey32"] = QString::fromLatin1(toHex(encKey, 32)); root["signSk32"] = QString::fromLatin1(toHex(sk, 32)); root["signPk32"] = QString::fromLatin1(toHex(pk, 32)); QJsonDocument doc(root); QString outPath = "keys.json"; if (app.arguments().size() >= 2) { outPath = app.arguments().at(1); } QFile f(outPath); if (!f.open(QIODevice::WriteOnly | QIODevice::Truncate)) { err << "Failed to write " << outPath << "\n"; return 1; } f.write(doc.toJson(QJsonDocument::Indented)); f.close(); out << "Keys generated successfully:\n\n"; out << "encKey32 : " << root["encKey32"].toString() << "\n"; out << "signSk32 : " << root["signSk32"].toString() << " (PC ONLY)\n"; out << "signPk32 : " << root["signPk32"].toString() << " (DEVICE)\n\n"; out << "Written to " << outPath << "\n"; return 0; }