paint-brush
Python を使用して秘密キーからイーサリアム アドレスを生成する方法@rareskills
6,339 測定値
6,339 測定値

Python を使用して秘密キーからイーサリアム アドレスを生成する方法

RareSkills4m2023/06/01
Read on Terminal Reader

長すぎる; 読むには

イーサリアム アドレスは、公開キーの kecck256 の最後の 20 バイトです。公開鍵アルゴリズムは secp256k1 で、ビットコインで使用されているものと同じです。 これは楕円曲線アルゴリズムであるため、公開鍵は (x, y) ペアであり、楕円曲線上の点に対応します。
featured image - Python を使用して秘密キーからイーサリアム アドレスを生成する方法
RareSkills HackerNoon profile picture
0-item
1-item
2-item

イーサリアム アドレスは、公開キーの kecck256 の最後の 20 バイトです。公開鍵アルゴリズムは secp256k1 で、ビットコインで使用されているものと同じです。


これは楕円曲線アルゴリズムであるため、公開鍵は (x, y) ペアであり、楕円曲線上の点に対応します。

楕円曲線公開鍵を生成します。

公開キーは x と y を連結したものであり、それからハッシュが取得されます。

コードを以下に示します。


 from ecpy.curves import Curve from ecpy.keys import ECPublicKey, ECPrivateKey from sha3 import keccak_256 private_key = 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 cv = Curve.get_curve('secp256k1') pv_key = ECPrivateKey(private_key, cv) pu_key = pv_key.get_public_key() # equivalent alternative for illustration: # concat_x_y = bytes.fromhex(hex(pu_key.Wx)[2:] + hex(pu_key.Wy)[2:]) concat_x_y = pu_key.Wxto_bytes(32, byteorder='big') + pu_key.Wyto_bytes(32, byteorder='big') eth_addr = '0x' + keccak_256(concat_x_y).digest()[-20:].hex() print('private key: ', hex(private_key)) print('eth_address: ', eth_addr)


ecpy ライブラリはここhttps://github.com/cslashm/ECPyにあります。このライブラリは Python で楕円曲線計算を実装しているため、 coincurveライブラリで使用されるビットコイン C 実装のラッパーほど高速ではありません。


ただし、Python 実装では、公開キーの導出に使用される楕円曲線の計算を段階的に確認できます。


このコードを使用すると、ブルート フォースでイーサリアム バニティ アドレスを生成できますが、ランダム性のソースが安全でないか、ランダム性が不十分な場合は、これと同様のハッキングの被害に遭う可能性があることに注意してください。

Python とコイン投げまたはサイコロで秘密鍵を生成する

コインを 256 回投げ、表の場合は 1、裏の場合は 0 を文字列に書き込むことで、秘密鍵からイーサリアム アドレスを自分で生成できます。

次の結果が得られたとします。

 result = b'1100001011001101010001001100101000001111101101111011001000110001101100011101101011010001011000101111100110010101001001101110111011001000100001010101111100001100100110010010111110110100000010011111100000110101001110000101100101011111001101010001100001000'


次の Python コードを使用して、それを秘密キーに変換できます。


 # 2 means base 2 for binary private_key = hex(int(result, 2)) # private key is 0x1859a89941f6f646363b5a2c5f32a4ddd910abe19325f6813f06a70b2be6a308


次に、その秘密キーを上記のセクションのコードに組み込むと、独自のランダム性を使用してアドレスが生成されます。


16 面サイコロを 64 回振って、生成される 16 進文字列を 1 文字ずつ書き出すことで、同じことをより速く実行できます。ほとんどのサイコロには数字の 0 が表現されていないため、各出目から 1 を減算する必要があることに注意してください。


従来の 6 面しか持っていない場合は、基数 6 で文字列を書き出し (各ロールから 1 を引くことを忘れないでください)、バイナリへの基数変換を行うことができます。秘密鍵が少なくとも 256 ビットになるまで、ローリングを続ける必要があります。ランダム性について特に心配な場合は、カジノグレードのサイコロを使用できます。


Python の組み込み乱数ライブラリを使用する場合は注意してください。暗号的に安全であることを目的としたものではありません。このトピックに慣れていない場合は、暗号的に安全なランダム性についてよく理解しておくことをお勧めします。


一般に、この方法を使用してハードウェア ウォレットを初期化することはできません。ハードウェア ウォレットで使用される 24 ワードのリカバリ フレーズは、トランザクションの署名に使用される秘密キーと同じではないからです。 24 ワードのリカバリ フレーズは、ウォレットが保持するさまざまなタイプの暗号に対する複数の秘密キーを導出するために使用されます。

数学: secp256k1: 秘密鍵からの公開鍵について

曲線の追加が視覚的にどのようなものかを説明するオンライン資料はすでにたくさんあるので、ここではより低いレベルで説明します。

曲線の形状

Secp256k1 は、楕円曲線 y^2 = x^3 + y (mod p) の形状を定義します。ここで、p は素数115792089237316195423570985008687907853269984665640564039457584007908834671663

または2^256 – 2^32 – 977


素数p を曲線の次数と混同しないでください。 0 < n < p のすべての値が上記の式を満たすわけではありません。ただし、曲線上の操作は閉じられることが保証されています。つまり、2 つの有効な点を加算または乗算すると、その結果は曲線上の有効な数値になります。

出発点

secp256k1 のもう 1 つの重要なパラメーターは開始点 G です。G は楕円曲線上の点であるため、2 次元であり、次のパラメーターを持ちます。

 x = 55066263022277343669578718895168534326250603453777594175500187360389116729240 y = 32670510020758816978083085130507043184471273380659243275938904335757337482424


G が有効な点であることを確認するには、数値を Python に代入します。

 x = 55066263022277343669578718895168534326250603453777594175500187360389116729240 y = 32670510020758816978083085130507043184471273380659243275938904335757337482424 p = 115792089237316195423570985008687907853269984665640564039457584007908834671663 assert pow(y, 2, p) == (pow(x, 3) + 7) % p

公開鍵と秘密鍵のペアを作成するには、乱数sが作成されます (これが秘密鍵です)。点 G はそれ自身にs回追加され、新しい点 (x, y) が公開鍵になります。 G からs を導出するのは現実的ではありません。


G をそれ自身に s 回加算することは、s * G を乗算することと同じです。実際、ライブラリが提供する抽象化の一部を取り除くことによって、この演算をより低いレベルで見ることができます。


 from ecpy.curves import Curve from sha3 import keccak_256 private_key = 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 cv = Curve.get_curve('secp256k1') pu_key = private_key * cv.generator # just multiplying the private key by generator point (EC multiplication) concat_x_y = pu_key.x.to_bytes(32, byteorder='big') + pu_key.y.to_bytes(32, byteorder='big') eth_addr = '0x' + keccak_256(concat_x_y).digest()[-20:].hex() print('private key: ', hex(private_key)) print('eth_address: ', eth_addr)


公開キーは、単純に秘密キーに secp256k1 楕円曲線上の点 G を乗算したものです。それでおしまい。

もっと詳しく知る

今すぐ高度なブロックチェーン ブートキャンプをチェックして、他のプログラマーが知らない難しいことを理解できるブロックチェーン開発者になりましょう。


ここでも公開されています。