🦀

RustでECDSA公開鍵からBTCアドレスを生成

2024/05/07に公開

はじめに

2024年4月からブロックチェーン公開講座を受講しています。今までなんとなく漠然と理解していたことを知識として体系的に整理できて、とてもありがたい講座です。

第2回『ビットコインその1』ではECDSAの公開鍵からBTCアドレスを生成する方法について学びましたので、その復習のためRustで試してみました。

RustとBlockchainの学習を目的として書いたものですので、実運用では信頼できるライブラリをお使いください。

アルゴリズム

ECDSA公開鍵からBTCアドレスを生成する流れは以下になります。

  1. ECDSA公開鍵をSHA256でハッシュ化する
  2. 1をRIPEMD160でハッシュ化する
  3. 2の先頭にバージョン情報1バイトを付与する
  4. 3をSHA256で2回ハッシュ化してその先頭4バイトを3の末尾に付与する
  5. 4をBase58エンコードする

プロジェクトの作成

$ cargo new study
$ cd study

依存パッケージの追加

$ cargo add base-x hex_literal ripemd sha2

src/main.rsの編集

src/main.rs
use hex_literal::hex;
use ripemd::{Ripemd160, Digest};
use sha2::Sha256;

fn get_btc_address(public_key: &[u8; 65]) -> String {
    // STEP-1: SHA-256
    let mut hasher = Sha256::new();
    hasher.update(public_key);
    let hashed_sha256 = hasher.finalize();

    // STEP-2: RIPEMD160
    let mut hasher = Ripemd160::new();
    hasher.update(&hashed_sha256);
    let account_id = hasher.finalize();

    // STEP-3: Payload (Starting with 0x00)
    let mut payload = account_id.to_vec();
    payload.insert(0, 0x0);

    // STEP-4: Append checksum (sha256 x 2)
    let mut hasher = Sha256::new();
    hasher.update(&payload);
    let hash = hasher.finalize();
    let mut hasher = Sha256::new();
    hasher.update(hash);
    let checksum = hasher.finalize();
    payload.append(&mut checksum[0..4].to_vec());

    // STEP-5: Base58
    const ALPHABET: &str = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
    base_x::encode(ALPHABET, &payload)
}

fn main() {
    // Public key
    let public_key = &hex!(
        "04F028892BAD7ED57D2FB57BF33081D5CFCF6F9ED3D3D7F159C2E2FFF579DC341A07CF33DA18BD734C600B96A72BBC4749D5141C90EC8AC328AE52DDFE2E505BDB"
    );

    // BTC Address
    let btc_address = get_btc_address(public_key);
    println!("BTC Address: {}", btc_address);
}

※ECDSA公開鍵(04:非圧縮; 512bit)は、ブロックチェーン公開講座の資料に記載されているものと同じ値を使用しています。

プログラムの実行

$ cargo run
   Compiling study v0.1.0 (/home/toshio/workspace/rustcrypto/rust_crypto_02_btc_address)
    Finished dev [unoptimized + debuginfo] target(s) in 0.23s
     Running `target/debug/study`
BTC Address: 1424C2F4bC9JidNjjTUZCbUxv6Sa1Mt62x

講座の公開資料と同じBTCアドレスを取得することができました。

Discussion