Skip to content

krabt/ecies

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ECIES - Elliptic Curve Integrated Encryption Scheme

A Go implementation of ECIES (Elliptic Curve Integrated Encryption Scheme) using modern cryptographic primitives for secure data encryption and key management.

Features

  • X25519 Key Exchange: Uses X25519 for ECDH key agreement (32-byte keys)
  • ChaCha20-Poly1305: AEAD encryption with 12-byte nonce and 16-byte authentication tag
  • Ed25519 Support: Generate and manage Ed25519 keys for digital signatures
  • Standard PEM Format:
    • Private keys saved in PKCS#8 format
    • Public keys saved in X.509 SubjectPublicKeyInfo format
    • Cross-language compatible formats (RFC 7468)
  • Secure Key Storage: Private key files created with restrictive 0600 permissions
  • Comprehensive Error Handling: Descriptive error types for all operations

Installation

go get github.com/krabt/ecies

Quick Start

Generate Encryption Keys

package main

import (
	"fmt"
	"github.com/krabt/ecies"
)

func main() {
	// Generate X25519 key pair for encryption
	priv, pub, err := ecies.GenerateX25519Key()
	if err != nil {
		panic(err)
	}
	
	// Save to PEM files
	if err := ecies.SavePrivateKeyToPEM("private.pem", priv); err != nil {
		panic(err)
	}
	if err := ecies.SavePublicKeyToPEM("public.pem", pub); err != nil {
		panic(err)
	}
	
	fmt.Println("Keys generated and saved!")
}

Encrypt and Decrypt

package main

import (
	"fmt"
	"github.com/krabt/ecies"
)

func main() {
	// Generate or load keys
	priv, pub, _ := ecies.GenerateX25519Key()
	
	// Encrypt a message
	plaintext := []byte("Hello, ECIES!")
	ciphertext, err := ecies.Encrypt(pub, plaintext)
	if err != nil {
		panic(err)
	}
	
	// Decrypt the message
	decrypted, err := ecies.Decrypt(priv, ciphertext)
	if err != nil {
		panic(err)
	}
	
	fmt.Printf("Original: %s\n", string(plaintext))
	fmt.Printf("Decrypted: %s\n", string(decrypted))
}

Generate Signature Keys

package main

import (
	"github.com/krabt/ecies"
)

func main() {
	// Generate Ed25519 key pair for signatures
	priv, pub, err := ecies.GenerateEd25519Key()
	if err != nil {
		panic(err)
	}
	
	// Save to PEM files
	ecies.SavePrivateKeyToPEM("sign_private.pem", priv)
	ecies.SavePublicKeyToPEM("sign_public.pem", pub)
}

Load Keys from PEM Files

package main

import (
	"crypto/ecdh"
	"github.com/krabt/ecies"
)

func main() {
	// Load private key
	privRaw, err := ecies.LoadPrivateKeyFromPEM("private.pem")
	if err != nil {
		panic(err)
	}
	priv := privRaw.(*ecdh.PrivateKey)
	
	// Load public key
	pubRaw, err := ecies.LoadPublicKeyFromPEM("public.pem")
	if err != nil {
		panic(err)
	}
	pub := pubRaw.(*ecdh.PublicKey)
}

API Reference

Key Generation

  • GenerateX25519Key() (*ecdh.PrivateKey, *ecdh.PublicKey, error) - Generate X25519 key pair
  • GenerateEd25519Key() (ed25519.PrivateKey, ed25519.PublicKey, error) - Generate Ed25519 key pair

Key Management

  • SavePrivateKeyToPEM(filename string, anyPriv any) error - Save private key (PKCS#8)
  • SavePublicKeyToPEM(filename string, anyPub any) error - Save public key (X.509)
  • LoadPrivateKeyFromPEM(filename string) (any, error) - Load private key from PEM
  • LoadPublicKeyFromPEM(filename string) (any, error) - Load public key from PEM

Encryption & Decryption

  • Encrypt(pub *ecdh.PublicKey, plaintext []byte) ([]byte, error) - Encrypt data
  • Decrypt(priv *ecdh.PrivateKey, ciphertext []byte) ([]byte, error) - Decrypt data

Cryptographic Details

Encryption Scheme

  1. Ephemeral Key Generation: Generate a random ephemeral X25519 key pair
  2. Shared Secret: Compute ECDH shared secret between ephemeral private key and recipient's public key
  3. Key Derivation: Use the shared secret as nonce input for ChaCha20-Poly1305
  4. Encryption: Encrypt plaintext using ChaCha20-Poly1305
  5. Output Format: [ephemeral_public_key (32 bytes)][nonce (12 bytes)][ciphertext + tag]

Constants

  • X25519 Public Key Size: 32 bytes
  • ChaCha20 Nonce Size: 12 bytes
  • Poly1305 Tag Size: 16 bytes
  • Header Size: 44 bytes (32 + 12)

Error Types

  • ErrPacketTooShort - Ciphertext packet is too short
  • ErrInvalidPubKey - Invalid ephemeral public key
  • ErrDecryptionFailed - Decryption failed (data may be tampered or wrong key)
  • ErrInvalidPEM - Invalid PEM block or block type mismatch

Security Considerations

  • Key Storage: Private keys are saved with 0600 permissions (owner read/write only)
  • Nonce: Each encryption operation uses a unique nonce derived from the ephemeral key
  • Authentication: ChaCha20-Poly1305 provides both confidentiality and authenticity
  • Constants: PEM block types follow RFC 7468 standards

Testing

Run the test suite:

go test -v

The tests cover:

  • Full ECIES encryption/decryption flow
  • Key generation and persistence
  • PEM file I/O operations
  • Cross-version key compatibility

Dependencies

  • golang.org/x/crypto - For cryptographic primitives
  • Standard Go crypto library - For ECDH, Ed25519, and x509/PEM support

License

This project is licensed under the MIT License - see the LICENSE file for details.

References

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages