ed25519

package
v1.2.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 1, 2026 License: Apache-2.0 Imports: 5 Imported by: 0

README

Ed25519

Ed25519 digital signature cryptography implementation.

Overview

The ed25519 package provides a high-level interface for Ed25519 public-key signatures based on the elliptic curve Ed25519. It simplifies key generation, signing, and verification operations with support for multiple key formats including PEM, PKCS8, PKIX, and SSH.

Features

  • Key Pair Generation - Cryptographically secure random key generation
  • Digital Signatures - Sign and verify messages with 128-bit security
  • Multiple Formats - PEM/PKCS8/PKIX/SSH format support
  • Type Safety - Separate types for private and public keys
  • Key Derivation - Automatic public key derivation from private key

Installation

go get -u github.com/common-library/go/security/crypto/ed25519

Quick Start

import "github.com/common-library/go/security/crypto/ed25519"

// Generate key pair
keyPair := &ed25519.KeyPair{}
keyPair.Generate()

// Sign message
signature := keyPair.Sign("Hello, World!")

// Verify signature
valid := keyPair.Verify("Hello, World!", signature)

API Reference

KeyPair Type
type KeyPair struct {
    privateKey PrivateKey
    publicKey  PublicKey
}

Container for Ed25519 private and public key pair.

KeyPair Methods
Generate
func (kp *KeyPair) Generate() error

Generates a new random Ed25519 key pair.

Sign
func (kp *KeyPair) Sign(message string) []byte

Creates a 64-byte signature for the message.

Verify
func (kp *KeyPair) Verify(message string, signature []byte) bool

Verifies a signature matches the message.

GetKeyPair
func (kp *KeyPair) GetKeyPair() (privateKey PrivateKey, publicKey PublicKey)

Retrieves the private and public keys.

SetKeyPair
func (kp *KeyPair) SetKeyPair(privateKey PrivateKey, publicKey PublicKey)

Sets the private and public keys.

PrivateKey Type
type PrivateKey struct {
    privateKey ed25519.PrivateKey
    publicKey  ed25519.PublicKey
}

Ed25519 private key (64 bytes: 32-byte seed + 32-byte public key).

PrivateKey Methods
Sign
func (pk *PrivateKey) Sign(message string) []byte

Creates a digital signature.

Verify
func (pk *PrivateKey) Verify(message string, signature []byte) bool

Verifies a signature using the associated public key.

Get
func (pk *PrivateKey) Get() ed25519.PrivateKey

Gets the underlying ed25519.PrivateKey.

Set
func (pk *PrivateKey) Set(privateKey ed25519.PrivateKey)

Sets the private key.

SetDefault
func (pk *PrivateKey) SetDefault() error

Generates a new random private key.

GetPemPKCS8
func (pk *PrivateKey) GetPemPKCS8() (string, error)

Returns the private key in PEM-encoded PKCS#8 format.

SetPemPKCS8
func (pk *PrivateKey) SetPemPKCS8(pemPKCS8 string) error

Sets the private key from PEM-encoded PKCS#8.

GetPublicKey
func (pk *PrivateKey) GetPublicKey() PublicKey

Derives the public key from the private key.

PublicKey Type
type PublicKey struct {
    publicKey ed25519.PublicKey
}

Ed25519 public key (32 bytes).

PublicKey Methods
Verify
func (pk *PublicKey) Verify(message string, signature []byte) bool

Verifies a digital signature.

Get
func (pk *PublicKey) Get() ed25519.PublicKey

Gets the underlying ed25519.PublicKey.

Set
func (pk *PublicKey) Set(publicKey ed25519.PublicKey)

Sets the public key.

GetPemPKIX
func (pk *PublicKey) GetPemPKIX() (string, error)

Returns the public key in PEM-encoded PKIX format.

SetPemPKIX
func (pk *PublicKey) SetPemPKIX(pemPKIX string) error

Sets the public key from PEM-encoded PKIX.

GetSsh
func (pk *PublicKey) GetSsh() (string, error)

Returns the public key in SSH authorized_keys format.

SetSsh
func (pk *PublicKey) SetSsh(sshKey string) error

Sets the public key from SSH format.

GetSshPublicKey
func (pk *PublicKey) GetSshPublicKey() (ssh.PublicKey, error)

Gets the key as ssh.PublicKey.

SetSshPublicKey
func (pk *PublicKey) SetSshPublicKey(publicKey ssh.PublicKey) error

Sets the key from ssh.PublicKey.

Complete Examples

Basic Signing and Verification
package main

import (
    "fmt"
    "log"
    "github.com/common-library/go/security/crypto/ed25519"
)

func main() {
    // Generate key pair
    keyPair := &ed25519.KeyPair{}
    err := keyPair.Generate()
    if err != nil {
        log.Fatal(err)
    }
    
    // Sign message
    message := "Hello, World!"
    signature := keyPair.Sign(message)
    fmt.Printf("Signature: %x\n", signature)
    
    // Verify signature
    valid := keyPair.Verify(message, signature)
    if valid {
        fmt.Println("✓ Signature is valid")
    } else {
        fmt.Println("✗ Signature is invalid")
    }
}
Exporting and Importing Keys (PEM Format)
package main

import (
    "fmt"
    "log"
    "github.com/common-library/go/security/crypto/ed25519"
)

func main() {
    // Generate key pair
    keyPair := &ed25519.KeyPair{}
    keyPair.Generate()
    
    // Extract keys
    privateKey, publicKey := keyPair.GetKeyPair()
    
    // Export to PEM
    privatePem, err := privateKey.GetPemPKCS8()
    if err != nil {
        log.Fatal(err)
    }
    
    publicPem, err := publicKey.GetPemPKIX()
    if err != nil {
        log.Fatal(err)
    }
    
    fmt.Println("Private Key (PEM):")
    fmt.Println(privatePem)
    
    fmt.Println("Public Key (PEM):")
    fmt.Println(publicPem)
    
    // Import from PEM
    newPrivateKey := &ed25519.PrivateKey{}
    err = newPrivateKey.SetPemPKCS8(privatePem)
    if err != nil {
        log.Fatal(err)
    }
    
    newPublicKey := &ed25519.PublicKey{}
    err = newPublicKey.SetPemPKIX(publicPem)
    if err != nil {
        log.Fatal(err)
    }
    
    // Verify imported keys work
    signature := newPrivateKey.Sign("test")
    valid := newPublicKey.Verify("test", signature)
    fmt.Printf("Imported keys valid: %v\n", valid)
}
SSH Key Format
package main

import (
    "fmt"
    "log"
    "github.com/common-library/go/security/crypto/ed25519"
)

func main() {
    // Generate key pair
    keyPair := &ed25519.KeyPair{}
    keyPair.Generate()
    
    _, publicKey := keyPair.GetKeyPair()
    
    // Export to SSH format
    sshKey, err := publicKey.GetSsh()
    if err != nil {
        log.Fatal(err)
    }
    
    fmt.Println("SSH Public Key:")
    fmt.Println(sshKey)
    
    // Import from SSH format
    newPublicKey := &ed25519.PublicKey{}
    err = newPublicKey.SetSsh(sshKey)
    if err != nil {
        log.Fatal(err)
    }
    
    // Verify works
    signature := keyPair.Sign("test")
    valid := newPublicKey.Verify("test", signature)
    fmt.Printf("SSH key import successful: %v\n", valid)
}
Separate Private and Public Key Operations
package main

import (
    "fmt"
    "log"
    "github.com/common-library/go/security/crypto/ed25519"
)

func main() {
    // Generate private key
    privateKey := &ed25519.PrivateKey{}
    err := privateKey.SetDefault()
    if err != nil {
        log.Fatal(err)
    }
    
    // Derive public key
    publicKey := privateKey.GetPublicKey()
    
    // Sign with private key
    message := "Secure message"
    signature := privateKey.Sign(message)
    
    // Verify with public key
    valid := publicKey.Verify(message, signature)
    fmt.Printf("Signature valid: %v\n", valid)
    
    // Export public key for sharing
    publicPem, _ := publicKey.GetPemPKIX()
    fmt.Println("\nShare this public key:")
    fmt.Println(publicPem)
}
Message Authentication
package main

import (
    "fmt"
    "log"
    "github.com/common-library/go/security/crypto/ed25519"
)

func authenticateMessage(message string, signature []byte, publicKeyPem string) bool {
    publicKey := &ed25519.PublicKey{}
    err := publicKey.SetPemPKIX(publicKeyPem)
    if err != nil {
        log.Printf("Invalid public key: %v", err)
        return false
    }
    
    return publicKey.Verify(message, signature)
}

func main() {
    // Sender generates key pair
    keyPair := &ed25519.KeyPair{}
    keyPair.Generate()
    
    _, publicKey := keyPair.GetKeyPair()
    publicPem, _ := publicKey.GetPemPKIX()
    
    // Sender signs message
    message := "Authenticated message"
    signature := keyPair.Sign(message)
    
    // Receiver verifies message
    valid := authenticateMessage(message, signature, publicPem)
    if valid {
        fmt.Println("✓ Message authenticated")
    } else {
        fmt.Println("✗ Message authentication failed")
    }
    
    // Try with tampered message
    tamperedMessage := "Tampered message"
    valid = authenticateMessage(tamperedMessage, signature, publicPem)
    if !valid {
        fmt.Println("✓ Tampered message detected")
    }
}
Key Storage and Loading
package main

import (
    "fmt"
    "log"
    "os"
    "github.com/common-library/go/security/crypto/ed25519"
)

func saveKeys(privateKeyPath, publicKeyPath string, keyPair *ed25519.KeyPair) error {
    privateKey, publicKey := keyPair.GetKeyPair()
    
    // Save private key
    privatePem, err := privateKey.GetPemPKCS8()
    if err != nil {
        return err
    }
    
    err = os.WriteFile(privateKeyPath, []byte(privatePem), 0600)
    if err != nil {
        return err
    }
    
    // Save public key
    publicPem, err := publicKey.GetPemPKIX()
    if err != nil {
        return err
    }
    
    err = os.WriteFile(publicKeyPath, []byte(publicPem), 0644)
    if err != nil {
        return err
    }
    
    return nil
}

func loadKeys(privateKeyPath, publicKeyPath string) (*ed25519.KeyPair, error) {
    // Load private key
    privatePem, err := os.ReadFile(privateKeyPath)
    if err != nil {
        return nil, err
    }
    
    privateKey := &ed25519.PrivateKey{}
    err = privateKey.SetPemPKCS8(string(privatePem))
    if err != nil {
        return nil, err
    }
    
    // Load public key
    publicPem, err := os.ReadFile(publicKeyPath)
    if err != nil {
        return nil, err
    }
    
    publicKey := &ed25519.PublicKey{}
    err = publicKey.SetPemPKIX(string(publicPem))
    if err != nil {
        return nil, err
    }
    
    // Create key pair
    keyPair := &ed25519.KeyPair{}
    keyPair.SetKeyPair(*privateKey, *publicKey)
    
    return keyPair, nil
}

func main() {
    // Generate and save keys
    keyPair := &ed25519.KeyPair{}
    keyPair.Generate()
    
    err := saveKeys("private.pem", "public.pem", keyPair)
    if err != nil {
        log.Fatal(err)
    }
    
    fmt.Println("Keys saved")
    
    // Load keys
    loadedKeyPair, err := loadKeys("private.pem", "public.pem")
    if err != nil {
        log.Fatal(err)
    }
    
    // Verify loaded keys work
    signature := loadedKeyPair.Sign("test")
    valid := loadedKeyPair.Verify("test", signature)
    fmt.Printf("Loaded keys work: %v\n", valid)
}

Best Practices

1. Protect Private Keys
// Good: Restrict private key file permissions
os.WriteFile("private.pem", privatePem, 0600) // Owner read/write only

// Avoid: World-readable private keys
os.WriteFile("private.pem", privatePem, 0644) // Insecure
2. Verify Message Integrity
// Good: Always verify before trusting message
if publicKey.Verify(message, signature) {
    processMessage(message)
}

// Avoid: Trust without verification
processMessage(message) // Dangerous!
3. Use Deterministic Signatures
// Good: Ed25519 signatures are deterministic
sig1 := privateKey.Sign("message")
sig2 := privateKey.Sign("message")
// sig1 == sig2 for same key and message

// This is a security feature - no random nonces needed
4. Handle Errors Properly
// Good: Check all error returns
privatePem, err := privateKey.GetPemPKCS8()
if err != nil {
    return fmt.Errorf("failed to export key: %w", err)
}

// Avoid: Ignore errors
privatePem, _ := privateKey.GetPemPKCS8()

Performance Tips

  1. Reuse Key Pairs - Generate once, reuse many times
  2. Public Key Distribution - Share public keys freely, signatures are fast to verify
  3. Batch Verification - Verify multiple signatures in parallel for throughput
  4. Key Storage - Cache loaded keys in memory during application lifetime

Security Considerations

  1. Private Key Protection - Never expose private keys
  2. Message Hashing - Ed25519 can sign messages of any length directly
  3. Signature Size - Always 64 bytes regardless of message size
  4. Security Level - 128-bit security (equivalent to 3072-bit RSA)
  5. Deterministic - Same message and key always produce same signature

Testing

func TestEd25519(t *testing.T) {
    keyPair := &ed25519.KeyPair{}
    err := keyPair.Generate()
    if err != nil {
        t.Fatalf("Failed to generate: %v", err)
    }
    
    message := "test message"
    signature := keyPair.Sign(message)
    
    if len(signature) != 64 {
        t.Errorf("Expected 64-byte signature, got %d", len(signature))
    }
    
    valid := keyPair.Verify(message, signature)
    if !valid {
        t.Error("Signature verification failed")
    }
    
    // Test wrong message
    invalid := keyPair.Verify("wrong message", signature)
    if invalid {
        t.Error("Should reject wrong message")
    }
}

Dependencies

  • crypto/ed25519 - Go standard library
  • crypto/rand - Cryptographic random generator
  • crypto/x509 - X.509 encoding
  • encoding/pem - PEM encoding
  • golang.org/x/crypto/ssh - SSH key formats

Further Reading

Documentation

Overview

Package ed25519 provides Ed25519 digital signature cryptography.

This package implements Ed25519 public-key signature system based on the elliptic curve Ed25519. It provides key generation, signing, and verification operations with simplified interfaces for key pair management.

Features

  • Ed25519 key pair generation
  • Digital signature creation and verification
  • PEM/PKCS8/PKIX format support
  • SSH public key format conversion
  • Type-safe key management

Basic Example

keyPair := &ed25519.KeyPair{}
err := keyPair.Generate()
signature := keyPair.Sign("message")
valid := keyPair.Verify("message", signature)

Package ed25519 provides Ed25519 digital signature cryptography.

This package implements Ed25519 public-key signature system based on the elliptic curve Ed25519. It provides key generation, signing, and verification operations with simplified interfaces for key pair management.

Features

  • Ed25519 key pair generation
  • Digital signature creation and verification
  • PEM/PKCS8/PKIX format support
  • SSH public key format conversion
  • Type-safe key management

Basic Example

privateKey := &ed25519.PrivateKey{}
err := privateKey.SetDefault()
signature := privateKey.Sign("message")

Package ed25519 provides Ed25519 digital signature cryptography.

This package implements Ed25519 public-key signature system based on the elliptic curve Ed25519. It provides key generation, signing, and verification operations with simplified interfaces for key pair management.

Features

  • Ed25519 key pair generation
  • Digital signature creation and verification
  • PEM/PKCS8/PKIX format support
  • SSH public key format conversion
  • Type-safe key management

Basic Example

publicKey := &ed25519.PublicKey{}
publicKey.SetPemPKIX(pemString)
valid := publicKey.Verify("message", signature)

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type KeyPair

type KeyPair struct {
	// contains filtered or unexported fields
}

KeyPair is struct that provides key pair related methods.

func (*KeyPair) Generate

func (kp *KeyPair) Generate() error

Generate creates a new Ed25519 key pair.

This method generates a random Ed25519 private key and derives the corresponding public key using the system's cryptographic random generator.

Returns

  • error: Error if key generation fails, nil on success

Behavior

The generated key pair:

  • Private key: 64 bytes (32-byte seed + 32-byte public key)
  • Public key: 32 bytes
  • Uses crypto/rand for secure randomness
  • Automatically derives public key from private key

Examples

Basic usage:

keyPair := &ed25519.KeyPair{}
err := keyPair.Generate()
if err != nil {
    log.Fatal(err)
}

func (*KeyPair) GetKeyPair

func (kp *KeyPair) GetKeyPair() (privateKey PrivateKey, publicKey PublicKey)

GetKeyPair retrieves the private and public keys.

This method returns both keys from the key pair for separate operations or storage.

Returns

  • privateKey: PrivateKey for signing operations
  • publicKey: PublicKey for verification operations

Examples

Extract keys:

privateKey, publicKey := keyPair.GetKeyPair()
pemPrivate, _ := privateKey.GetPemPKCS8()
pemPublic, _ := publicKey.GetPemPKIX()

func (*KeyPair) SetKeyPair

func (kp *KeyPair) SetKeyPair(privateKey PrivateKey, publicKey PublicKey)

SetKeyPair sets the private and public keys.

This method initializes the key pair with existing keys, useful for loading keys from storage or external sources.

Parameters

  • privateKey: PrivateKey to set
  • publicKey: PublicKey to set (must correspond to private key)

Examples

Load existing keys:

privateKey := ed25519.PrivateKey{}
privateKey.SetPemPKCS8(pemString)
publicKey := privateKey.GetPublicKey()
keyPair.SetKeyPair(privateKey, publicKey)

func (*KeyPair) Sign

func (kp *KeyPair) Sign(message string) []byte

Sign creates a digital signature for the message.

This method signs the message using the private key, producing a 64-byte signature that can be verified with the corresponding public key.

Parameters

  • message: Text message to sign

Returns

  • []byte: 64-byte Ed25519 signature

Behavior

The signature:

  • Always 64 bytes regardless of message length
  • Deterministic for same message and key
  • Cryptographically secure (128-bit security level)
  • Cannot be forged without the private key

Examples

Sign a message:

signature := keyPair.Sign("Hello, World!")
fmt.Printf("Signature: %x\n", signature)

func (*KeyPair) Verify

func (kp *KeyPair) Verify(message string, signature []byte) bool

Verify verifies a digital signature.

This method verifies that the signature was created by the private key corresponding to this key pair's public key.

Parameters

  • message: Original text message
  • signature: 64-byte signature to verify

Returns

  • bool: true if signature is valid, false otherwise

Behavior

Verification checks:

  • Signature matches message and public key
  • Signature has not been tampered with
  • Returns false for invalid signatures (no panic)

Examples

Verify a signature:

signature := keyPair.Sign("message")
valid := keyPair.Verify("message", signature)
if valid {
    fmt.Println("Signature is valid")
}

type PrivateKey

type PrivateKey struct {
	// contains filtered or unexported fields
}

PrivateKey is struct that provides private key related methods.

func (*PrivateKey) Get

func (pk *PrivateKey) Get() ed25519.PrivateKey

Get retrieves the underlying ed25519.PrivateKey.

Returns

  • ed25519.PrivateKey: Raw private key (64 bytes)

Examples

key := privateKey.Get()

func (*PrivateKey) GetPemPKCS8

func (pk *PrivateKey) GetPemPKCS8() (string, error)

GetPemPKCS8 returns the private key in PEM-encoded PKCS#8 format.

Returns

  • string: PEM-encoded private key
  • error: Error if encoding fails, nil on success

Examples

pemString, err := privateKey.GetPemPKCS8()

func (*PrivateKey) GetPublicKey

func (pk *PrivateKey) GetPublicKey() PublicKey

GetPublicKey derives the public key from the private key.

Returns

  • PublicKey: Corresponding public key

Examples

publicKey := privateKey.GetPublicKey()

func (*PrivateKey) Set

func (pk *PrivateKey) Set(privateKey ed25519.PrivateKey)

Set sets the private key from an ed25519.PrivateKey.

Parameters

  • privateKey: Ed25519 private key to set

Examples

privateKey.Set(key)

func (*PrivateKey) SetDefault

func (pk *PrivateKey) SetDefault() error

SetDefault generates a new random private key.

Returns

  • error: Error if key generation fails, nil on success

Examples

err := privateKey.SetDefault()

func (*PrivateKey) SetPemPKCS8

func (pk *PrivateKey) SetPemPKCS8(pemPKCS8 string) error

SetPemPKCS8 sets the private key from a PEM-encoded PKCS#8 string.

Parameters

  • pemPKCS8: PEM-encoded private key string

Returns

  • error: Error if decoding or parsing fails, nil on success

Examples

err := privateKey.SetPemPKCS8(pemString)

func (*PrivateKey) Sign

func (pk *PrivateKey) Sign(message string) []byte

Sign creates a digital signature for the message.

Parameters

  • message: Text message to sign

Returns

  • []byte: 64-byte Ed25519 signature

Examples

signature := privateKey.Sign("Hello, World!")

func (*PrivateKey) Verify

func (pk *PrivateKey) Verify(message string, signature []byte) bool

Verify verifies a digital signature using the public key.

Parameters

  • message: Original text message
  • signature: 64-byte signature to verify

Returns

  • bool: true if signature is valid, false otherwise

Examples

valid := privateKey.Verify("message", signature)

type PublicKey

type PublicKey struct {
	// contains filtered or unexported fields
}

PublicKey is struct that provides public key related methods.

func (*PublicKey) Get

func (pk *PublicKey) Get() ed25519.PublicKey

Get retrieves the underlying ed25519.PublicKey.

Returns

  • ed25519.PublicKey: Raw public key (32 bytes)

Examples

key := publicKey.Get()

func (*PublicKey) GetPemPKIX

func (pk *PublicKey) GetPemPKIX() (string, error)

GetPemPKIX returns the public key in PEM-encoded PKIX format.

Returns

  • string: PEM-encoded public key
  • error: Error if encoding fails, nil on success

Examples

pemString, err := publicKey.GetPemPKIX()

func (*PublicKey) GetSsh

func (pk *PublicKey) GetSsh() (string, error)

GetSsh returns the public key in SSH authorized_keys format.

Returns

  • string: SSH public key string
  • error: Error if encoding fails, nil on success

Examples

sshKey, err := publicKey.GetSsh()

func (*PublicKey) GetSshPublicKey

func (pk *PublicKey) GetSshPublicKey() (ssh.PublicKey, error)

GetSshPublicKey returns the key as an ssh.PublicKey.

Returns

  • ssh.PublicKey: SSH public key interface
  • error: Error if conversion fails, nil on success

Examples

sshKey, err := publicKey.GetSshPublicKey()

func (*PublicKey) Set

func (pk *PublicKey) Set(publicKey ed25519.PublicKey)

Set sets the public key from an ed25519.PublicKey.

Parameters

  • publicKey: Ed25519 public key to set

Examples

publicKey.Set(key)

func (*PublicKey) SetPemPKIX

func (pk *PublicKey) SetPemPKIX(pemPKIX string) error

SetPemPKIX sets the public key from a PEM-encoded PKIX string.

Parameters

  • pemPKIX: PEM-encoded public key string

Returns

  • error: Error if decoding or parsing fails, nil on success

Examples

err := publicKey.SetPemPKIX(pemString)

func (*PublicKey) SetSsh

func (pk *PublicKey) SetSsh(sshKey string) error

SetSsh sets the public key from an SSH authorized_keys format string.

Parameters

  • sshKey: SSH public key string

Returns

  • error: Error if parsing fails, nil on success

Examples

err := publicKey.SetSsh(sshKey)

func (*PublicKey) SetSshPublicKey

func (pk *PublicKey) SetSshPublicKey(publicKey ssh.PublicKey) error

SetSshPublicKey sets the public key from an ssh.PublicKey.

Parameters

  • publicKey: SSH public key to set

Returns

  • error: Error if conversion fails, nil on success

Examples

err := publicKey.SetSshPublicKey(sshKey)

func (*PublicKey) Verify

func (pk *PublicKey) Verify(message string, signature []byte) bool

Verify verifies a digital signature.

Parameters

  • message: Original text message
  • signature: 64-byte signature to verify

Returns

  • bool: true if signature is valid, false otherwise

Examples

valid := publicKey.Verify("message", signature)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL