Advertisement
Guest User

Untitled

a guest
Sep 24th, 2014
187
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.26 KB | None | 0 0
  1.  
  2. --------------------------------------------------------------------------------------------------------------
  3. ----- bip32.h ------------------------------------------------------------------------------------------------
  4. --------------------------------------------------------------------------------------------------------------
  5.  
  6. #ifndef BIP32_H
  7. #define BIP32_H
  8.  
  9. #include <QObject>
  10. #include <QMessageBox>
  11.  
  12. #include <utils/base58.h>
  13.  
  14. #include <secp256k1.h>
  15.  
  16. #include <openssl/buffer.h>
  17. #include <openssl/ec.h>
  18. #include <openssl/bn.h>
  19. #include <openssl/ecdsa.h>
  20. #include <openssl/obj_mac.h>
  21. #include <openssl/hmac.h>
  22.  
  23. class bip32 : public QObject
  24. {
  25.     Q_OBJECT
  26. public:
  27.     explicit bip32(QObject *parent = 0);
  28.  
  29.     QString magic_bytes;
  30.     QString key_type;
  31.     int depth;
  32.     QByteArray fingerprint;
  33.     QByteArray address_num;
  34.     QByteArray chain_code;
  35.     QByteArray key;
  36.  
  37.     void import(QString);
  38.     QByteArray private_to_public();
  39.     QString get_addr();
  40.     QList<QString> get_definition_tuple(QString);
  41.  
  42.     QString derive_child_key();
  43.  
  44.  
  45. signals:
  46.  
  47. public slots:
  48.  
  49. };
  50.  
  51. #endif // BIP32_H
  52.  
  53.  
  54. --------------------------------------------------------------------------------------------------------------
  55. ----- bip32.cpp ----------------------------------------------------------------------------------------------
  56. --------------------------------------------------------------------------------------------------------------
  57.  
  58. #include "bip32.h"
  59.  
  60. bip32::bip32(QObject *parent) :
  61.     QObject(parent)
  62. {
  63. }
  64.  
  65. void bip32::import(QString ext_key) {
  66.  
  67.     // BASE58 decode
  68.     base58 *b58 = new base58();
  69.     QByteArray decoded = b58->base58_decode(ext_key);
  70.  
  71.     // Get magic bytes & type
  72.     magic_bytes = decoded.left(4).toHex();
  73.     key_type = magic_bytes == "0488ade4" ? "private" : "public";
  74.  
  75.     // Get depth
  76.     depth = decoded.at(4);
  77.     decoded.remove(0, 5);
  78.  
  79.     // Get fingerprint & address num
  80.     fingerprint = decoded.left(4);
  81.     decoded.remove(0, 4);
  82.     address_num = decoded.left(4);
  83.     decoded.remove(0, 4);
  84.  
  85.     // Get chain code
  86.     chain_code = decoded.left(32);
  87.     decoded.remove(0, 32);
  88.  
  89.     // Get key
  90.     if (key_type == "private") {
  91.         decoded.remove(0, 1);
  92.         key = decoded.left(32);
  93.         decoded.remove(0, 32);
  94.     } else {
  95.         key = decoded.left(33);
  96.         decoded.remove(0, 33);
  97.     }
  98.  
  99. }
  100.  
  101. QByteArray bip32::private_to_public() {
  102.  
  103.     // Initialize
  104.     OPENSSL_init();
  105.     secp256k1_start();
  106.  
  107.     // Set variables
  108.     EC_KEY *eckey = NULL;
  109.     EC_POINT *pub_key = NULL;
  110.     const EC_GROUP *group = NULL;
  111.     BIGNUM start;
  112.     BIGNUM *res;
  113.     BN_CTX *ctx;
  114.  
  115.     // Get bignum & ctx
  116.     BN_init(&start);
  117.     ctx = BN_CTX_new();
  118.  
  119.     // Load key
  120.     res = &start;
  121.     BN_hex2bn(&res, key.toHex());
  122.     eckey = EC_KEY_new_by_curve_name(NID_secp256k1);
  123.     group = EC_KEY_get0_group(eckey);
  124.     pub_key = EC_POINT_new(group);
  125.     EC_KEY_set_private_key(eckey, res);
  126.  
  127.     // Generate public key
  128.     EC_POINT_mul(group, pub_key, res, NULL, NULL, ctx);
  129.     EC_KEY_set_public_key(eckey, pub_key);
  130.  
  131.     // Retrieve public key
  132.     char *cc = EC_POINT_point2hex(group, pub_key, POINT_CONVERSION_COMPRESSED, ctx);
  133.     QByteArray addr = cc;
  134.  
  135.     // Clean up
  136.     secp256k1_stop();
  137.     BN_CTX_free(ctx);
  138.     free(cc);
  139.  
  140.     // Return
  141.     return addr;
  142.  
  143. }
  144.  
  145. QString bip32::get_addr() {
  146.  
  147.     QCA::Initializer init;
  148.  
  149.     QByteArray pubkey = "023E4740D0BA639E28963F3476157B7CF2FB7C6FDF4254F97099CF8670B505EA59";
  150.     QByteArray ripHash = QCA::Hash("ripemd160").hash(QCA::Hash("sha256").hash(QByteArray::fromHex(pubkey))).toByteArray();
  151.     QByteArray encHash = "00" + ripHash.toHex();
  152.  
  153.     // Get checksum
  154.     QByteArray shaHash = QCA::Hash("sha256").hash(QCA::Hash("sha256").hash(QByteArray::fromHex(encHash))).toByteArray();
  155.     QByteArray checkHash = encHash + shaHash.left(4).toHex();
  156.  
  157.     base58 *b58 = new base58();
  158.     QString addr = b58->base58_encode(checkHash);
  159.  
  160.     // Return
  161.     return addr;
  162.  
  163. }
  164.  
  165. QList<QString> bip32::get_definition_tuple(QString keyindex) {
  166.  
  167.     QList<QString> k = keyindex.split("/");
  168.  
  169.     for (int x = 0; x < k.size(); x++) {
  170.         uint d = k[x].toUInt();
  171.         QString dx;
  172.         dx.setNum(d, 16);
  173.  
  174.     }
  175.  
  176.     return k;
  177.  
  178. }
  179.  
  180. QString bip32::derive_child_key() {
  181.  
  182.     QCA::Initializer init;
  183.     OPENSSL_init();
  184.  
  185.     QByteArray pubkey = "023E4740D0BA639E28963F3476157B7CF2FB7C6FDF4254F97099CF8670B505EA59";
  186.     pubkey += "00000023";
  187.  
  188.     // Hash
  189.     QCA::MessageAuthenticationCode hmac("hmac(sha512)", QCA::SecureArray());
  190.     QCA::SecureArray karr(chain_code);
  191.     QCA::SymmetricKey sk(karr);
  192.     hmac.setup(sk);
  193.     hmac.update(QCA::hexToArray(pubkey));
  194.  
  195.     // Parse resulting hash
  196.     QByteArray result = hmac.final().toByteArray();
  197.     QCA::SecureArray arr_left(result.left(32));
  198.     QCA::SecureArray arr_key(key);
  199.     QCA::SecureArray arr_order(QByteArray("115792089237316195423570985008687907852837564279074904382605163141518161494337"));
  200.  
  201.     // Get big integers
  202.     QCA::BigInteger bnl(arr_left);
  203.     QCA::BigInteger bnk(arr_key);
  204.     QCA::BigInteger bno(arr_order);
  205.  
  206.     bnl += bnk;
  207.     bnl %= bno;
  208.  
  209.     // Return
  210.     QByteArray new_key = bnl.toArray().toByteArray().toHex();
  211.     return new_key;
  212.  
  213. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement