>  기사  >  백엔드 개발  >  ed25519의 Go 구현이 특정 경우에 예상과 다른 공개 키를 생성하는 이유는 무엇입니까?

ed25519의 Go 구현이 특정 경우에 예상과 다른 공개 키를 생성하는 이유는 무엇입니까?

Mary-Kate Olsen
Mary-Kate Olsen원래의
2024-10-30 17:24:031001검색

Why does the Go implementation of ed25519 generate a different public key than expected in certain cases?

ed25519 공개 키 생성 차이

ed25519 암호화 패키지는 개인 키에서 공개 키를 생성하는 수단을 제공합니다. 그러나 사용자는 Go 구현으로 생성된 공개 키가 특정 사용 사례에서 예상되는 값과 일치하지 않는다는 것을 관찰했습니다.

근본 원인:

이러한 차이 ed25519 개인 키를 나타내는 데 사용되는 다양한 형식에서 발생합니다. Go 패키지는 개인 키가 32바이트 시드와 32바이트 공개 키의 연결로 표시되는 형식을 활용합니다. 반대로 예상 결과를 정의하는 테스트 벡터는 개인 키를 시드 해싱의 64바이트 출력으로 나타냅니다.

해결책:

해싱 프로세스를 반대로 하면 테스트 벡터 개인 키를 Go 구현과 호환되는 형식으로 변환하는 것이 불가능합니다. 또는 대체 개인 키 형식을 지원하는 Go 라이브러리의 수정된 버전을 생성할 수 있습니다.

수정된 라이브러리 코드:

다음 코드 조각은 사용자 정의 버전을 제공합니다. 대체 개인 키 형식을 지원하기 위한 Go 구현:

공개 키 생성:

<code class="go">// Generate the public key corresponding to the already hashed private
// key.
//
// This code is mostly copied from GenerateKey in the
// golang.org/x/crypto/ed25519 package, from after the SHA512
// calculation of the seed.
func getPublicKey(privateKey []byte) []byte {
    var A edwards25519.ExtendedGroupElement
    var hBytes [32]byte
    copy(hBytes[:], privateKey)
    edwards25519.GeScalarMultBase(&amp;A, &amp;hBytes)
    var publicKeyBytes [32]byte
    A.ToBytes(&amp;publicKeyBytes)

    return publicKeyBytes[:]
}</code>

서명:

<code class="go">// Calculate the signature from the (pre hashed) private key, public key
// and message.
//
// This code is mostly copied from the Sign function from
// golang.org/x/crypto/ed25519, from after the SHA512 calculation of the
// seed.
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(&amp;messageDigestReduced, &amp;messageDigest)
    var R edwards25519.ExtendedGroupElement
    edwards25519.GeScalarMultBase(&amp;R, &amp;messageDigestReduced)

    var encodedR [32]byte
    R.ToBytes(&amp;encodedR)

    h.Reset()
    h.Write(encodedR[:])
    h.Write(publicKey)
    h.Write(message)
    h.Sum(hramDigest[:0])
    var hramDigestReduced [32]byte
    edwards25519.ScReduce(&amp;hramDigestReduced, &amp;hramDigest)

    var s [32]byte
    edwards25519.ScMulAdd(&amp;s, &amp;hramDigestReduced, &amp;privateKeyA, &amp;messageDigestReduced)

    signature := make([]byte, 64)
    copy(signature[:], encodedR[:])
    copy(signature[32:], s[:])

    return signature
}</code>

데모:

다음 코드는 예상되는 공개 키와 서명을 생성하기 위해 사용자 정의 함수를 사용하는 방법을 보여줍니다.

<code class="go">privateKeyHex := "e06d3183d14159228433ed599221b80bd0a5ce8352e4bdf0262f76786ef1c74db7e7a9fea2c0eb269d61e3b38e450a22e754941ac78479d6c54e1faf6037881d"

expectedPublicKey := "77ff84905a91936367c01360803104f92432fcd904a43511876df5cdf3e7e548"
expectedSig := "6834284b6b24c3204eb2fea824d82f88883a3d95e8b4a21b8c0ded553d17d17ddf9a8a7104b1258f30bed3787e6cb896fca78c58f8e03b5f18f14951a87d9a08"

privateKey, _ := hex.DecodeString(privateKeyHex)
publicKey := getPublicKey(privateKey)

fmt.Printf("Calculated key: %x\n", publicKey)
fmt.Printf("Expected key:   %s\n", expectedPublicKey)
keyMatches := expectedPublicKey == hex.EncodeToString(publicKey)
fmt.Printf("Public key matches expected: %v\n", keyMatches)

buffer := []byte("4:salt6:foobar3:seqi1e1:v12:Hello World!")
calculatedSig := sign(privateKey, publicKey, buffer)

fmt.Printf("Calculated sig: %x\n", calculatedSig)
fmt.Printf("Expected sig:   %s\n", expectedSig)
sigMatches := expectedSig == hex.EncodeToString(calculatedSig)
fmt.Printf("Signature matches expected: %v\n", sigMatches)</code>

이러한 사용자 정의를 통합하여 기능을 코드에 추가하면 대체 개인 키 형식으로 정의된 테스트 벡터를 처리하고 일치하지 않는 결과가 발생하지 않고 공개 키 생성 및 서명과 같은 작업을 수행할 수 있습니다.

위 내용은 ed25519의 Go 구현이 특정 경우에 예상과 다른 공개 키를 생성하는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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