package hpke
import "github.com/cloudflare/circl/hpke"
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).
Code:play
Output: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))
}
true
Index ¶
- Variables
- type AEAD
- func (a AEAD) CipherLen(mLen uint) uint
- func (a AEAD) IsValid() bool
- func (a AEAD) KeySize() uint
- func (a AEAD) New(key []byte) (cipher.AEAD, error)
- func (a AEAD) NonceSize() uint
- type Context
- type KDF
- func (k KDF) Expand(pseudorandomKey, info []byte, outputLen uint) []byte
- func (k KDF) Extract(secret, salt []byte) (pseudorandomKey []byte)
- func (k KDF) ExtractSize() int
- func (k KDF) IsValid() bool
- type KEM
- type Opener
- type Receiver
- func (r *Receiver) Setup(enc []byte) (Opener, error)
- func (r *Receiver) SetupAuth(enc []byte, pkS kem.PublicKey) (Opener, error)
- func (r *Receiver) SetupAuthPSK( enc, psk, pskID []byte, pkS kem.PublicKey, ) (Opener, error)
- func (r *Receiver) SetupPSK(enc, psk, pskID []byte) (Opener, error)
- type Sealer
- type Sender
- func (s *Sender) Setup(rnd io.Reader) (enc []byte, seal Sealer, err error)
- func (s *Sender) SetupAuth(rnd io.Reader, skS kem.PrivateKey) ( enc []byte, seal Sealer, err error, )
- func (s *Sender) SetupAuthPSK(rnd io.Reader, skS kem.PrivateKey, psk, pskID []byte) ( enc []byte, seal Sealer, err error, )
- func (s *Sender) SetupPSK(rnd io.Reader, psk, pskID []byte) ( enc []byte, seal Sealer, err error, )
- type Suite
- func NewSuite(kemID KEM, kdfID KDF, aeadID AEAD) Suite
- func (suite Suite) NewReceiver(skR kem.PrivateKey, info []byte) ( *Receiver, error, )
- func (suite Suite) NewSender(pkR kem.PublicKey, info []byte) (*Sender, error)
- func (suite Suite) Params() (KEM, KDF, AEAD)
- func (suite Suite) String() string
- Bugs
Examples ¶
Variables ¶
var ( ErrInvalidHPKESuite = errors.New("hpke: invalid HPKE suite") ErrInvalidKDF = errors.New("hpke: invalid KDF identifier") ErrInvalidKEM = errors.New("hpke: invalid KEM identifier") ErrInvalidAuthKEM = errors.New("hpke: KEM does not support Auth mode") ErrInvalidAEAD = errors.New("hpke: invalid AEAD identifier") ErrInvalidKEMPublicKey = errors.New("hpke: invalid KEM public key") ErrInvalidKEMPrivateKey = errors.New("hpke: invalid KEM private key") = errors.New("hpke: invalid KEM shared secret") ErrInvalidKEMDeriveKey = errors.New("hpke: too many tries to derive KEM key") ErrAEADSeqOverflows = errors.New("hpke: AEAD sequence number overflows") )
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 ¶
CipherLen returns the length of a ciphertext corresponding to a message of length mLen.
func (AEAD) IsValid ¶
func (AEAD) KeySize ¶
KeySize returns the size in bytes of the keys used by the AEAD cipher.
func (AEAD) New ¶
New instantiates an AEAD cipher from the identifier, returns an error if the identifier is not known.
func (AEAD) NonceSize ¶
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 ¶
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 ¶
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 ¶
ExtractSize returns the size (in bytes) of the pseudorandom key produced by KDF.Extract.
func (KDF) IsValid ¶
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 // KEM_XWING is a hybrid KEM using X25519 and ML-KEM-768. KEM_XWING KEM = 0x647a )
func (KEM) IsValid ¶
IsValid returns true if the KEM identifier is supported by the HPKE package.
func (KEM) Scheme ¶
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 ¶
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 ¶
Setup generates a new HPKE context used for Base Mode encryption. Setup takes an encapsulated key and returns an Opener.
func (*Receiver) SetupAuth ¶
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 ¶
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 ¶
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 ¶
UnmarshalSealer parses an HPKE sealer.
type Sender ¶
type Sender struct {
// contains filtered or unexported fields
}
Sender performs hybrid public-key encryption.
func (*Sender) Setup ¶
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 ¶
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 ¶
NewSuite builds a Suite from a specified set of algorithms. Panics if an algorithm identifier is not valid.
func (Suite) NewReceiver ¶
NewReceiver creates a Receiver with knowledge of a private key.
func (Suite) NewSender ¶
NewSender creates a Sender with knowledge of the receiver's public-key.
func (Suite) Params ¶
Params returns the codepoints for the algorithms comprising the suite.
func (Suite) String ¶
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).
Source Files ¶
aead.go algs.go genericnoauthkem.go hpke.go hybridkem.go kembase.go marshal.go shortkem.go util.go xkem.go
- Version
- v1.6.1 (latest)
- Published
- Apr 9, 2025
- Platform
- linux/amd64
- Imports
- 24 packages
- Last checked
- 2 days ago –
Tools for package owners.