ホームページ  >  記事  >  バックエンド開発  >  Go パッケージ golang.org/x/crypto/ed25519 を使用して、事前ハッシュされた秘密鍵から正しい公開鍵と署名を取得するにはどうすればよいですか?

Go パッケージ golang.org/x/crypto/ed25519 を使用して、事前ハッシュされた秘密鍵から正しい公開鍵と署名を取得するにはどうすればよいですか?

Susan Sarandon
Susan Sarandonオリジナル
2024-11-01 04:27:02578ブラウズ

How can I derive the correct public key and signature from a prehashed private key using the Go package golang.org/x/crypto/ed25519?

Ed25519 公開鍵の不一致

問題の説明:

Go パッケージの使用 golang.org/x/crypto/ed25519 、指定された秘密鍵から公開鍵を導出しようとすると、指定されたテスト ケースで定義されている予想される公開鍵と比較して異なる結果が生成されます。

根本原因:

この不一致は、異なる ed25519 秘密キー形式の使用から生じます。

秘密キー形式の違い:

  • Go パッケージは、次のような秘密キー形式を想定しています。
  • テスト ケースは、シードに適用されたハッシュの 64 バイトの結果である秘密鍵形式を使用します (または、64 バイトのランダム バイトが使用される可能性があります)。

解決策:

テスト ケースの秘密鍵の生成に使用されたハッシュを逆にすることは現実的ではないため、互換性のある形式に変換します。 Go パッケージは使用できません。

提案された解決策:

テスト ケースの正しい公開キーを取得するには、Go パッケージの修正バージョンを作成できます。次のカスタム関数を利用します:

getPublicKey:

<code class="go">// GetPublicKey generates the public key from the prehashed private key.
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>

sign:

<code class="go">// Sign generates a signature from the prehashed private key, public key, and message.
func sign(privateKey, publicKey, message []byte) []byte {
    var privateKeyA [32]byte
    copy(privateKeyA[:], privateKey)
    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">privateKeyHex := "e06d3183d14159228433ed599221b80bd0a5ce8352e4bdf0262f76786ef1c74db7e7a9fea2c0eb269d61e3b38e450a22e754941ac78479d6c54e1faf6037881d"
privateKey, _ := hex.DecodeString(privateKeyHex)
expectedPublicKey := "77ff84905a91936367c01360803104f92432fcd904a43511876df5cdf3e7e548"
expectedSig := "6834284b6b24c3204eb2fea824d82f88883a3d95e8b4a21b8c0ded553d17d17ddf9a8a7104b1258f30bed3787e6cb896fca78c58f8e03b5f18f14951a87d9a08"
publicKey := getPublicKey(privateKey)
fmt.Printf("Calculated Public Key: %x\n", publicKey)
fmt.Printf("Expected Public Key:   %s\n", expectedPublicKey)
calculatedSig := sign(privateKey, publicKey, []byte("Hello, World!"))
fmt.Printf("Calculated Signature: %x\n", calculatedSig)
fmt.Printf("Expected Signature:   %s\n", expectedSig)</code>

このアプローチでは、テスト ケースで指定されているように、変更された Go パッケージを使用して正しい公開キーと署名を計算できます。

以上がGo パッケージ golang.org/x/crypto/ed25519 を使用して、事前ハッシュされた秘密鍵から正しい公開鍵と署名を取得するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。