2013-07-16 18 views
8

Ich schreibe einfachen Code in C++ mit OpenSSL, um gültige Bitcoin-Adresse zu generieren - private Schlüsselpaar.Generieren Bitcoin-Adresse von ECDSA Public Key

ich diese Schnipsel mit den öffentlichen Schlüssel aus gegebenen Hex-Form privaten Schlüssel zu generieren:

#include <stdio.h> 
#include <stdlib.h> 
#include <openssl/ec.h> 
#include <openssl/obj_mac.h> 
#include <openssl/bn.h> 

int main() 
{ 
    EC_KEY *eckey = NULL; 
    EC_POINT *pub_key = NULL; 
    const EC_GROUP *group = NULL; 
    BIGNUM start; 
    BIGNUM *res; 
    BN_CTX *ctx; 



    BN_init(&start); 
    ctx = BN_CTX_new(); // ctx is an optional buffer to save time from allocating and deallocating memory whenever required 

    res = &start; 
    BN_hex2bn(&res,"30caae2fcb7c34ecadfddc45e0a27e9103bd7cfc87730d7818cc096b1266a683"); 
    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); 

    /* pub_key is a new uninitialized `EC_POINT*`. priv_key res is a `BIGNUM*`. */ 
    if (!EC_POINT_mul(group, pub_key, res, NULL, NULL, ctx)) 
     printf("Error at EC_POINT_mul.\n"); 

    EC_KEY_set_public_key(eckey, pub_key); 

    char *cc = EC_POINT_point2hex(group, pub_key, 4, ctx); 

    char *c=cc; 

    int i; 

    for (i=0; i<130; i++) // 1 byte 0x42, 32 bytes for X coordinate, 32 bytes for Y coordinate 
    { 
     printf("%c", *c++); 
    } 

    printf("\n"); 

    BN_CTX_free(ctx); 

    free(cc); 

    return 0; 
} 

Was ich will, ist dieser öffentliche Schlüssel zur Transformation Adresse Bitcoin - was ist der schnellste Weg, um es zu erreichen ? Ich weiß nicht, wie man RIPEMD160 aus OpenSSLs BIGNUM erstellt. Oder vielleicht gibt es eine andere, bessere Lösung?

+1

Haben Sie den resultierenden Code? hört sich interessant an – Nande

Antwort

12

Vorausgesetzt, dass, was Sie tun, auf Umwandlung basiert:

enter image description here

Ich werde beschreiben, was Sie in Pseudo-Code tun können:

Erster Extrakt x, y aus dem öffentlichen Schlüssel .

// get x and y from Public key "point" 
EC_POINT_get_affine_coordinates_GFp(group, pub_key, x, y, ctx); 
// convert BIGNUMs x, y into binary form 
BN_bn2bin(x,x_char); 
BN_bn2bin(y,y_char); 

Als nächstes müssen Sie Nachricht mehrmals tun verdauen, darunter 3 sha256 und 1 ripemd160. Im folgenden Pseudo-Code zeige ich dir, wie man ripemd160 macht. Um sha256 mit EVP_MD zu machen, ersetzen Sie einfach EVP_ripemd160() durch EVP_sha256(), und aktualisieren Sie (Eingang zu EVP_MD) Ihre Eingangsnachricht mit einem oder mehreren EVP_DigestUpdate().

EVP_MD_CTX ctx; 
EVP_MD_CTX_init(&md_ctx); 
EVP_DigestInit(&md_ctx, EVP_ripemd160()); 
// hdr = 0x04 
EVP_DigestUpdate(&md_ctx,hdr,1); 
EVP_DigestUpdate(&md_ctx,x_char,32); 
EVP_DigestUpdate(&md_ctx,y_char,32); 
// put message degest into dgst and set length to dgstlen 
EVP_DigestFinal(&md_ctx,dgst,&dgstlen); 
EVP_MD_CTX_cleanup(&md_ctx); 

oder die einfachen Art und Weise, rufen sha256() und ripemd160() direkt. Sie müssen jedoch Ihre Eingabenachricht vor dem Aufruf der Hash-Funktionen sha256() oder ripemd160() vorbereiten.

Die 25-Byte-Binäradresse ist das Ergebnis von ripemd160, zusammen mit den ersten 4 Bytes der 32-Byte-Prüfsumme. Sie müssen einen Weg finden, um es von Base 256 zu Base 58 zu konvertieren. Ich denke nicht, dass OpenSSL das unterstützt.

+0

Danke! Es hat mir sehr geholfen! – mpestkow

Verwandte Themen