Search code examples
gocryptographyed25519

Get public key from private ED25519 Go


I am attempting to extract a public key from a private key using ED25519 with Go.

I pass my private key byte value into my method, create a new ed25519 private key struct from it, and then use the .Public() method to retrieve the public key.

pk := ed25519.PrivateKey(privateKey).Public()
cpk, ok := pk.(ed25519.PublicKey)
if !ok {
    return nil, errors.New("problem casting public key to ed25519 public key")
}

It's not erroring but the resulting public key byte is always empty, is there something I'm doing incorrectly when creating the private key struct?


Solution

  • The ed25519 package has this important comment in the overview:

    ... unlike RFC 8032's formulation, this package's private key representation includes a public key suffix to make multiple signing operations with the same key more efficient. This package refers to the RFC 8032 private key as the “seed”.

    This means that it uses the following equivalences and terminology:

    • RFC 8032 private key: 32 bytes, known as "seed" in this package
    • RFC 8032 private key and public key concateneated: 64 bytes, known as "private key" in this package

    If you already have a 64 byte slice consisting of RFC 8032 <private key><public key>, you can use the code in your question.

    If you only have the a 32 byte slice consisting of RFC 8032 <private key>, you need to calculate the public key as follows:

    // Compute the full 64 byte <private key><public key> from the private key
    priv := ed25519.NewKeyFromSeed(32bytePrivateKey)
    
    // Print out the public key (the last 32 bytes)
    fmt.Println(priv.Public())
    

    Please note: ed25519.PrivateKey and ed25519.PublicKey are both type []byte.