Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --------------------------------------------------------------------------------------------------------------
- ----- bip32.h ------------------------------------------------------------------------------------------------
- --------------------------------------------------------------------------------------------------------------
- #ifndef BIP32_H
- #define BIP32_H
- #include <QObject>
- #include <QMessageBox>
- #include <utils/base58.h>
- #include <secp256k1.h>
- #include <openssl/buffer.h>
- #include <openssl/ec.h>
- #include <openssl/bn.h>
- #include <openssl/ecdsa.h>
- #include <openssl/obj_mac.h>
- #include <openssl/hmac.h>
- class bip32 : public QObject
- {
- Q_OBJECT
- public:
- explicit bip32(QObject *parent = 0);
- QString magic_bytes;
- QString key_type;
- int depth;
- QByteArray fingerprint;
- QByteArray address_num;
- QByteArray chain_code;
- QByteArray key;
- void import(QString);
- QByteArray private_to_public();
- QString get_addr();
- QList<QString> get_definition_tuple(QString);
- QString derive_child_key();
- signals:
- public slots:
- };
- #endif // BIP32_H
- --------------------------------------------------------------------------------------------------------------
- ----- bip32.cpp ----------------------------------------------------------------------------------------------
- --------------------------------------------------------------------------------------------------------------
- #include "bip32.h"
- bip32::bip32(QObject *parent) :
- QObject(parent)
- {
- }
- void bip32::import(QString ext_key) {
- // BASE58 decode
- base58 *b58 = new base58();
- QByteArray decoded = b58->base58_decode(ext_key);
- // Get magic bytes & type
- magic_bytes = decoded.left(4).toHex();
- key_type = magic_bytes == "0488ade4" ? "private" : "public";
- // Get depth
- depth = decoded.at(4);
- decoded.remove(0, 5);
- // Get fingerprint & address num
- fingerprint = decoded.left(4);
- decoded.remove(0, 4);
- address_num = decoded.left(4);
- decoded.remove(0, 4);
- // Get chain code
- chain_code = decoded.left(32);
- decoded.remove(0, 32);
- // Get key
- if (key_type == "private") {
- decoded.remove(0, 1);
- key = decoded.left(32);
- decoded.remove(0, 32);
- } else {
- key = decoded.left(33);
- decoded.remove(0, 33);
- }
- }
- QByteArray bip32::private_to_public() {
- // Initialize
- OPENSSL_init();
- secp256k1_start();
- // Set variables
- EC_KEY *eckey = NULL;
- EC_POINT *pub_key = NULL;
- const EC_GROUP *group = NULL;
- BIGNUM start;
- BIGNUM *res;
- BN_CTX *ctx;
- // Get bignum & ctx
- BN_init(&start);
- ctx = BN_CTX_new();
- // Load key
- res = &start;
- BN_hex2bn(&res, key.toHex());
- eckey = EC_KEY_new_by_curve_name(NID_secp256k1);
- group = EC_KEY_get0_group(eckey);
- pub_key = EC_POINT_new(group);
- EC_KEY_set_private_key(eckey, res);
- // Generate public key
- EC_POINT_mul(group, pub_key, res, NULL, NULL, ctx);
- EC_KEY_set_public_key(eckey, pub_key);
- // Retrieve public key
- char *cc = EC_POINT_point2hex(group, pub_key, POINT_CONVERSION_COMPRESSED, ctx);
- QByteArray addr = cc;
- // Clean up
- secp256k1_stop();
- BN_CTX_free(ctx);
- free(cc);
- // Return
- return addr;
- }
- QString bip32::get_addr() {
- QCA::Initializer init;
- QByteArray pubkey = "023E4740D0BA639E28963F3476157B7CF2FB7C6FDF4254F97099CF8670B505EA59";
- QByteArray ripHash = QCA::Hash("ripemd160").hash(QCA::Hash("sha256").hash(QByteArray::fromHex(pubkey))).toByteArray();
- QByteArray encHash = "00" + ripHash.toHex();
- // Get checksum
- QByteArray shaHash = QCA::Hash("sha256").hash(QCA::Hash("sha256").hash(QByteArray::fromHex(encHash))).toByteArray();
- QByteArray checkHash = encHash + shaHash.left(4).toHex();
- base58 *b58 = new base58();
- QString addr = b58->base58_encode(checkHash);
- // Return
- return addr;
- }
- QList<QString> bip32::get_definition_tuple(QString keyindex) {
- QList<QString> k = keyindex.split("/");
- for (int x = 0; x < k.size(); x++) {
- uint d = k[x].toUInt();
- QString dx;
- dx.setNum(d, 16);
- }
- return k;
- }
- QString bip32::derive_child_key() {
- QCA::Initializer init;
- OPENSSL_init();
- QByteArray pubkey = "023E4740D0BA639E28963F3476157B7CF2FB7C6FDF4254F97099CF8670B505EA59";
- pubkey += "00000023";
- // Hash
- QCA::MessageAuthenticationCode hmac("hmac(sha512)", QCA::SecureArray());
- QCA::SecureArray karr(chain_code);
- QCA::SymmetricKey sk(karr);
- hmac.setup(sk);
- hmac.update(QCA::hexToArray(pubkey));
- // Parse resulting hash
- QByteArray result = hmac.final().toByteArray();
- QCA::SecureArray arr_left(result.left(32));
- QCA::SecureArray arr_key(key);
- QCA::SecureArray arr_order(QByteArray("115792089237316195423570985008687907852837564279074904382605163141518161494337"));
- // Get big integers
- QCA::BigInteger bnl(arr_left);
- QCA::BigInteger bnk(arr_key);
- QCA::BigInteger bno(arr_order);
- bnl += bnk;
- bnl %= bno;
- // Return
- QByteArray new_key = bnl.toArray().toByteArray().toHex();
- return new_key;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement