Hi there, nice to be in this wonderful community. I have a question regarding the signature generation code in Python on this site about Fix API: Fix API | Binance Open Platform is there a c++ equivalent library? I tried <sodium.h> and it seems the signatures are different solely because of the algorithms in generating signatures or utilizing the ed25519 private keys.
I did many deep-dive into how Python and c++ handle the private key and generate signatures differently and the code in c++ is given below. Can anyone please help verify if this is the correct way of generating signatures in c++? I know it’s not and what’s the right way for doing this then? It would be great if an example can be provided so that c++ developer can benefit greatly from it. Thanks.
#include <iostream>
#include <sodium.h>
#include <stdexcept>
// Function to generate the Ed25519 signature
std::string generateEd25519Signature(const std::string& payload, const std::string& privateKeyBase64) {
// Decode the private key from Base64
unsigned char privateKey[crypto_sign_SECRETKEYBYTES];
if (sodium_base642bin(privateKey, sizeof(privateKey),
privateKeyBase64.c_str(), privateKeyBase64.size(),
nullptr, nullptr, nullptr, sodium_base64_VARIANT_ORIGINAL) != 0) {
throw std::runtime_error("Failed to decode private key from Base64.");
}
// Debug: Print the decoded private key in hex
std::cout << "Decoded Private Key (Hex): ";
for (size_t i = 0; i < crypto_sign_SECRETKEYBYTES; ++i) {
printf("%02x", privateKey[i]);
}
std::cout << std::endl;
// Generate the Ed25519 signature
unsigned char signature[crypto_sign_BYTES];
if (crypto_sign_detached(signature, nullptr,
reinterpret_cast<const unsigned char*>(payload.c_str()), payload.size(),
privateKey) != 0) {
throw std::runtime_error("Failed to generate Ed25519 signature.");
}
// Debug: Print the raw signature in hex
std::cout << "Raw Signature (Hex): ";
for (size_t i = 0; i < crypto_sign_BYTES; ++i) {
printf("%02x", signature[i]);
}
std::cout << std::endl;
// Convert the signature to Base64
char base64Signature[crypto_sign_BYTES * 2]; // Ensure buffer is large enough
sodium_bin2base64(base64Signature, sizeof(base64Signature),
signature, crypto_sign_BYTES, sodium_base64_VARIANT_ORIGINAL);
// Return the signature as a Base64-encoded string
return std::string(base64Signature);
}
int main() {
// Initialize libsodium
if (sodium_init() < 0) {
std::cerr << "Failed to initialize libsodium" << std::endl;
return 1;
}
// Construct the payload explicitly
const char SOH = '\x01'; // ASCII Start of Header character
std::string payload = "A" + std::string(1, SOH) +
"5JQmUOsm" + std::string(1, SOH) +
"SPOT" + std::string(1, SOH) +
"1" + std::string(1, SOH) +
"20241121-08:08:35.672";
// Debug: Print the payload with escaped characters
std::cout << "Payload (with escaped \\x01): ";
for (char c : payload) {
if (c == '\x01') {
std::cout << "\\x01";
} else {
std::cout << c;
}
}
std::cout << std::endl;
// Replace with your private key in Base64 format
std::string privateKeyBase64 = "";
// Generate signature
try {
std::string signature = generateEd25519Signature(payload, privateKeyBase64);
std::cout << "Generated Ed25519 Signature (Base64): " << signature << std::endl;
} catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
return 1;
}
return 0;
}