2016-05-07 13 views
1

私はBitcoin Addressを生成するために小さなアプリケーションを構築しようとしています(理解のため)。
私はOpenSSLライブラリを使用しています。
秘密鍵を公開鍵に変換し、公開鍵をsha256で変換したところ、結果は正常でした。しかし、sha256 result trough ripemd160を実行しようとすると問題が発生します。
- 私はプレーンな文字列で機能をRIPEMD160テストし、それが正常に動作し
- 私は変換SHA256が文字列
になりました - それでも私はここに私のメインのだ間違った結果
C++ OpenSSL Ripemd-160は間違った出力を返します

を得る:

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    char sha256_buffer[65]; 
    char ripemd160_buffer[41]; 
    char *pvt_key = "18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725"; 
    unsigned char *pub_hex = priv2pub((const unsigned char *)pvt_key, POINT_CONVERSION_UNCOMPRESSED); 
    //printf("%s\n", pub_hex); 
    std::string pub_key_string = hex_to_string(reinterpret_cast<char*>(pub_hex)); 
    sha256(&pub_key_string[0], sha256_buffer); 
    printf("%s\n", sha256_buffer); 
    std::string hash256_string = hex_to_string(reinterpret_cast<char*>(sha256_buffer)); 
    ripemd160(&hash256_string[0], ripemd160_buffer); 
    printf("%s\n", ripemd160_buffer); 
    return 0; 
} 

私のripemd160機能は次のとおりです。

void ripemd160(char *string, char outputBuffer[41]) 
{ 
    unsigned char hash[RIPEMD160_DIGEST_LENGTH]; 
    RIPEMD160_CTX ripemd160; 
    RIPEMD160_Init(&ripemd160); 
    RIPEMD160_Update(&ripemd160, string, strlen(string)); 
    RIPEMD160_Final(hash, &ripemd160); 
    for (int i = 0; i < RIPEMD160_DIGEST_LENGTH; i++) 
    { 
     sprintf_s(outputBuffer + (i * 2), sizeof(outputBuffer + (i * 2)), "%02x", hash[i]); 
    } 
    outputBuffer[40] = 0; 
} 
ここ

は、文字列関数への私の六角です:

string hex_to_string(const string& in) 
{ 
    string output; 
    if ((in.length() % 2) != 0) { 
     throw runtime_error("String is not valid length ..."); 
    } 
    size_t cnt = in.length()/2; 
    for (size_t i = 0; cnt > i; ++i) { 
     uint32_t s = 0; 
     stringstream ss; 
     ss << hex << in.substr(i * 2, 2); 
     ss >> s; 
     output.push_back(static_cast<unsigned char>(s)); 
    } 
    return output; 
} 

私は
https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses

これは私が取得すると仮定RIPEMD-160であるから例を使用しています:
010966776006953D5567439E5E39F86A0D273BEE

この私が実際に手に入れているRipemd-160です:
6c9814cf2a93131c8d3263158896e786de7a3f21

答えて

1

SHA-256ハッシュを最初に16進文字列に変換するのではなく、SHA-256ハッシュの生のバイトをRIPEMD-160関数に渡す必要があります。

これはopensslコマンドラインツールを使用して確認できます。期待値が一致していない16進文字列の

$ echo -n '600FFE422B4E00731A59557A5CCA46CC183944191006324A447BDB2D98D4B408' | 
> xxd -p -r | openssl rmd160 
(stdin)= 010966776006953d5567439e5e39f86a0d273bee 

RIPEMD-160:期待値と一致した生のバイトの

RIPEMD-160、同様

$ echo -n '600FFE422B4E00731A59557A5CCA46CC183944191006324A447BDB2D98D4B408' | 
> openssl rmd160 
(stdin)= 1435727e0369ab470035797c66215799f258188b 

を、あなたもすべき公開鍵の生のバイトをSHA-256関数に渡す必要があります。最初に公開鍵を16進文字列に変換するのではなく、

$ echo -n '0450863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B23522CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6' | 
> openssl sha256 
(stdin)= 32511e82d56dcea68eb774094e25bab0f8bdd9bc1eca1ceeda38c7a43aceddce 
:期待値と一致しない16進数文字列として公開鍵の

$ echo -n '0450863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B23522CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6' | 
> xxd -p -r | openssl sha256 
(stdin)= 600ffe422b4e00731a59557a5cca46cc183944191006324a447bdb2d98d4b408 

SHA-256:期待値と一致する公開鍵の生のバイトの

SHA-256

+0

私はこのようにしました(メインの変更):
ripemd160(sha256_buffer、ripemd160_buffer);
printf( "%s \ n"、ripemd160_buffer);
RogerT

+0

'sha256_buffer'には生のバイトが含まれています。しかし、この出力は '4c15742656730a77232d1d67dba82f065bd72e67'となります。私はQt5.5を使用しています。 C++、コードで説明してください。ありがとう。 – RogerT

+0

公開鍵の生のバイトを 'SHA-256'関数に渡すべきです。最初に公開鍵を16進文字列に変換するのではなく、 –

関連する問題