rome

package module
v1.0.1 Latest Latest
Warning

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

Go to latest
Published: Nov 2, 2022 License: GPL-3.0 Imports: 21 Imported by: 2

README

Rome

Go Reference Go Report Card GitHub Workflow Status

The Elliptic and Edward Curve cryptography library built for multi-curve use. Unified crypto interface for ECDSA, EdDSA, ECIES and ECDH. A high level library which gives you the control: specify curve, KDFs or hash functions, ciphers etc.

Go Version: >= 18.0

Test Coverage: 80.0%

Implemented Curves & Features

Curve Type Sign Verify Encrypt DH
Nist P-521 Elliptic Curve
Nist P-384 Elliptic Curve
Nist P-256 Elliptic Curve
Nist P-224 Elliptic Curve
Brainpool P160r1 Elliptic Curve
Brainpool P160t1 Elliptic Curve
Brainpool P192r1 Elliptic Curve
Brainpool P192t1 Elliptic Curve
Brainpool P224r1 Elliptic Curve
Brainpool P224t1 Elliptic Curve
Brainpool P256r1 Elliptic Curve
Brainpool P256t1 Elliptic Curve
Brainpool P320r1 Elliptic Curve
Brainpool P320t1 Elliptic Curve
Brainpool P384r1 Elliptic Curve
Brainpool P384t1 Elliptic Curve
Brainpool P512r1 Elliptic Curve
Brainpool P512t1 Elliptic Curve
Ed25519 Edwards Curve n/a n/a
Ed448 Edwards Curve n/a n/a
x25519/Curve25519 Elliptic Curve
x448 Goldilocks Elliptic Curve

Features

  • Generate key
  • Export (Public, Private) PEM and ASN.1 DER bytes
  • Import (Public, Private) PEM and ASN.1 DER bytes
  • Sign (ASN.1 format)
  • Verify
  • Elliptic Curve Diffie Hellman (ECDH)
  • Encrypt (ECIES: AES_GCM 128 & 256 bit)
  • Decrypt
  • Retrieve Points

Ciphers

Cipher Authenticated
AES_GCM
ChaCha20
ChaCha20_SHA256
ChaCha20_SHA512
ChaCha20_Poly1305
Salsa20

Curves

  • nist P-521
  • nist P-384
  • nist P-256
  • nist P-224
  • Ed25519
  • Ed448
  • Brainpool P160t1
  • Brainpool P192r1
  • Brainpool P192t1
  • Brainpool P224r1
  • Brainpool P224t1
  • Brainpool P256r1
  • Brainpool P256t1
  • Brainpool P320r1
  • Brainpool P320t1
  • Brainpool P384r1
  • Brainpool P384t1
  • Brainpool P512r1
  • Brainpool P512t1

Todo

  • Maybe RSA (support not just ECC)
  • secp256k1
  • saltpack
  • Encrypt private key option
  • Convert keys to SSH keys

Encrypt (ECIES)

Rome supports ECIES for elliptic curves allowing you to encrypt to a public key. Encryption can be customised with cipher options: AES_256_GCM (more coming soon) and customise KDFs used for shared secret generation (ECDH). Supporting the hash.Hash interface you can use your favourite algorithm. It's even possible to use Argon2 as a KDF.

Encrypt example with AES_256_GCM_SHA256:

package main

import (
	"crypto/sha256"
	"fmt"
	"os"

	"github.com/go-compile/rome"
	"github.com/go-compile/rome/p256"
)

func main() {
	// Generate a nist P256 Elliptic Curve
	k, err := p256.Generate()
	if err != nil {
		panic(err)
	}

	pub := k.Public()

	msg := []byte("Secret message.")

	// encrypt message using AES256_GCM with SHA256 and a 98bit nonce
	ciphertext, err := pub.Encrypt(msg, rome.CipherAES_GCM, sha256.New())
	if err != nil {
		panic(err)
	}

    fmt.Printf("%X\n", ciphertext)
}

Install

go get -u github.com/go-compile/rome

Examples

Full code examples can be found ./examples/

package main

import (
	"fmt"

	"github.com/go-compile/rome"
	"github.com/go-compile/rome/p256"
)

func main() {
	// Generate a nist P256 Elliptic Curve
	k, err := p256.Generate()
	if err != nil {
		panic(err)
	}

	printKey("P256", k)
}

func printKey(name string, k rome.PrivateKey) {
	// Format private key using PEM and ASN.1 DER bytes
	private, err := k.Private()
	if err != nil {
		panic(err)
	}

	public, err := k.Public().Key()
	if err != nil {
		panic(err)
	}

	fmt.Printf("%s:\n Private:\n%s\n Public:\n%s\n",
		name, string(private), string(public))
}

Output:

P256:
Private:
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIATPRwGmsr81mgiH1Tf+yntyUcj0m9Ta3UsaWrgPjZtKoAoGCCqGSM49
AwEHoUQDQgAENjGsmnjl4dXbRur5AfzlDxq6Bp0BQafwM7DJdhSv1yUNRF3+oDsw
mZ9MD9z6VjjBh8REN6e0SDIM/IJCZL84DA==
-----END EC PRIVATE KEY-----

Public:
-----BEGIN EC PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAENjGsmnjl4dXbRur5AfzlDxq6Bp0B
QafwM7DJdhSv1yUNRF3+oDswmZ9MD9z6VjjBh8REN6e0SDIM/IJCZL84DA==
-----END EC PUBLIC KEY-----

Documentation

Index

Constants

View Source
const (
	// CipherAES_GCM is a AHEAD cipher and is recommended for most use cases
	CipherAES_GCM = iota
	// CipherChacha20 is a UNAUTHENTICATED cipher and is only provided with the expectation
	// you will handle the data integrity by using a MAC. Or instead please use one of the
	// provided authenticated ChaCha ciphers below.
	CipherChacha20
	// CipherChacha20_SHA256 is a authenticated Encrypt-then-MAC (EtM) cipher using ChaCha20
	// the MAC is a SHA256 hmac with the secret being the encryption key
	CipherChacha20_SHA256
	// CipherChacha20_SHA512 is a authenticated Encrypt-then-MAC (EtM) cipher using ChaCha20
	// the MAC is a SHA512 hmac with the secret being the encryption key
	CipherChacha20_SHA512
	// CipherChaCha20Poly1305 is a authenticated cipher which takes a 256bit key
	CipherChaCha20Poly1305
	// CipherSalsa20 is a UNAUTHENTICATED cipher and is only provided with the expectation
	// you will handle the data integrity by using a MAC. Or instead please use one of the
	// provided authenticated ChaCha ciphers below.
	CipherSalsa20
)

Variables

View Source
var (
	// ErrUnknownCipher is returned if the cipher provided is unsupported
	ErrUnknownCipher = errors.New("unknown cipher suite")
	// ErrCipherTxtSmall is returned if the data is so small it must be invalid
	ErrCipherTxtSmall = errors.New("cipher text is too small")
	// ErrAuthFail is returned when the ciphertext mac fails
	ErrAuthFail = errors.New("message authentication failed")
	// ErrKeySize is returned if the key is not supported in the encryption algorithm
	ErrKeySize = errors.New("key size not supported")
)
View Source
var (
	// ErrWrongKey is returned if the key is the wrong type
	ErrWrongKey = errors.New("wrong key type or curve")
	// ErrInvalidPem is returned when invalid PEM data is attempted to be decoded
	ErrInvalidPem = errors.New("invalid PEM data failed to parse")
	// ErrDerivePub is returned if there is a error in extracting the pub key from private D
	ErrDerivePub = errors.New("could not derive public key")
)

Functions

func Pad

func Pad(x []byte, size int) []byte

Pad will add padding to the left

Types

type Cipher

type Cipher uint8

Cipher specifies what cipher to use in encryption

type ECKey

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

ECKey is a Elliptic Curve

func NewECCurve

func NewECCurve(priv *ecdsa.PrivateKey) *ECKey

NewECCurve takes a ECDSA key and converts it to a Rome private key

func ParseECPrivate

func ParseECPrivate(private []byte) (*ECKey, error)

ParseECPrivate will read a PEM ASN.1 DER encoded key

func ParseECPrivateASN1

func ParseECPrivateASN1(private []byte) (*ECKey, error)

ParseECPrivateASN1 will read a ASN.1 DER encoded key

func (*ECKey) Decrypt

func (k *ECKey) Decrypt(ciphertext []byte, c Cipher, hash hash.Hash, options ...Option) ([]byte, error)

Decrypt uses ECIES hybrid encryption. Cipher is used to specify the encryption algorithm and hash is used to derive the key via the ECDH

func (*ECKey) ECPublic

func (k *ECKey) ECPublic() *ECPublicKey

ECPublic returns the ECPublic interface instead of the unified rome interface. It is not recommended this function is used.

func (*ECKey) Private

func (k *ECKey) Private() ([]byte, error)

Private will return the private key as PEM ASN.1 DER bytes

func (*ECKey) PrivateASN1

func (k *ECKey) PrivateASN1() ([]byte, error)

PrivateASN1 will return the private key as ASN.1 DER bytes

func (*ECKey) PrivateRaw

func (k *ECKey) PrivateRaw() []byte

PrivateRaw returns the private key (D)

func (*ECKey) Public

func (k *ECKey) Public() PublicKey

Public returns the public key interface

func (*ECKey) Sign

func (k *ECKey) Sign(digest []byte) ([]byte, error)

Sign will take a digest and use the private key to sign it

type ECPublicKey

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

ECPublicKey holds the X and Y parameters for the key

func ParseECPublic

func ParseECPublic(public []byte) (*ECPublicKey, error)

ParseECPublic will read elliptic curve public key from PEM ASN.1 DER format

func ParseECPublicASN1

func ParseECPublicASN1(der []byte) (*ECPublicKey, error)

ParseECPublicASN1 will read a elliptic curve public key from ASN.1 DER format

func (*ECPublicKey) DH

func (k *ECPublicKey) DH(hash hash.Hash, g PrivateKey, options ...Option) ([]byte, error)

DH calculates a ECDH using your specified hash function for key generation

func (*ECPublicKey) Encrypt

func (k *ECPublicKey) Encrypt(m []byte, c Cipher, hash hash.Hash, options ...Option) ([]byte, error)

Encrypt uses ECIES hybrid encryption. Cipher is used to specify the encryption algorithm and hash is used to derive the key via the ECDH

func (*ECPublicKey) Fingerprint

func (k *ECPublicKey) Fingerprint(h hash.Hash) []byte

Fingerprint returns the hashed ASN.1 digest representing this public key. This function will panic if it fails to encode the public key.

func (*ECPublicKey) Key

func (k *ECPublicKey) Key() ([]byte, error)

Key returns the public key in PEM ASN.1 DER format

func (*ECPublicKey) KeyASN1

func (k *ECPublicKey) KeyASN1() ([]byte, error)

KeyASN1 returns the public key formatted in ASN.1

func (*ECPublicKey) Name

func (k *ECPublicKey) Name() string

Name returns the name of the curve

func (*ECPublicKey) Points

func (k *ECPublicKey) Points() (x *big.Int, y *big.Int)

Points returns the Elliptic Curve coordinates

func (*ECPublicKey) Size

func (k *ECPublicKey) Size() int

Size returns the key size in bytes

func (*ECPublicKey) Verify

func (k *ECPublicKey) Verify(digest []byte, signature []byte) (bool, error)

Verify will take a ASN.1 signature and return true if it's valid

type Option

type Option any

Option allows you to specify exactly what you want a function to use. Functions only use the options relevant to them.

type OptionHKDF

type OptionHKDF struct {
	KeySize int
	Salt    []byte
	Hash    func() hash.Hash
}

OptionHKDF is used in a DH and will overwrite the shared secret options

func NewHKDF

func NewHKDF(h func() hash.Hash, keysize int, salt []byte) OptionHKDF

NewHKDF allows you to use HKDF in your ECDH. Salt can be nil and keysize usually should be 32 (256bit)

type PrivateKey

type PrivateKey interface {
	// Sign returns a ASN.1 formatted signature
	Sign(digest []byte) ([]byte, error)
	// Public returns the public key interface
	Public() PublicKey

	// Private returns the private key as PEM ANS.1 DER bytes
	//
	// Example Output:
	//
	// 	-----BEGIN EC PUBLIC KEY-----
	// MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQAcnk2OsBaHEE1LW40x5ZyRubtyYN0
	// P0lfNYr/J621MzgmHFWUhPXiGiNi5OLsoWkXAWBqoM5JHPI4GJXzrjBjh2gAgve4
	// miuuyibmAF+KgXN8t24pm/Wo2owBTXjTPn2R4kPf8lvkeom3/uM8OQUxx3sn4Gld
	// wnDkkVtMdB42du+DMQw=
	//
	// -----END EC PUBLIC KEY-----
	Private() ([]byte, error)
	// Private returns the private key as ANS.1 DER bytes
	PrivateASN1() ([]byte, error)

	// PrivateRaw if a elliptic or edwards curve the returned bytes will
	// be the value D
	PrivateRaw() []byte

	// Decrypt will take a ECIES encrypted ciphertext and decrypt it using the
	// private key
	Decrypt(ciphertext []byte, cipher Cipher, hash hash.Hash, option ...Option) ([]byte, error)
}

PrivateKey holds the D point for the curve and the public key.

type PublicKey

type PublicKey interface {
	// Name returns the curve name
	Name() string
	// Size returns the key size in bytes
	Size() int
	// Verify will take a ASN.1 signature and return true if it's valid
	Verify(digest []byte, signature []byte) (bool, error)
	// Points returns the Elliptic/Edward Curve coordinates
	Points() (x *big.Int, y *big.Int)
	// Key returns the public key in PEM ASN.1 DER format
	Key() ([]byte, error)
	// KeyASN1 returns the public key formatted in ASN.1
	KeyASN1() ([]byte, error)
	// DH takes a hasher and the ephemeral private key
	DH(h hash.Hash, g PrivateKey, options ...Option) ([]byte, error)
	// Encrypt will uses ECIES to encrypt your message to the public key
	Encrypt(msg []byte, cipher Cipher, hash hash.Hash, options ...Option) ([]byte, error)

	// Fingerprint returns the hashed ASN.1 digest representing this
	// public key. This function will panic if it fails to encode the
	// public key.
	Fingerprint(hash.Hash) []byte
}

PublicKey is a Elliptic/Edward curve public key

Directories

Path Synopsis
Package argon2 provides argon2id hash function which satisfies the hash.Hash interface
Package argon2 provides argon2id hash function which satisfies the hash.Hash interface
Package brainpool provides generator functions for Brainpool Elliptic Curves
Package brainpool provides generator functions for Brainpool Elliptic Curves
bcurves
Package brainpool provides the elliptic curves specified in rfc 5639
Package brainpool provides the elliptic curves specified in rfc 5639
Package derbytes is a slimmed down fork of crypto/x509 modified to support additional elliptic and edward curves.
Package derbytes is a slimmed down fork of crypto/x509 modified to support additional elliptic and edward curves.
Package ed25519 provides a interface to use the Ed25519 Edwards Curve
Package ed25519 provides a interface to use the Ed25519 Edwards Curve
Package ed448 provides a generator function for the Ed448 Edwards Curve
Package ed448 provides a generator function for the Ed448 Edwards Curve
examples
Package parse provides a unified parser for both Elliptic and Edwards Curves.
Package parse provides a unified parser for both Elliptic and Edwards Curves.

Jump to

Keyboard shortcuts

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