"Se um trabalhador quiser fazer bem o seu trabalho, ele deve primeiro afiar suas ferramentas." - Confúcio, "Os Analectos de Confúcio. Lu Linggong"
Primeira página > Programação > Como reconciliar a discrepância entre os formatos de chave privada Golang e Bittorrent para Ed25519?

Como reconciliar a discrepância entre os formatos de chave privada Golang e Bittorrent para Ed25519?

Publicado em 2024-11-08
Navegar:513

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

ed25519.Discrepância de resultados públicos

O problema surge de diferentes formatos para chaves privadas ed25519. A chave começa como uma semente de 32 bytes que é criptografada usando SHA512 para criar 64 bytes (certos bits são invertidos durante esse processo).

Formato de chave privada Golang

O formato de chave privada Golang compreende a semente de 32 bytes concatenada com a chave pública de 32 bytes.

Chave privada Bittorrent Formato

As chaves privadas do Bittorrent são a saída de 64 bytes do hash ou potencialmente apenas 64 bytes aleatórios usados ​​da mesma forma que o resultado do hash.

Conversão de chaves Bittorrent em Golang Formato

Infelizmente, não é viável converter chaves Bittorrent em um formato que a API Golang aceita porque o processo de hash não é reversível.

Implementação Golang personalizada para vetores de teste

Para resolver esse problema, uma versão modificada da biblioteca Golang baseada no pacote interno golang.org/x/crypto /ed25519/internal/edwards25519 pode ser criado:

Função para gerar chave pública a partir de privada Chave

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

Função para geração de assinatura

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
}

Exemplo de uso

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!")))
Tutorial mais recente Mais>

Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.

Copyright© 2022 湘ICP备2022001581号-3