Maison  >  Article  >  développement back-end  >  Comment concilier l'écart entre les formats de clé privée Golang et Bittorrent pour Ed25519 ?

Comment concilier l'écart entre les formats de clé privée Golang et Bittorrent pour Ed25519 ?

DDD
DDDoriginal
2024-10-31 07:06:30521parcourir

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

ed25519.Différence de résultat public

Le problème provient de différents formats pour les clés privées ed25519. La clé commence par une graine de 32 octets qui est hachée à l'aide de SHA512 pour créer 64 octets (certains bits sont inversés au cours de ce processus).

Format de clé privée Golang

Le format de clé privée Golang comprend la graine de 32 octets concaténée avec la clé publique de 32 octets.

Format de clé privée Bittorrent

Les clés privées Bittorrent sont les 64- sortie d'octets du hachage ou potentiellement seulement 64 octets aléatoires utilisés de la même manière que le résultat du hachage.

Conversion des clés Bittorrent au format Golang

Malheureusement, il n'est pas possible de convertir les clés Bittorrent en un format accepté par l'API Golang car le processus de hachage n'est pas réversible.

Implémentation Golang personnalisée pour les vecteurs de test

Pour résoudre ce problème, une version modifiée de la bibliothèque Golang basé sur le package interne golang.org/x/crypto/ed25519/internal/edwards25519 peut être créé :

Fonction de génération de clé publique à partir de clé privée

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

Fonction de génération de signature

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

Exemple d'utilisation

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

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn