delphi

package module
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Jun 20, 2025 License: MIT Imports: 21 Imported by: 7

README

Go Delphi

Delphi is a package that provides secure, efficient cryptographic operations with a few nice features:

  • perfect forward secrecy is provided using X25519 key exchange and ephemeral keys
  • all keys are the same length (public, private, encryption, decryption) (32 bytes)
  • ed25519 for signatures and verification
  • a nice sensible API

Getting Started

$ go get github.com/sean9999/go-delphi@latest
import (
	"crypto/rand"
	"testing"

	"github.com/sean9999/go-delphi"
	"github.com/stretchr/testify/assert"
)

func TestExample(t *testing.T) {

	//	some plain text
	sentence := []byte("hello world")

	//	create two principals
	alice := delphi.NewPrincipal(rand.Reader)
	bob := delphi.NewPrincipal(rand.Reader)

	//	create a message for bob, from alice
	msg := delphi.NewMessage(rand.Reader, sentence)
	msg.Sender = alice.PublicKey()
	msg.Recipient = bob.PublicKey()

	//	add some metadata (this becomes AAD)
	msg.Headers.Set("foo", []byte("bar"))
	msg.Headers.Set("bing", []byte("bat"))

	//	encrypt message
	err := msg.Encrypt(rand.Reader, alice, nil)
	assert.NoError(t, err)

	//	decrpyt message
	err = bob.Decrypt(msg, nil)
	assert.NoError(t, err)

	//	is decrypted text same as plain text?
	assert.Equal(t, sentence, msg.PlainText)

	//	has the metadata survived?
	foo, ok := msg.Headers.Get("foo")
	assert.True(t, ok)
	assert.Equal(t, []byte("bar"), foo)

}

Documentation

Overview

Example
//	some plain text
sentence := []byte("hello world")

//	create two principals
alice := delphi.NewPrincipal(rand.Reader)
bob := delphi.NewPrincipal(rand.Reader)

//	create a message for bob, from alice
msg := delphi.ComposeMessage(rand.Reader, delphi.PlainMessage, sentence)
msg.SenderKey = alice.PublicKey()

//	add some metadata (this becomes AAD)
msg.Headers["foo"] = "bar"
msg.Headers["bing"] = "bat"

//	encrypt message
err := msg.Encrypt(rand.Reader, alice, bob.PublicKey(), nil)
fmt.Println("should be nil", err)

//	decrpyt message
err = bob.Decrypt(msg, nil)
fmt.Println("should be nil", err)

//	is decrypted text same as plain text?
diff := slices.Compare(sentence, msg.PlainText)
fmt.Println("should be 0", diff)

//	has the metadata survived?
foo, ok := msg.Headers["foo"]

fmt.Println("should be true", ok)
fmt.Println(foo)
Output:

should be nil <nil>
should be nil <nil>
should be 0 0
should be true true
bar

Index

Examples

Constants

View Source
const GLOBAL_SALT = "oracle/v1"
View Source
const Keyspace = "delphi"

the prefix for header keys

View Source
const SubKeySize = 32
View Source
const Version = "v1"

Variables

View Source
var ErrBadKey = errors.New("bad key")
View Source
var ErrDecryptionFailed = errors.New("decryption failed")
View Source
var ErrDelphi = errors.New("delphi")
View Source
var ErrEncryptionFailed = errors.New("encryption failed")
View Source
var ErrInvalidMsg = pear.Defer("invalid message")
View Source
var ErrNoEphemeralKey = errors.New("no ephemeral key")
View Source
var ErrNoMsg = pear.Defer("no message")
View Source
var ErrNoNonce = pear.Defer("zero value nonce")
View Source
var ErrNoSender = pear.Defer("no sender")
View Source
var ErrNoSign = pear.Defer("could not sign message")
View Source
var ErrNoValid = pear.Defer("no valid signature")
View Source
var ErrNotImplemented = errors.New("not implemented")
View Source
var UniversalNonce []byte = make([]byte, chacha20poly1305.NonceSize)

Functions

func NewSubKey added in v0.0.4

func NewSubKey(randy io.Reader) subKey

Types

type Certifier

type Certifier interface {
	crypto.PrivateKey
	crypto.Signer
	Verifier
}

a Certifier can produce and verify signatures

type Cipherer

type Cipherer interface {
	crypto.PrivateKey
	Encrypter
	Decrypter
}

a Cipherer can encrypt and decrypt a Message

type CryptOpts

type CryptOpts struct {
	Nonce []byte
	AAD   []byte
}

type Decrypter added in v0.0.4

type Decrypter interface {
	Decrypt(*Message, crypto.DecrypterOpts) error
}

type Encrypter

type Encrypter interface {
	Encrypt(io.Reader, *Message, Key, EncrypterOpts) error
}

type EncrypterOpts added in v0.0.4

type EncrypterOpts = any

type KV added in v0.1.1

type KV map[string]string

a KV is a simple map with some super powers useful to us

func (KV) Get added in v0.3.0

func (kv KV) Get(keyspace string, key string) string

func (KV) LexicalOrder added in v0.2.0

func (kv KV) LexicalOrder() iter.Seq2[string, string]

LexicolOrder ranges through a KV in lexical order

func (KV) MarshalBinary added in v0.2.0

func (kv KV) MarshalBinary() ([]byte, error)

func (KV) Set added in v0.3.0

func (kv KV) Set(keyspace string, key string, val string)

func (*KV) UnmarshalBinary added in v0.2.0

func (kv *KV) UnmarshalBinary(b []byte) error

type Key added in v0.0.5

type Key [2]subKey

a Key is two (specifically one encryption and one signing) keys

func KeyFromBytes added in v0.0.3

func KeyFromBytes(b []byte) Key

func KeyFromHex added in v0.0.5

func KeyFromHex(str string) Key

func NewKey added in v0.0.4

func NewKey(randy io.Reader) Key

func (Key) Bytes added in v0.0.5

func (k Key) Bytes() []byte

func (Key) Encryption added in v0.0.5

func (k Key) Encryption() subKey

func (Key) Equal added in v0.0.5

func (k Key) Equal(j Key) bool

func (Key) From added in v0.0.5

func (k Key) From(b []byte) Key

func (Key) IsZero added in v0.0.5

func (k Key) IsZero() bool

a Key is zero if all it's subKeys are zero

func (Key) MarshalBinary added in v0.3.16

func (k Key) MarshalBinary() ([]byte, error)

func (Key) MarshalJSON added in v0.3.16

func (k Key) MarshalJSON() ([]byte, error)

func (Key) MarshalText added in v0.1.1

func (k Key) MarshalText() ([]byte, error)

func (Key) Signing added in v0.0.5

func (k Key) Signing() subKey

func (Key) ToHex added in v0.1.1

func (k Key) ToHex() string

func (Key) ToInt64 added in v0.1.1

func (k Key) ToInt64() int64

func (*Key) UnmarshalBinary added in v0.3.16

func (k *Key) UnmarshalBinary(b []byte) error

func (*Key) UnmarshalJSON added in v0.2.0

func (k *Key) UnmarshalJSON(b []byte) error

type KeyPair added in v0.0.5

type KeyPair [2]Key

a KeyPair is two [Key]s. One public, one private

func NewKeyPair added in v0.0.4

func NewKeyPair(randy io.Reader) KeyPair

NewKeyPair generates valid ed25519 and X25519 keys

func (KeyPair) Bytes added in v0.0.5

func (k KeyPair) Bytes() []byte

func (KeyPair) IsZero added in v0.0.5

func (kp KeyPair) IsZero() bool

a KeyPair is zero if all it's keys are zero

type Message

type Message struct {
	Subject      Subject `msgpack:"subj" json:"subj"`
	RecipientKey Key     `msgpack:"to" json:"to"`
	SenderKey    Key     `msgpack:"from" json:"from"`
	Headers      KV      `msgpack:"hdrs" json:"hdrs"` // additional authenticated data (AAD)
	Eph          []byte  `msgpack:"eph" json:"eph"`
	Nonce        Nonce   `msgpack:"nonce" json:"nonce"`
	CipherText   []byte  `msgpack:"ciph" json:"ciph"`
	PlainText    []byte  `msgpack:"plain" json:"plain"`
	Sig          []byte  `msgpack:"sig" json:"sig"`
	// contains filtered or unexported fields
}

a Message is a message that represents either plain text or cipher text, encapsulating all data and metadata necessary to perform cryptographic operations.

func ComposeMessage added in v0.3.16

func ComposeMessage(randy io.Reader, subj Subject, plainTxt []byte) *Message

ComposeMessage creates a new Message. If you pass in a source of randomness, it will have a Nonce.

func NewMessage

func NewMessage() *Message

func (*Message) Digest added in v0.0.3

func (msg *Message) Digest() ([]byte, error)

Digest returns a hash of the Message fields which should be hashed.

func (*Message) Encrypt

func (msg *Message) Encrypt(randy io.Reader, encrypter Encrypter, recipient Peer, opts EncrypterOpts) error

Encrypt encrypts a message to a Peer

func (*Message) Encrypted added in v0.0.4

func (msg *Message) Encrypted() bool

func (*Message) Ephemeral added in v0.0.4

func (msg *Message) Ephemeral() crypto.PublicKey

Ephemeral() returns the ephemeral key (X25519)

func (*Message) FromPEM added in v0.1.1

func (msg *Message) FromPEM(p pem.Block) error

func (*Message) Plain added in v0.0.4

func (msg *Message) Plain() bool

func (*Message) Read added in v0.1.1

func (msg *Message) Read(b []byte) (int, error)

func (*Message) RecipientEncryption added in v0.1.1

func (msg *Message) RecipientEncryption() crypto.PublicKey

RecipientEncryption() returns the recipient as a public encryption key (ECDH)

func (*Message) Sender added in v0.0.5

func (msg *Message) Sender() crypto.PublicKey

Sender() returns the sender as a public encryption key (ECDH)

func (*Message) Sign added in v0.0.3

func (msg *Message) Sign(randy io.Reader, signer crypto.Signer) error

Sign signs a Message

func (*Message) Signatory added in v0.0.4

func (msg *Message) Signatory() crypto.PublicKey

Signatory() returns the public signing key of the sender (X25519)

func (*Message) String added in v0.1.1

func (msg *Message) String() string

func (*Message) ToPEM added in v0.1.1

func (msg *Message) ToPEM() pem.Block

func (*Message) Valid added in v0.0.4

func (msg *Message) Valid() bool

func (*Message) Verify added in v0.1.1

func (msg *Message) Verify() bool

Verify verifies the signature on a Message

func (*Message) Write added in v0.2.0

func (msg *Message) Write(b []byte) (int, error)

type Nonce added in v0.0.3

type Nonce [NonceSize]byte

A Nonce is a random value with a reasonably high chance of being globally unqiue.

func NewNonce added in v0.0.4

func NewNonce(randy io.Reader) Nonce

func NonceFromBytes added in v0.3.0

func NonceFromBytes(b []byte) Nonce

func (Nonce) Bytes added in v0.0.4

func (nonce Nonce) Bytes() []byte

func (Nonce) IsZero added in v0.0.3

func (nonce Nonce) IsZero() bool

type Peer added in v0.3.0

type Peer = Key

A Peer is the public portion of a Principal, which is a public-private key pair.

func NewPeer added in v0.3.16

func NewPeer() Peer

func (Peer) MarshalPEM added in v0.3.16

func (p Peer) MarshalPEM() (pem.Block, error)

func (Peer) Nickname added in v0.3.0

func (p Peer) Nickname() string

A Nickname is a very memorable string for humans only. It has weak uniqueness that is good enough for some uses.

type Principal

type Principal = KeyPair

A Principal contains cryptographic key material and can sign, verify, encrypt, and decrypt [Message]s.

func NewPrincipal

func NewPrincipal(randy io.Reader) Principal

NewPrincipal creates a new Principal

func (Principal) Assert added in v0.3.0

func (p Principal) Assert(randy io.Reader) (*Message, error)

Assert creates a signed assertion

func (Principal) ComposeMessage added in v0.3.0

func (p Principal) ComposeMessage(randy io.Reader, body []byte) *Message

func (Principal) Decrypt added in v0.0.5

func (p Principal) Decrypt(msg *Message, _ crypto.DecrypterOpts) error

Decrypt decrypts a Message

func (Principal) Encrypt added in v0.0.5

func (p Principal) Encrypt(randy io.Reader, msg *Message, recipient Key, _ any) error

Encrypt encrypts a Message

func (Principal) Equal added in v0.0.5

func (p Principal) Equal(p2 crypto.PublicKey) bool

func (Principal) From added in v0.0.5

func (Principal) From(b []byte) (Principal, error)

From re-hydrates a Principal from a byte slice

func (Principal) MarshalBinary added in v0.0.5

func (p Principal) MarshalBinary() ([]byte, error)

func (Principal) MarshalPEM added in v0.3.2

func (p Principal) MarshalPEM() (pem.Block, error)

func (Principal) Nickname added in v0.3.0

func (p Principal) Nickname() string

A Nickname is a very memorable string for humans only. It has weak uniqueness that is good enough for some uses.

func (Principal) PrivateKey added in v0.0.5

func (p Principal) PrivateKey() Key

func (Principal) Public added in v0.0.5

func (p Principal) Public() crypto.PublicKey

func (Principal) PublicKey added in v0.0.5

func (p Principal) PublicKey() Key

func (Principal) Sign added in v0.0.5

func (p Principal) Sign(_ io.Reader, digest []byte, _ crypto.SignerOpts) ([]byte, error)

Sign signs a digest

func (*Principal) UnmarshalBinary added in v0.0.5

func (p *Principal) UnmarshalBinary(b []byte) error

func (*Principal) UnmarshalPEM added in v0.3.0

func (p *Principal) UnmarshalPEM(b pem.Block) error

func (Principal) Verify added in v0.0.5

func (p Principal) Verify(delphiPubKey crypto.PublicKey, digest []byte, sig []byte) bool

Verify verifies a signature

type Subject added in v0.3.0

type Subject string
const (
	PlainMessage     Subject = "DELPHI PLAIN MESSAGE"
	EncryptedMessage Subject = "DELPHI ENCRYPTED MESSAGE"
	Assertion        Subject = "DELPHI ASSERTION"
	Pubkey           Subject = "DELPHI PUBLIC KEY"
	Privkey          Subject = "DELPHI PRIVATE KEY"
)

func (Subject) Equals added in v0.3.16

func (subj Subject) Equals(str string) bool

func (Subject) String added in v0.3.16

func (subj Subject) String() string

type Verifier

type Verifier interface {
	Verify(pub crypto.PublicKey, digest []byte, sig []byte) bool
}

a Verifier can verify that a signature is valid

Directories

Path Synopsis
cmd
delphi
this does cool stuff
this does cool stuff

Jump to

Keyboard shortcuts

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