2013-07-16 1 views
8

유효한 비트 코인 주소 - 개인 키 쌍을 생성하기 위해 OpenSSL을 사용하는 C++로 간단한 코드를 작성합니다.ECDSA 공용 키에서 Bitcoin 주소 생성

나는 주어진 진수 형식의 개인 키와 공개 키를 생성하려면이 조각을 사용하고 있습니다 :

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

내가 원하는 것은 주소를 비트 코인이 공개 키를 변환하는 것입니다 - 그것을 달성하는 가장 빠른 방법은 무엇입니까 ? OpenSSL의 BIGNUM에서 RIPEMD160을 작성하는 방법을 모르겠습니다. 아니면 다른 해결책이 있을까요?

+1

결과 코드가 있습니까? 흥미로운 소리 – Nande

답변

12

은 당신이하고있는 것은이 변환을 기반으로 가정하면 :

enter image description here

난 당신이 의사 코드에 무엇을 할 수 있는지 설명 할 것이다

: 공개 키에서

먼저 추출 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); 

다음 당신은 메시지가 3 SHA256 1 RIPEMD160 등 여러 번 소화 할 필요가있다. 다음 의사 코드에서는 ripemd160하는 방법을 보여 드리겠습니다. EVP_MD로 sha256을 수행하려면 EVP_ripemd160()EVP_sha256()으로 바꾸고 입력 메시지를 하나 또는 여러 개의 EVP_DigestUpdate()으로 업데이트 (EVP_MD 입력)하십시오.

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

또는 쉬운 방법, sha256()ripemd160() 직접 호출합니다. 그러나 해시 함수 sha256() 또는 ripemd160()을 호출하기 전에 입력 메시지를 준비해야합니다.

25 바이트 이진 주소는 ripemd160의 결과이며 32 바이트 체크섬의 처음 4 바이트와 함께 사용됩니다. Base 256에서 Base 58로 변환하는 방법을 찾아야합니다. OpenSSL이이를 지원하지 않는다고 생각합니다.

+0

고마워! 그것은 나를 많이 도왔다! – mpestkow