hpkecompact

package module
v0.0.0-...-4ee502b Latest Latest
Warning

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

Go to latest
Published: Aug 11, 2023 License: ISC Imports: 10 Imported by: 6

README

CI status Go Reference

HPKE-Compact

A compact HPKE implemention for Go

hpkecompact is a small implementation of the Hybrid Public Key Encryption (HPKE) draft.

It fits in a single file and only uses the Go standard library and x/crypto.

Suites are currently limited to X25519-HKDF-SHA256 / HKDF-SHA-256 / {AES-{128,256}-GCM, CHACHA20-POLY1305}; these are very likely to be the most commonly deployed ones for a forseable future.

Usage

Suite instantiation
suite, err := NewSuite(KemX25519HkdfSha256, KdfHkdfSha256, AeadAes128Gcm)
Key pair creation
serverKp, err := ctx.GenerateKeyPair()
Client: creation and encapsulation of the shared secret

A client initiates a connexion by sending an encrypted secret; a server accepts an encrypted secret from a client, and decrypts it, so that both parties can eventually agree on a shared secret.

clientCtx, encryptedSharedSecret, err :=
    suite.NewClientContext(serverKp.PublicKey, []byte("application name"), nil)
  • encryptedSharedSecret needs to be sent to the server.
  • clientCtx can be used to encrypt/decrypt messages exchanged with the server.
  • The last parameter is an optional pre-shared key (Psk type).

To improve misuse resistance, this implementation uses distinct types for the client and the server context: ClientContext for the client, and ServerContext for the server.

Server: decapsulation of the shared secret
serverCtx, err := suite.NewServerContext(encryptedSharedSecret,
    serverKp, []byte("application name"), nil)
  • serverCtx can be used to encrypt/decrypt messages exchanged with the client
  • The last parameter is an optional pre-shared key (Psk type).
Encryption of a message from the client to the server

A message can be encrypted by the client for the server:

ciphertext, err := clientCtx.EncryptToServer([]byte("message"), nil)

Nonces are automatically incremented, so it is safe to call this function multiple times within the same context.

Second parameter is optional associated data.

Decryption of a ciphertext received by the server

The server can decrypt a ciphertext sent by the client:

decrypted, err := serverCtx.DecryptFromClient(ciphertext, nil)

Second parameter is optional associated data.

Encryption of a message from the server to the client

A message can also be encrypted by the server for the client:

ciphertext, err := serverCtx.EncryptToClient([]byte("response"), nil)

Nonces are automatically incremented, so it is safe to call this function multiple times within the same context.

Second parameter is optional associated data.

Decryption of a ciphertext received by the client

The client can decrypt a ciphertext sent by the server:

decrypted, err := clientCtx.DecryptFromServer(ciphertext, nil)

Second parameter is optional associated data.

Authenticated modes

Authenticated modes, with or without a PSK are supported.

Just replace NewClientContext() with NewAuthenticatedClientContext() and NewServerContext() with NewAuthenticatedServerContext() for authentication.

clientKp, err := suite.GenerateKeyPair()
serverKp, err := suite.GenerateKeyPair()

clientCtx, encryptedSharedSecret, err := suite.NewAuthenticatedClientContext(
    clientKp, serverKp.PublicKey, []byte("app"), psk)

serverCtx, err := suite.NewAuthenticatedServerContext(
    clientKp.PublicKey, encryptedSharedSecret, serverKp, []byte("app"), psk)
Exporter secret

The exporter secret can be obtained with the ExportedSecret() function available both in the ServerContext and ClientContext structures:

exporter := serverCtx.ExporterSecret()
Key derivation
secret1, err := clientCtx.Export("description 1")
secret2, err := serverCtx.Export("description 2");
Access the raw cipher interface
cipher, err := suite.NewRawCipher(key)

That's it!

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AeadID

type AeadID uint16

AeadID - AEAD ID

const (
	// AeadAes128Gcm - AES128-GCM
	AeadAes128Gcm AeadID = 0x0001
	// AeadAes256Gcm - AES256-GCM
	AeadAes256Gcm AeadID = 0x0002
	// AeadChaCha20Poly1305 - ChaCha20-Poly1305
	AeadChaCha20Poly1305 AeadID = 0x0003
	// AeadExportOnly - Don't use the HPKE encryption API
	AeadExportOnly AeadID = 0xffff
)

type ClientContext

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

ClientContext - A client encryption context

func (*ClientContext) DecryptFromServer

func (context *ClientContext) DecryptFromServer(ciphertext []byte, ad []byte) ([]byte, error)

DecryptFromServer - Verify and decrypt a ciphertext received from the server, with optional associated data

func (*ClientContext) EncryptToServer

func (context *ClientContext) EncryptToServer(message []byte, ad []byte) ([]byte, error)

EncryptToServer - Encrypt and authenticate a message for the server, with optional associated data

func (*ClientContext) Export

func (context *ClientContext) Export(exporterContext []byte, length uint16) ([]byte, error)

Export - Derive an arbitrary-long secret

func (*ClientContext) ExporterSecret

func (context *ClientContext) ExporterSecret() []byte

ExporterSecret - Return the exporter secret

type KdfID

type KdfID uint16

KdfID - KDF ID

const (
	// KdfHkdfSha256 - HKDF-SHA256
	KdfHkdfSha256 KdfID = 0x0001
)

type KemID

type KemID uint16

KemID - KEM ID

const (
	// KemX25519HkdfSha256 - X25519 with HKDF-SHA256
	KemX25519HkdfSha256 KemID = 0x0020
)

type KeyPair

type KeyPair struct {
	// PublicKey - Public key
	PublicKey []byte
	// SecretKey - Secret key
	SecretKey []byte
}

KeyPair - A key pair (packed as a byte string)

type Mode

type Mode byte

Mode - Mode

const (
	// ModeBase - Base mode
	ModeBase Mode = 0x00
	// ModePsk - PSK mode
	ModePsk Mode = 0x01
	// ModeAuth - Auth mode
	ModeAuth Mode = 0x02
	// ModeAuthPsk - PSK Auth mode
	ModeAuthPsk Mode = 0x03
)

type Psk

type Psk struct {
	Key []byte
	ID  []byte
}

Psk - Pre-shared key and key ID

type ServerContext

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

ServerContext - A server encryption context

func (*ServerContext) DecryptFromClient

func (context *ServerContext) DecryptFromClient(ciphertext []byte, ad []byte) ([]byte, error)

DecryptFromClient - Verify and decrypt a ciphertext received from the client, with optional associated data

func (*ServerContext) EncryptToClient

func (context *ServerContext) EncryptToClient(message []byte, ad []byte) ([]byte, error)

EncryptToClient - Encrypt and authenticate a message for the client, with optional associated data

func (*ServerContext) Export

func (context *ServerContext) Export(exporterContext []byte, length uint16) ([]byte, error)

Export - Derive an arbitrary-long secret

func (*ServerContext) ExporterSecret

func (context *ServerContext) ExporterSecret() []byte

ExporterSecret - Return the exporter secret

type Suite

type Suite struct {
	SuiteIDContext [10]byte
	SuiteIDKEM     [5]byte
	Hash           func() hash.Hash
	PrkBytes       uint16
	KeyBytes       uint16
	NonceBytes     uint16
	KemHashBytes   uint16
	AeadID         AeadID
}

Suite - HPKE suite

func NewSuite

func NewSuite(kemID KemID, kdfID KdfID, aeadID AeadID) (*Suite, error)

NewSuite - Create a new suite from its components

func (*Suite) DeterministicKeyPair

func (suite *Suite) DeterministicKeyPair(seed []byte) (KeyPair, error)

DeterministicKeyPair - Derive a deterministic key pair from a seed

func (*Suite) Expand

func (suite *Suite) Expand(prk []byte, info []byte, length uint16) ([]byte, error)

Expand - KDF-Expand

func (*Suite) Extract

func (suite *Suite) Extract(secret []byte, salt []byte) []byte

Extract - KDF-Extract

func (*Suite) GenerateKeyPair

func (suite *Suite) GenerateKeyPair() (KeyPair, error)

GenerateKeyPair - Generate a random key pair

func (*Suite) NewAuthenticatedClientContext

func (suite *Suite) NewAuthenticatedClientContext(clientKp KeyPair, serverPk []byte, info []byte, psk *Psk) (ClientContext, []byte, error)

NewAuthenticatedClientContext - Create a new context for a client (aka "sender"), with authentication

func (*Suite) NewAuthenticatedClientDeterministicContext

func (suite *Suite) NewAuthenticatedClientDeterministicContext(clientKp KeyPair, serverPk []byte, info []byte, psk *Psk, seed []byte) (ClientContext, []byte, error)

NewAuthenticatedClientDeterministicContext - Create a new deterministic context for a client, with authentication - Should only be used for testing purposes

func (*Suite) NewAuthenticatedServerContext

func (suite *Suite) NewAuthenticatedServerContext(clientPk []byte, enc []byte, serverKp KeyPair, info []byte, psk *Psk) (ServerContext, error)

NewAuthenticatedServerContext - Create a new context for a server (aka "recipient"), with authentication

func (*Suite) NewClientContext

func (suite *Suite) NewClientContext(serverPk []byte, info []byte, psk *Psk) (ClientContext, []byte, error)

NewClientContext - Create a new context for a client (aka "sender")

func (*Suite) NewClientDeterministicContext

func (suite *Suite) NewClientDeterministicContext(serverPk []byte, info []byte, psk *Psk, seed []byte) (ClientContext, []byte, error)

NewClientDeterministicContext - Create a new deterministic context for a client - Should only be used for testing purposes

func (*Suite) NewRawCipher

func (suite *Suite) NewRawCipher(key []byte) (cipher.AEAD, error)

NewRawCipher - Access the raw cipher interface

func (*Suite) NewServerContext

func (suite *Suite) NewServerContext(enc []byte, serverKp KeyPair, info []byte, psk *Psk) (ServerContext, error)

NewServerContext - Create a new context for a server (aka "recipient")

Jump to

Keyboard shortcuts

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