Maison > Article > développement back-end > Comment concilier l'écart entre les formats de clé privée Golang et Bittorrent pour 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!