"Si un ouvrier veut bien faire son travail, il doit d'abord affûter ses outils." - Confucius, "Les Entretiens de Confucius. Lu Linggong"
Page de garde > La programmation > 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 ?

Publié le 2024-11-08
Parcourir:361

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 pour générer une clé publique à partir d'une clé privée

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[:]
}

Fonction pour la génération de signature

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
}

Exemple d'utilisation

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!")))
Dernier tutoriel Plus>

Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.

Copyright© 2022 湘ICP备2022001581号-3