hpke

package
v1.5.0 Latest Latest
Warning

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

Go to latest
Published: Oct 10, 2024 License: BSD-3-Clause Imports: 24 Imported by: 56

Documentation

Overview

Package hpke implements the Hybrid Public Key Encryption (HPKE) standard specified by draft-irtf-cfrg-hpke-07.

HPKE works for any combination of a public-key encapsulation mechanism (KEM), a key derivation function (KDF), and an authenticated encryption scheme with additional data (AEAD).

Specification in https://datatracker.ietf.org/doc/draft-irtf-cfrg-hpke

BUG(cjpatton): This package does not implement the "Export-Only" mode of the HPKE context. In particular, it does not recognize the AEAD codepoint reserved for this purpose (0xFFFF).

Example
package main

import (
	"bytes"
	"crypto/rand"
	"fmt"

	"github.com/cloudflare/circl/hpke"
)

func main() {
	// import "github.com/cloudflare/circl/hpke"
	// import "crypto/rand"

	// HPKE suite is a domain parameter.
	kemID := hpke.KEM_P384_HKDF_SHA384
	kdfID := hpke.KDF_HKDF_SHA384
	aeadID := hpke.AEAD_AES256GCM
	suite := hpke.NewSuite(kemID, kdfID, aeadID)
	info := []byte("public info string, known to both Alice and Bob")

	// Bob prepares to receive messages and announces his public key.
	publicBob, privateBob, err := kemID.Scheme().GenerateKeyPair()
	if err != nil {
		panic(err)
	}
	Bob, err := suite.NewReceiver(privateBob, info)
	if err != nil {
		panic(err)
	}

	// Alice gets Bob's public key.
	Alice, err := suite.NewSender(publicBob, info)
	if err != nil {
		panic(err)
	}
	enc, sealer, err := Alice.Setup(rand.Reader)
	if err != nil {
		panic(err)
	}

	// Alice encrypts some plaintext and sends the ciphertext to Bob.
	ptAlice := []byte("text encrypted to Bob's public key")
	aad := []byte("additional public data")
	ct, err := sealer.Seal(ptAlice, aad)
	if err != nil {
		panic(err)
	}

	// Bob decrypts the ciphertext.
	opener, err := Bob.Setup(enc)
	if err != nil {
		panic(err)
	}
	ptBob, err := opener.Open(ct, aad)
	if err != nil {
		panic(err)
	}

	// Plaintext was sent successfully.
	fmt.Println(bytes.Equal(ptAlice, ptBob))
}
Output:

true

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	ErrInvalidHPKESuite       = errors.New("hpke: invalid HPKE suite")
	ErrInvalidKDF             = errors.New("hpke: invalid KDF identifier")
	ErrInvalidKEM             = errors.New("hpke: invalid KEM identifier")
	ErrInvalidAEAD            = errors.New("hpke: invalid AEAD identifier")
	ErrInvalidKEMPublicKey    = errors.New("hpke: invalid KEM public key")
	ErrInvalidKEMPrivateKey   = errors.New("hpke: invalid KEM private key")
	ErrInvalidKEMSharedSecret = errors.New("hpke: invalid KEM shared secret")
	ErrAEADSeqOverflows       = errors.New("hpke: AEAD sequence number overflows")
)

Functions

This section is empty.

Types

type AEAD

type AEAD uint16
const (
	// AEAD_AES128GCM is AES-128 block cipher in Galois Counter Mode (GCM).
	AEAD_AES128GCM AEAD = 0x01
	// AEAD_AES256GCM is AES-256 block cipher in Galois Counter Mode (GCM).
	AEAD_AES256GCM AEAD = 0x02
	// AEAD_ChaCha20Poly1305 is ChaCha20 stream cipher and Poly1305 MAC.
	AEAD_ChaCha20Poly1305 AEAD = 0x03
)

func (AEAD) CipherLen

func (a AEAD) CipherLen(mLen uint) uint

CipherLen returns the length of a ciphertext corresponding to a message of length mLen.

func (AEAD) IsValid

func (a AEAD) IsValid() bool

func (AEAD) KeySize

func (a AEAD) KeySize() uint

KeySize returns the size in bytes of the keys used by the AEAD cipher.

func (AEAD) New

func (a AEAD) New(key []byte) (cipher.AEAD, error)

New instantiates an AEAD cipher from the identifier, returns an error if the identifier is not known.

func (AEAD) NonceSize added in v1.3.3

func (a AEAD) NonceSize() uint

NonceSize returns the size in bytes of the nonce used by the AEAD cipher.

type Context

type Context interface {
	encoding.BinaryMarshaler
	// Export takes a context string exporterContext and a desired length (in
	// bytes), and produces a secret derived from the internal exporter secret
	// using the corresponding KDF Expand function. It panics if length is
	// greater than 255*N bytes, where N is the size (in bytes) of the KDF's
	// output.
	Export(exporterContext []byte, length uint) []byte
	// Suite returns the cipher suite corresponding to this context.
	Suite() Suite
}

Context defines the capabilities of an HPKE context.

type KDF

type KDF uint16
const (
	// KDF_HKDF_SHA256 is a KDF using HKDF with SHA-256.
	KDF_HKDF_SHA256 KDF = 0x01
	// KDF_HKDF_SHA384 is a KDF using HKDF with SHA-384.
	KDF_HKDF_SHA384 KDF = 0x02
	// KDF_HKDF_SHA512 is a KDF using HKDF with SHA-512.
	KDF_HKDF_SHA512 KDF = 0x03
)

func (KDF) Expand

func (k KDF) Expand(pseudorandomKey, info []byte, outputLen uint) []byte

Expand derives a variable length pseudorandom string from a pseudorandom key and an information string. Panics if the pseudorandom key is less than N bytes, or if the output length is greater than 255*N bytes, where N is the size returned by KDF.Extract function.

func (KDF) Extract

func (k KDF) Extract(secret, salt []byte) (pseudorandomKey []byte)

Extract derives a pseudorandom key from a high-entropy, secret input and a salt. The size of the output is determined by KDF.ExtractSize.

func (KDF) ExtractSize

func (k KDF) ExtractSize() int

ExtractSize returns the size (in bytes) of the pseudorandom key produced by KDF.Extract.

func (KDF) IsValid

func (k KDF) IsValid() bool

type KEM

type KEM uint16
const (
	// KEM_P256_HKDF_SHA256 is a KEM using P256 curve and HKDF with SHA-256.
	KEM_P256_HKDF_SHA256 KEM = 0x10
	// KEM_P384_HKDF_SHA384 is a KEM using P384 curve and HKDF with SHA-384.
	KEM_P384_HKDF_SHA384 KEM = 0x11
	// KEM_P521_HKDF_SHA512 is a KEM using P521 curve and HKDF with SHA-512.
	KEM_P521_HKDF_SHA512 KEM = 0x12
	// KEM_X25519_HKDF_SHA256 is a KEM using X25519 Diffie-Hellman function
	// and HKDF with SHA-256.
	KEM_X25519_HKDF_SHA256 KEM = 0x20
	// KEM_X448_HKDF_SHA512 is a KEM using X448 Diffie-Hellman function and
	// HKDF with SHA-512.
	KEM_X448_HKDF_SHA512 KEM = 0x21
	// KEM_X25519_KYBER768_DRAFT00 is a hybrid KEM built on DHKEM(X25519, HKDF-SHA256)
	// and Kyber768Draft00
	KEM_X25519_KYBER768_DRAFT00 KEM = 0x30
)

func (KEM) IsValid

func (k KEM) IsValid() bool

IsValid returns true if the KEM identifier is supported by the HPKE package.

func (KEM) Scheme

func (k KEM) Scheme() kem.AuthScheme

Scheme returns an instance of a KEM that supports authentication. Panics if the KEM identifier is invalid.

type Opener

type Opener interface {
	Context
	// Open takes a ciphertext and associated data to recover, if successful,
	// the plaintext. The nonce is handled by the Opener and incremented after
	// each call.
	Open(ct, aad []byte) (pt []byte, err error)
}

Opener decrypts a ciphertext using an AEAD encryption.

func UnmarshalOpener

func UnmarshalOpener(raw []byte) (Opener, error)

UnmarshalOpener parses a serialized HPKE opener and returns the corresponding Opener.

type Receiver

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

Receiver performs hybrid public-key decryption.

func (*Receiver) Setup

func (r *Receiver) Setup(enc []byte) (Opener, error)

Setup generates a new HPKE context used for Base Mode encryption. Setup takes an encapsulated key and returns an Opener.

func (*Receiver) SetupAuth

func (r *Receiver) SetupAuth(enc []byte, pkS kem.PublicKey) (Opener, error)

SetupAuth generates a new HPKE context used for Auth Mode encryption. SetupAuth takes an encapsulated key and a public key, and returns an Opener.

func (*Receiver) SetupAuthPSK

func (r *Receiver) SetupAuthPSK(
	enc, psk, pskID []byte, pkS kem.PublicKey,
) (Opener, error)

SetupAuthPSK generates a new HPKE context used for Auth-PSK Mode encryption. SetupAuthPSK takes an encapsulated key, a public key, and a pre-shared key; and returns an Opener.

func (*Receiver) SetupPSK

func (r *Receiver) SetupPSK(enc, psk, pskID []byte) (Opener, error)

SetupPSK generates a new HPKE context used for PSK Mode encryption. SetupPSK takes an encapsulated key, and a pre-shared key; and returns an Opener.

type Sealer

type Sealer interface {
	Context
	// Seal takes a plaintext and associated data to produce a ciphertext.
	// The nonce is handled by the Sealer and incremented after each call.
	Seal(pt, aad []byte) (ct []byte, err error)
}

Sealer encrypts a plaintext using an AEAD encryption.

func UnmarshalSealer

func UnmarshalSealer(raw []byte) (Sealer, error)

UnmarshalSealer parses an HPKE sealer.

type Sender

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

Sender performs hybrid public-key encryption.

func (*Sender) Setup

func (s *Sender) Setup(rnd io.Reader) (enc []byte, seal Sealer, err error)

Setup generates a new HPKE context used for Base Mode encryption. Returns the Sealer and corresponding encapsulated key.

func (*Sender) SetupAuth

func (s *Sender) SetupAuth(rnd io.Reader, skS kem.PrivateKey) (
	enc []byte, seal Sealer, err error,
)

SetupAuth generates a new HPKE context used for Auth Mode encryption. Returns the Sealer and corresponding encapsulated key.

func (*Sender) SetupAuthPSK

func (s *Sender) SetupAuthPSK(rnd io.Reader, skS kem.PrivateKey, psk, pskID []byte) (
	enc []byte, seal Sealer, err error,
)

SetupAuthPSK generates a new HPKE context used for Auth-PSK Mode encryption. Returns the Sealer and corresponding encapsulated key.

func (*Sender) SetupPSK

func (s *Sender) SetupPSK(rnd io.Reader, psk, pskID []byte) (
	enc []byte, seal Sealer, err error,
)

SetupPSK generates a new HPKE context used for PSK Mode encryption. Returns the Sealer and corresponding encapsulated key.

type Suite

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

Suite is an HPKE cipher suite consisting of a KEM, KDF, and AEAD algorithm.

func NewSuite

func NewSuite(kemID KEM, kdfID KDF, aeadID AEAD) Suite

NewSuite builds a Suite from a specified set of algorithms. Panics if an algorithm identifier is not valid.

func (Suite) NewReceiver

func (suite Suite) NewReceiver(skR kem.PrivateKey, info []byte) (
	*Receiver, error,
)

NewReceiver creates a Receiver with knowledge of a private key.

func (Suite) NewSender

func (suite Suite) NewSender(pkR kem.PublicKey, info []byte) (*Sender, error)

NewSender creates a Sender with knowledge of the receiver's public-key.

func (Suite) Params

func (suite Suite) Params() (KEM, KDF, AEAD)

Params returns the codepoints for the algorithms comprising the suite.

func (Suite) String

func (suite Suite) String() string

Notes

Bugs

  • This package does not implement the "Export-Only" mode of the HPKE context. In particular, it does not recognize the AEAD codepoint reserved for this purpose (0xFFFF).

Jump to

Keyboard shortcuts

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