Home > Backend Development > Golang > How can I derive the correct public key and signature from a prehashed private key using the Go package golang.org/x/crypto/ed25519?

How can I derive the correct public key and signature from a prehashed private key using the Go package golang.org/x/crypto/ed25519?

Susan Sarandon
Release: 2024-11-01 04:27:02
Original
664 people have browsed it

How can I derive the correct public key and signature from a prehashed private key using the Go package golang.org/x/crypto/ed25519?

Ed25519 Public Key Discrepancy

Problem Description:

Using the Go package golang.org/x/crypto/ed25519, attempts to derive the public key from a given private key produce a different result compared to the expected public key as defined in a given test case.

Root Cause:

The discrepancy arises from the use of different ed25519 private key formats.

Private Key Format Difference:

  • The Go package expects a private key format that consists of the 32-byte seed concatenated with the 32-byte public key.
  • The test case uses a private key format that is the 64-byte result of a hash applied to the seed (or possibly 64 random bytes used as a substitute).

Solution:

Since reversing the hash used to generate the test case private keys is not feasible, conversion to a format compatible with the Go package is not possible.

Proposed Solution:

To obtain the correct public key for the test case, a modified version of the Go package can be created that utilizes the following custom functions:

getPublicKey:

<code class="go">// GetPublicKey generates the public key from the prehashed private key.
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>
Copy after login

sign:

<code class="go">// Sign generates a signature from the prehashed private key, public key, and message.
func sign(privateKey, publicKey, message []byte) []byte {
    var privateKeyA [32]byte
    copy(privateKeyA[:], privateKey)
    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>
Copy after login

Usage Example:

<code class="go">privateKeyHex := "e06d3183d14159228433ed599221b80bd0a5ce8352e4bdf0262f76786ef1c74db7e7a9fea2c0eb269d61e3b38e450a22e754941ac78479d6c54e1faf6037881d"
privateKey, _ := hex.DecodeString(privateKeyHex)
expectedPublicKey := "77ff84905a91936367c01360803104f92432fcd904a43511876df5cdf3e7e548"
expectedSig := "6834284b6b24c3204eb2fea824d82f88883a3d95e8b4a21b8c0ded553d17d17ddf9a8a7104b1258f30bed3787e6cb896fca78c58f8e03b5f18f14951a87d9a08"
publicKey := getPublicKey(privateKey)
fmt.Printf("Calculated Public Key: %x\n", publicKey)
fmt.Printf("Expected Public Key:   %s\n", expectedPublicKey)
calculatedSig := sign(privateKey, publicKey, []byte("Hello, World!"))
fmt.Printf("Calculated Signature: %x\n", calculatedSig)
fmt.Printf("Expected Signature:   %s\n", expectedSig)</code>
Copy after login

This approach allows for the calculation of the correct public key and signature using the modified Go package, as specified in the test case.

The above is the detailed content of How can I derive the correct public key and signature from a prehashed private key using the Go package golang.org/x/crypto/ed25519?. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template