Heim >Backend-Entwicklung >Golang >Wie kann die Diskrepanz zwischen den privaten Schlüsselformaten von Golang und Bittorrent für Ed25519 ausgeglichen werden?

Wie kann die Diskrepanz zwischen den privaten Schlüsselformaten von Golang und Bittorrent für Ed25519 ausgeglichen werden?

DDD
DDDOriginal
2024-10-31 07:06:30596Durchsuche

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

ed25519.Public Result Discrepancy

Das Problem ergibt sich aus unterschiedlichen Formaten für private Schlüssel von ed25519. Der Schlüssel beginnt als 32-Byte-Seed, der mit SHA512 gehasht wird, um 64 Bytes zu erstellen (bestimmte Bits werden während dieses Prozesses umgedreht).

Golang Private Key Format

Das Golang-Privatschlüsselformat besteht aus dem 32-Byte-Startwert, der mit dem 32-Byte-Öffentlichkeitsschlüssel verkettet ist.

Bittorrent-Privatschlüsselformat

Die privaten Bittorrent-Schlüssel sind die 64- Byte-Ausgabe des Hashs oder möglicherweise nur 64 zufällige Bytes, die auf die gleiche Weise wie das Hash-Ergebnis verwendet werden.

Konvertieren von Bittorrent-Schlüsseln in das Golang-Format

Leider ist es nicht möglich, Bittorrent-Schlüssel in ein zu konvertieren Format, das die Golang-API akzeptiert, da der Hash-Prozess nicht umkehrbar ist.

Benutzerdefinierte Golang-Implementierung für Testvektoren

Um dieses Problem zu beheben, eine modifizierte Version der Golang-Bibliothek Basierend auf dem internen Paket golang.org/x/crypto/ed25519/internal/edwards25519 kann erstellt werden:

Funktion zum Generieren eines öffentlichen Schlüssels aus einem privaten Schlüssel

<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>

Funktion zur Signaturgenerierung

<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>

Beispielverwendung

<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>

Das obige ist der detaillierte Inhalt vonWie kann die Diskrepanz zwischen den privaten Schlüsselformaten von Golang und Bittorrent für Ed25519 ausgeglichen werden?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn