2013-07-16 24 views
8

Geçerli bir bitcoin adresi oluşturmak için CSS'de OpenSSL kullanarak basit kod yazıyorum - özel anahtar çifti.ECDSA Genel Anahtarından Bitcoin adresi oluşturma

Bana verilen altıgen biçimli özel anahtar Genel anahtarı oluşturmak için bu pasajı kullanıyorum:

#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; 
} 

İstediğim adresi Bitcoin için bu Public Key dönüştürmektir - bunu başarmak için en hızlı yolu nedir ? OpenSSL'in BIGNUM'undan nasıl RIPEMD160 oluşturulacağını bilmiyorum. Ya da belki başka, daha iyi bir çözüm var mı?

+1

Sonuç kodunuz var mı? ilginç geliyor – Nande

cevap

12

ne yaptığınızı bu dönüşüm dayanmaktadır varsayarak:

enter image description here

Sana sözde kodda neler yapabileceğini anlatacağım

: Kamu anahtarından

İlk özü x, y .

// 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); 

Sonraki mesajın 3 SHA256 ve 1 RIPEMD160 dahil olmak üzere birçok kez, sindirmek yapmak gerekir. Aşağıdaki sözde kodda size ripemd160 nasıl yapacağınızı göstereceğim. EVP_MD ile sha256 yapmak için, EVP_sha256() ile EVP_ripemd160()'u değiştirin ve giriş mesajınızı tek veya birkaç EVP_DigestUpdate() ile güncelleyin (EVP_MD'ye giriş yapın).

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); 

Veya daha kolay bir şekilde, sha256() ve ripemd160() doğrudan diyoruz. Ancak, sha256() veya ripemd160() karma işlevlerini aramadan önce giriş mesajınızı hazırlamanız gerekir.

25 baytlık ikili adres, ripemd160'un ve 4 baytlık 32 baytlık sağlama toplamının sonucudur. Base 256'dan Base 58'e dönüştürmenin bir yolunu bulmalısın. OpenSSL'in bunu desteklediğini sanmıyorum.

+0

Teşekkürler! Bana çok yardımcı oldu! – mpestkow

İlgili konular