>백엔드 개발 >Golang >Ed25519의 Golang과 Bittorrent 개인 키 형식 간의 불일치를 조정하는 방법은 무엇입니까?

Ed25519의 Golang과 Bittorrent 개인 키 형식 간의 불일치를 조정하는 방법은 무엇입니까?

DDD
DDD원래의
2024-10-31 07:06:30595검색

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

ed25519.공개 결과 불일치

이 문제는 ed25519 개인 키의 다양한 형식으로 인해 발생합니다. 키는 SHA512를 사용하여 해시되어 64바이트를 생성하는 32바이트 시드로 시작합니다(이 프로세스 중에 특정 비트가 반전됨).

Golang 개인 키 형식

Golang 개인 키 형식은 32바이트 공개 키와 연결된 32바이트 시드로 구성됩니다.

Bittorrent 개인 키 형식

Bittorrent 개인 키는 64- 해시의 바이트 출력 또는 해시 결과와 동일한 방식으로 사용되는 잠재적으로 단지 64개의 무작위 바이트입니다.

Bittorrent 키를 Golang 형식으로 변환

안타깝게도 Bittorrent 키를 해시 프로세스는 되돌릴 수 없기 때문에 Golang API가 허용하는 형식입니다.

테스트 벡터를 위한 사용자 정의 Golang 구현

이 문제를 해결하기 위해 Golang 라이브러리의 수정된 버전 내부 패키지 golang.org/x/crypto/ed25519/internal/edwards25519를 기반으로 생성할 수 있습니다:

개인 키에서 공개 키를 생성하는 기능

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

시그니처 생성 기능

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

사용예

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

위 내용은 Ed25519의 Golang과 Bittorrent 개인 키 형식 간의 불일치를 조정하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.