ホームページ > バックエンド開発 > Golang > Ed25519 の Golang と Bittorrent の秘密鍵形式の不一致を調整するにはどうすればよいですか?

Ed25519 の Golang と Bittorrent の秘密鍵形式の不一致を調整するにはどうすればよいですか?

DDD
リリース: 2024-10-31 07:06:30
オリジナル
602 人が閲覧しました

How to reconcile the discrepancy between Golang and Bittorrent private key formats for Ed25519?

ed25519.公開結果の不一致

この問題は、ed25519 秘密鍵の形式が異なるために発生します。キーは 32 バイトのシードとして開始され、SHA512 を使用してハッシュされて 64 バイトが作成されます (このプロセス中に特定のビットが反転されます)。

Golang 秘密鍵形式

Golang 秘密鍵形式は、32 バイトの公開鍵と連結された 32 バイトのシードで構成されます。

Bittorrent 秘密鍵形式

Bittorrent 秘密鍵は 64-ハッシュのバイト出力、またはハッシュ結果と同じ方法で使用される可能性のある 64 のランダム バイト。

Bittorrent キーを Golang 形式に変換

残念ながら、Bittorrent キーを Golang 形式に変換することは現実的ではありません。ハッシュ プロセスは元に戻せないため、Golang API が受け入れる形式です。

テスト ベクター用のカスタム Golang 実装

この問題に対処するには、Golang ライブラリの修正バージョンが必要です。内部パッケージ golang.org/x/crypto/ed25519/internal/edwards25519 に基づいて作成できます:

秘密鍵から公開鍵を生成する関数

<code class="go">func getPublicKey(privateKey []byte) []byte {
    var A edwards25519.ExtendedGroupElement
    var hBytes [32]byte
    copy(hBytes[:], privateKey)
    edwards25519.GeScalarMultBase(&A, &hBytes)
    var publicKeyBytes [32]byte
    A.ToBytes(&publicKeyBytes)

    return publicKeyBytes[:]
}</code>
ログイン後にコピー

署名生成関数

<code class="go">func sign(privateKey, publicKey, message []byte) []byte {

    var privateKeyA [32]byte
    copy(privateKeyA[:], privateKey) // we need this in an array later
    var messageDigest, hramDigest [64]byte

    h := sha512.New()
    h.Write(privateKey[32:])
    h.Write(message)
    h.Sum(messageDigest[:0])

    var messageDigestReduced [32]byte
    edwards25519.ScReduce(&messageDigestReduced, &messageDigest)
    var R edwards25519.ExtendedGroupElement
    edwards25519.GeScalarMultBase(&R, &messageDigestReduced)

    var encodedR [32]byte
    R.ToBytes(&encodedR)

    h.Reset()
    h.Write(encodedR[:])
    h.Write(publicKey)
    h.Write(message)
    h.Sum(hramDigest[:0])
    var hramDigestReduced [32]byte
    edwards25519.ScReduce(&hramDigestReduced, &hramDigest)

    var s [32]byte
    edwards25519.ScMulAdd(&s, &hramDigestReduced, &privateKeyA, &messageDigestReduced)

    signature := make([]byte, 64)
    copy(signature[:], encodedR[:])
    copy(signature[32:], s[:])

    return signature
}</code>
ログイン後にコピー

使用例

<code class="go">const privateKeyHex = "e06d3183d14159228433ed599221b80bd0a5ce8352e4bdf0262f76786ef1c74db7e7a9fea2c0eb269d61e3b38e450a22e754941ac78479d6c54e1faf6037881d"

const expectedPublicKey = "77ff84905a91936367c01360803104f92432fcd904a43511876df5cdf3e7e548"
const expectedSig = "6834284b6b24c3204eb2fea824d82f88883a3d95e8b4a21b8c0ded553d17d17ddf9a8a7104b1258f30bed3787e6cb896fca78c58f8e03b5f18f14951a87d9a08"

privateKey, _ := hex.DecodeString(privateKeyHex)
publicKey := getPublicKey(privateKey)

keyMatches := expectedPublicKey == hex.EncodeToString(publicKey)
sigMatches := expectedSig == hex.EncodeToString(sign(privateKey, publicKey, []byte("4:salt6:foobar3:seqi1e1:v12:Hello World!")))</code>
ログイン後にコピー

以上がEd25519 の Golang と Bittorrent の秘密鍵形式の不一致を調整するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート