Documentation
¶
Overview ¶
Package hpke implements Hybrid Public Key Encryption as specified in RFC 9180. HPKE provides public-key encryption of arbitrary-sized plaintexts with optional sender authentication.
See README.md for details.
Index ¶
- Constants
- Variables
- func DecryptingWithApplicationInfo[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], ...](info []byte) encryption.DecrypterOption[*Decrypter[P, B, S], Message, Ciphertext]
- func DecryptingWithAuthPSK[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], ...](pk *PublicKey[P, B, S], pskID []byte, psk *encryption.SymmetricKey) encryption.DecrypterOption[*Decrypter[P, B, S], Message, Ciphertext]
- func DecryptingWithAuthentication[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], ...](pk *PublicKey[P, B, S]) encryption.DecrypterOption[*Decrypter[P, B, S], Message, Ciphertext]
- func DecryptingWithCapsule[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], ...](capsule *Capsule[P, B, S]) encryption.DecrypterOption[*Decrypter[P, B, S], Message, Ciphertext]
- func DecryptingWithPreSharedKey[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], ...](pskID []byte, psk *encryption.SymmetricKey) encryption.DecrypterOption[*Decrypter[P, B, S], Message, Ciphertext]
- func EncryptingWhileCachingRecentContextualInfo[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], ...]() ...
- func EncryptingWithApplicationInfo[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], ...](info []byte) ...
- func EncryptingWithAuthPSK[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], ...](sk *PrivateKey[S], pskID []byte, psk *encryption.SymmetricKey) ...
- func EncryptingWithAuthentication[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], ...](sk *PrivateKey[S]) ...
- func EncryptingWithPreSharedKey[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], ...](pskID []byte, psk *encryption.SymmetricKey) ...
- func SealPSK[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], ...](ctx *SenderContext[P, B, S], additionalData, plaintext []byte) (ciphertext []byte, err error)
- func WithSenderPrivateKey[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], ...](sk *PrivateKey[S]) encryption.KEMOption[*KEM[P, B, S], *PublicKey[P, B, S], *Capsule[P, B, S]]
- func WithSenderPublicKey[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], ...](pk *PublicKey[P, B, S]) encryption.DEMOption[*DEM[P, B, S], *Capsule[P, B, S]]
- type AEADID
- type Capsule
- type CipherSuite
- type Ciphertext
- type DEM
- type Decrypter
- func (e *Decrypter[P, B, S]) Decrypt(ciphertext Ciphertext) (Message, error)
- func (e *Decrypter[P, B, S]) Export(context []byte, length uint) (*encryption.SymmetricKey, error)
- func (e *Decrypter[P, B, S]) Mode() ModeID
- func (e *Decrypter[P, B, S]) Open(ciphertext Ciphertext, aad []byte) (Message, error)
- type Encrypter
- func (e *Encrypter[P, B, S]) Encrypt(plaintext Message, receiver *PublicKey[P, B, S], prng io.Reader) (Ciphertext, *Capsule[P, B, S], error)
- func (e *Encrypter[P, B, S]) Export(context []byte, length uint) (*encryption.SymmetricKey, error)
- func (e *Encrypter[P, B, S]) Mode() ModeID
- func (e *Encrypter[P, B, S]) Seal(plaintext Message, receiver *PublicKey[P, B, S], aad []byte, prng io.Reader) (Ciphertext, *Capsule[P, B, S], error)
- type KDFID
- type KEM
- type KEMID
- type KeyGenerator
- type KeyGeneratorOption
- type Message
- type ModeID
- type PrivateKey
- type PublicKey
- type ReceiverContext
- func SetupAuthPSKR[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], ...](suite *CipherSuite, receiverPrivatekey *PrivateKey[S], ...) (*ReceiverContext[P, B, S], error)
- func SetupAuthR[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], ...](suite *CipherSuite, receiverPrivatekey *PrivateKey[S], ...) (*ReceiverContext[P, B, S], error)
- func SetupBaseR[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], ...](suite *CipherSuite, receiverPrivatekey *PrivateKey[S], ...) (*ReceiverContext[P, B, S], error)
- func SetupPSKR[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], ...](suite *CipherSuite, receiverPrivatekey *PrivateKey[S], ...) (*ReceiverContext[P, B, S], error)
- type Scheme
- func (s *Scheme[P, B, S]) AEAD(key *encryption.SymmetricKey) (cipher.AEAD, error)
- func (s *Scheme[P, B, S]) CipherSuite() *CipherSuite
- func (s *Scheme[P, B, S]) DEM(receiverPrivateKey *PrivateKey[S], ...) (*DEM[P, B, S], error)
- func (s *Scheme[P, B, S]) Decrypter(receiverPrivateKey *PrivateKey[S], ...) (*Decrypter[P, B, S], error)
- func (s *Scheme[P, B, S]) Encrypter(...) (*Encrypter[P, B, S], error)
- func (s *Scheme[P, B, S]) KEM(...) (*KEM[P, B, S], error)
- func (s *Scheme[P, B, S]) Keygen(opts ...KeyGeneratorOption[P, B, S]) (*KeyGenerator[P, B, S], error)
- func (*Scheme[P, B, S]) Name() encryption.Name
- type SenderContext
- func SetupAuthPSKS[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], ...](suite *CipherSuite, receiverPublicKey *PublicKey[P, B, S], ...) (sender *SenderContext[P, B, S], err error)
- func SetupAuthS[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], ...](suite *CipherSuite, receiverPublicKey *PublicKey[P, B, S], ...) (sender *SenderContext[P, B, S], err error)
- func SetupBaseS[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], ...](suite *CipherSuite, receiverPublicKey *PublicKey[P, B, S], info []byte, ...) (sender *SenderContext[P, B, S], err error)
- func SetupPSKS[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], ...](suite *CipherSuite, receiverPublicKey *PublicKey[P, B, S], ...) (sender *SenderContext[P, B, S], err error)
Constants ¶
const ( // Name is the identifier for the HPKE encryption scheme. Name encryption.Name = "HPKE" // Base mode (mode_base = 0x00) provides encryption without sender authentication. // The recipient cannot verify the sender's identity. Base ModeID = internal.Base // PSk mode (mode_psk = 0x01) authenticates the sender via a pre-shared key. // Both parties must possess the same PSK and PSK ID. The recipient can verify // the sender possessed the PSK, but PSK compromise allows impersonation. PSk ModeID = internal.PSk // Auth mode (mode_auth = 0x02) authenticates the sender via an asymmetric key pair. // The sender's private key is used in the encapsulation, allowing the recipient // to verify the sender's identity using the sender's public key. Auth ModeID = internal.Auth // AuthPSk mode (mode_auth_psk = 0x03) combines PSK and asymmetric authentication. // The sender is authenticated via both mechanisms, providing defence in depth. AuthPSk ModeID = internal.AuthPSk // AEAD_RESERVED (0x0000) is reserved and MUST NOT be used. AEAD_RESERVED AEADID = internal.AEAD_RESERVED // AEAD_AES_128_GCM (0x0001) specifies AES-128-GCM with Nk=16, Nn=12, Nt=16. AEAD_AES_128_GCM AEADID = internal.AEAD_AES_128_GCM // AEAD_AES_256_GCM (0x0002) specifies AES-256-GCM with Nk=32, Nn=12, Nt=16. AEAD_AES_256_GCM AEADID = internal.AEAD_AES_256_GCM // AEAD_CHACHA_20_POLY_1305 (0x0003) specifies ChaCha20Poly1305 with Nk=32, Nn=12, Nt=16. AEAD_CHACHA_20_POLY_1305 AEADID = internal.AEAD_CHACHA_20_POLY_1305 // AEAD_EXPORT_ONLY (0xFFFF) indicates that the AEAD is not used for encryption; // only the Export interface is available. This is useful for key derivation scenarios. AEAD_EXPORT_ONLY AEADID = internal.AEAD_EXPORT_ONLY // KDF_HKDF_RESERVED (0x0000) is reserved and MUST NOT be used. KDF_HKDF_RESERVED KDFID = internal.KDF_HKDF_RESERVED // KDF_HKDF_SHA256 (0x0001) specifies HKDF-SHA256 with Nh=32. KDF_HKDF_SHA256 KDFID = internal.KDF_HKDF_SHA256 // KDF_HKDF_SHA512 (0x0003) specifies HKDF-SHA512 with Nh=64. KDF_HKDF_SHA512 KDFID = internal.KDF_HKDF_SHA512 // DHKEM_RESERVED (0x0000) is reserved and MUST NOT be used. DHKEM_RESERVED KEMID = internal.DHKEM_RESERVED // DHKEM_P256_HKDF_SHA256 (0x0010) specifies DHKEM(P-256, HKDF-SHA256) // with Nsecret=32, Nenc=65, Npk=65, Nsk=32. DHKEM_P256_HKDF_SHA256 KEMID = internal.DHKEM_P256_HKDF_SHA256 // DHKEM_X25519_HKDF_SHA256 (0x0020) specifies DHKEM(X25519, HKDF-SHA256) // with Nsecret=32, Nenc=32, Npk=32, Nsk=32. DHKEM_X25519_HKDF_SHA256 KEMID = internal.DHKEM_X25519_HKDF_SHA256 )
Variables ¶
var ( ErrInvalidArgument = errs.New("invalid argument") ErrInvalidLength = errs.New("invalid length") ErrNotSupported = errs.New("not supported") )
var ( // NewCipherSuite creates a new CipherSuite from the specified KEM, KDF, and AEAD identifiers. // Returns an error if any identifier is reserved (0x0000) or invalid. // // See: https://www.rfc-editor.org/rfc/rfc9180.html#section-5.1 NewCipherSuite = internal.NewCipherSuite )
Functions ¶
func DecryptingWithApplicationInfo ¶
func DecryptingWithApplicationInfo[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], S algebra.PrimeFieldElement[S]](info []byte) encryption.DecrypterOption[*Decrypter[P, B, S], Message, Ciphertext]
DecryptingWithApplicationInfo returns an option that sets the application-specific info parameter. This must match the info used by the sender for successful decryption.
See: https://www.rfc-editor.org/rfc/rfc9180.html#section-5.1
func DecryptingWithAuthPSK ¶
func DecryptingWithAuthPSK[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], S algebra.PrimeFieldElement[S]](pk *PublicKey[P, B, S], pskID []byte, psk *encryption.SymmetricKey) encryption.DecrypterOption[*Decrypter[P, B, S], Message, Ciphertext]
DecryptingWithAuthPSK returns an option that enables AuthPSK mode (mode_auth_psk = 0x03) for decryption. Both the sender's public key and PSK must be provided and match those used by the sender.
See: https://www.rfc-editor.org/rfc/rfc9180.html#section-5.1.4
func DecryptingWithAuthentication ¶
func DecryptingWithAuthentication[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], S algebra.PrimeFieldElement[S]](pk *PublicKey[P, B, S]) encryption.DecrypterOption[*Decrypter[P, B, S], Message, Ciphertext]
DecryptingWithAuthentication returns an option that enables Auth mode (mode_auth = 0x02) for decryption. The sender's public key is used to verify that the sender possessed the corresponding private key during encapsulation.
See: https://www.rfc-editor.org/rfc/rfc9180.html#section-5.1.3
func DecryptingWithCapsule ¶
func DecryptingWithCapsule[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], S algebra.PrimeFieldElement[S]](capsule *Capsule[P, B, S]) encryption.DecrypterOption[*Decrypter[P, B, S], Message, Ciphertext]
DecryptingWithCapsule returns an option that sets the capsule (enc) received from the sender. The capsule is the serialised ephemeral public key used in the key encapsulation mechanism. This option is required for decryption.
See: https://www.rfc-editor.org/rfc/rfc9180.html#section-4.1
func DecryptingWithPreSharedKey ¶
func DecryptingWithPreSharedKey[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], S algebra.PrimeFieldElement[S]](pskID []byte, psk *encryption.SymmetricKey) encryption.DecrypterOption[*Decrypter[P, B, S], Message, Ciphertext]
DecryptingWithPreSharedKey returns an option that enables PSK mode (mode_psk = 0x01) for decryption. The PSK and PSK ID must match those used by the sender.
See: https://www.rfc-editor.org/rfc/rfc9180.html#section-5.1.2
func EncryptingWhileCachingRecentContextualInfo ¶
func EncryptingWhileCachingRecentContextualInfo[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], S algebra.PrimeFieldElement[S]]() encryption.EncrypterOption[*Encrypter[P, B, S], *PublicKey[P, B, S], Message, Ciphertext, *Capsule[P, B, S]]
EncryptingWhileCachingRecentContextualInfo returns an option that enables caching of the sender context after encryption. This allows the Export method to be called to derive additional secrets from the encryption context.
Note: When caching is enabled, the encrypter holds a mutex during Seal operations for thread safety.
func EncryptingWithApplicationInfo ¶
func EncryptingWithApplicationInfo[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], S algebra.PrimeFieldElement[S]](info []byte) encryption.EncrypterOption[*Encrypter[P, B, S], *PublicKey[P, B, S], Message, Ciphertext, *Capsule[P, B, S]]
EncryptingWithApplicationInfo returns an option that sets the application-specific info parameter for the HPKE key schedule. The info parameter is bound to the derived keys and must match between sender and receiver for successful decryption.
Per RFC 9180 Section 5.1, info is application-supplied information that should be independently agreed upon by both parties.
See: https://www.rfc-editor.org/rfc/rfc9180.html#section-5.1
func EncryptingWithAuthPSK ¶
func EncryptingWithAuthPSK[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], S algebra.PrimeFieldElement[S]](sk *PrivateKey[S], pskID []byte, psk *encryption.SymmetricKey) encryption.EncrypterOption[*Encrypter[P, B, S], *PublicKey[P, B, S], Message, Ciphertext, *Capsule[P, B, S]]
EncryptingWithAuthPSK returns an option that enables AuthPSK mode (mode_auth_psk = 0x03). This combines both asymmetric authentication (via the sender's private key) and PSK authentication, providing defence in depth.
See: https://www.rfc-editor.org/rfc/rfc9180.html#section-5.1.4
func EncryptingWithAuthentication ¶
func EncryptingWithAuthentication[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], S algebra.PrimeFieldElement[S]](sk *PrivateKey[S]) encryption.EncrypterOption[*Encrypter[P, B, S], *PublicKey[P, B, S], Message, Ciphertext, *Capsule[P, B, S]]
EncryptingWithAuthentication returns an option that enables Auth mode (mode_auth = 0x02). The sender's private key is used in the encapsulation to authenticate the sender's identity. The recipient can verify the sender possessed the corresponding private key.
See: https://www.rfc-editor.org/rfc/rfc9180.html#section-5.1.3
func EncryptingWithPreSharedKey ¶
func EncryptingWithPreSharedKey[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], S algebra.PrimeFieldElement[S]](pskID []byte, psk *encryption.SymmetricKey) encryption.EncrypterOption[*Encrypter[P, B, S], *PublicKey[P, B, S], Message, Ciphertext, *Capsule[P, B, S]]
EncryptingWithPreSharedKey returns an option that enables PSK mode (mode_psk = 0x01). Both sender and receiver must possess the same pre-shared key (psk) and PSK identifier (pskID). The PSK is incorporated into the key schedule, providing sender authentication.
Per RFC 9180, the psk MUST have at least 32 bytes of entropy, and pskID is a sequence of bytes used to identify the PSK.
See: https://www.rfc-editor.org/rfc/rfc9180.html#section-5.1.2
func SealPSK ¶
func SealPSK[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], S algebra.PrimeFieldElement[S]](ctx *SenderContext[P, B, S], additionalData, plaintext []byte) (ciphertext []byte, err error)
SealPSK encrypts a plaintext using a PSK-mode sender context. This is a convenience wrapper around ctx.Seal for PSK mode.
See: https://www.rfc-editor.org/rfc/rfc9180.html#section-5.2
func WithSenderPrivateKey ¶
func WithSenderPrivateKey[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], S algebra.PrimeFieldElement[S]](sk *PrivateKey[S]) encryption.KEMOption[*KEM[P, B, S], *PublicKey[P, B, S], *Capsule[P, B, S]]
WithSenderPrivateKey returns an option that enables authenticated encapsulation by providing the sender's private key. When set, the KEM uses AuthEncap instead of Encap, allowing the receiver to verify the sender's identity.
See: https://www.rfc-editor.org/rfc/rfc9180.html#section-4.1
func WithSenderPublicKey ¶
func WithSenderPublicKey[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], S algebra.PrimeFieldElement[S]](pk *PublicKey[P, B, S]) encryption.DEMOption[*DEM[P, B, S], *Capsule[P, B, S]]
WithSenderPublicKey returns an option that enables authenticated decapsulation by providing the sender's public key. When set, the DEM uses AuthDecap instead of Decap, verifying that the capsule was created by the sender.
See: https://www.rfc-editor.org/rfc/rfc9180.html#section-4.1
Types ¶
type AEADID ¶
AEADID is a two-byte value identifying the AEAD algorithm, defined in RFC 9180 Table 3. HPKE supports AES-128-GCM, AES-256-GCM, ChaCha20Poly1305, and an export-only mode.
See: https://www.rfc-editor.org/rfc/rfc9180.html#section-7.3
type Capsule ¶
type Capsule[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], S algebra.PrimeFieldElement[S]] = internal.PublicKey[P, B, S]
Capsule is the encapsulated key transmitted from sender to receiver, represented as an ephemeral public key. In DHKEM, the capsule is the serialised ephemeral public key (enc) that allows the receiver to derive the same shared secret.
See: https://www.rfc-editor.org/rfc/rfc9180.html#section-4.1
type CipherSuite ¶
type CipherSuite = internal.CipherSuite
CipherSuite specifies the combination of KEM, KDF, and AEAD algorithms used for HPKE. The suite identifier is computed as concat("HPKE", I2OSP(kem_id, 2), I2OSP(kdf_id, 2), I2OSP(aead_id, 2)).
See: https://www.rfc-editor.org/rfc/rfc9180.html#section-5.1
type Ciphertext ¶
type Ciphertext []byte
Ciphertext is the encrypted message produced by HPKE's AEAD encryption. It contains both the encrypted plaintext and the authentication tag.
type DEM ¶
type DEM[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], S algebra.PrimeFieldElement[S]] struct { // contains filtered or unexported fields }
DEM provides data encapsulation mechanism (decapsulation) operations for HPKE. It uses the receiver's private key to recover the shared secret from a capsule.
The DEM supports both standard and authenticated decapsulation. Authenticated decapsulation verifies that the shared secret was produced using the sender's private key.
See: https://www.rfc-editor.org/rfc/rfc9180.html#section-4
func (*DEM[P, B, S]) Decapsulate ¶
func (d *DEM[P, B, S]) Decapsulate(capsule *Capsule[P, B, S]) (*encryption.SymmetricKey, error)
Decapsulate recovers the shared secret from a capsule using the receiver's private key. Returns a symmetric key derived from the shared secret.
If WithSenderPublicKey was configured, this performs authenticated decapsulation (AuthDecap), otherwise standard decapsulation (Decap).
See: https://www.rfc-editor.org/rfc/rfc9180.html#section-4.1
func (*DEM[P, B, S]) IsAuthenticated ¶
IsAuthenticated returns true if the sender's public key has been configured, indicating that authenticated decapsulation will be used.
type Decrypter ¶
type Decrypter[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], S algebra.PrimeFieldElement[S]] struct { // contains filtered or unexported fields }
Decrypter performs HPKE decryption operations. The receiver context is established during construction based on the receiver's private key and the capsule from the sender.
The decrypter supports all four HPKE modes, determined by which options were provided during construction. The mode must match what the sender used, or decryption will fail.
func (*Decrypter[P, B, S]) Decrypt ¶
Decrypt decrypts a ciphertext encrypted to this receiver's public key. This is equivalent to Open with nil associated data.
func (*Decrypter[P, B, S]) Export ¶
func (e *Decrypter[P, B, S]) Export(context []byte, length uint) (*encryption.SymmetricKey, error)
Export derives a secret from the decryption context using the HPKE secret export mechanism. The exporter_context parameter and length are inputs to the secret derivation.
When called with the same inputs on both sender and receiver, Export produces the same output, enabling key agreement for additional symmetric keys.
See: https://www.rfc-editor.org/rfc/rfc9180.html#section-5.3
func (*Decrypter[P, B, S]) Mode ¶
Mode returns the HPKE mode configured for decryption, determined by which authentication parameters have been set.
func (*Decrypter[P, B, S]) Open ¶
Open decrypts a ciphertext with associated data. The associated data must match exactly what was provided during encryption, or the authentication will fail.
The sequence number is incremented after each successful decryption, so ciphertexts must be opened in the same order they were sealed by the sender.
See: https://www.rfc-editor.org/rfc/rfc9180.html#section-5.2
type Encrypter ¶
type Encrypter[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], S algebra.PrimeFieldElement[S]] struct { // contains filtered or unexported fields }
Encrypter performs HPKE encryption operations. It establishes a sender context for each encryption and seals messages using the AEAD algorithm specified in the cipher suite.
The encrypter supports all four HPKE modes, determined by which options were provided during construction. For each Encrypt/Seal call, a new ephemeral key pair is generated and a fresh sender context is established.
func (*Encrypter[P, B, S]) Encrypt ¶
func (e *Encrypter[P, B, S]) Encrypt(plaintext Message, receiver *PublicKey[P, B, S], prng io.Reader) (Ciphertext, *Capsule[P, B, S], error)
Encrypt encrypts a plaintext message to the receiver's public key. It returns the ciphertext and the capsule (ephemeral public key) that must be transmitted to the receiver for decryption. This is equivalent to Seal with nil aad.
A fresh sender context is established for each call, generating a new ephemeral key pair and deriving fresh encryption keys.
func (*Encrypter[P, B, S]) Export ¶
func (e *Encrypter[P, B, S]) Export(context []byte, length uint) (*encryption.SymmetricKey, error)
Export derives a secret from the encryption context using the HPKE secret export mechanism. This requires context caching to be enabled via EncryptingWhileCachingRecentContextualInfo.
The exporter_context parameter and length are inputs to the secret derivation. The same inputs will produce the same output on both sender and receiver sides.
See: https://www.rfc-editor.org/rfc/rfc9180.html#section-5.3
func (*Encrypter[P, B, S]) Mode ¶
Mode returns the HPKE mode that will be used for encryption, determined by which authentication parameters have been configured.
func (*Encrypter[P, B, S]) Seal ¶
func (e *Encrypter[P, B, S]) Seal(plaintext Message, receiver *PublicKey[P, B, S], aad []byte, prng io.Reader) (Ciphertext, *Capsule[P, B, S], error)
Seal encrypts a plaintext message with associated data to the receiver's public key. The associated data (aad) is authenticated but not encrypted; it must be provided identically during decryption.
Returns the ciphertext (containing encrypted plaintext and authentication tag) and the capsule (ephemeral public key) needed for decryption.
See: https://www.rfc-editor.org/rfc/rfc9180.html#section-5.2
type KDFID ¶
KDFID is a two-byte value identifying the key derivation function, defined in RFC 9180 Table 2. HPKE uses HKDF with either SHA-256 or SHA-512 as the underlying hash.
See: https://www.rfc-editor.org/rfc/rfc9180.html#section-7.2
type KEM ¶
type KEM[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], S algebra.PrimeFieldElement[S]] struct { // contains filtered or unexported fields }
KEM provides key encapsulation mechanism operations for HPKE. It wraps the underlying DHKEM (Diffie-Hellman based KEM) and supports both standard and authenticated encapsulation.
The KEM generates an ephemeral key pair and combines it with the receiver's public key to produce a shared secret and a capsule (the ephemeral public key).
See: https://www.rfc-editor.org/rfc/rfc9180.html#section-4
func (*KEM[P, B, S]) Encapsulate ¶
func (k *KEM[P, B, S]) Encapsulate(receiver *PublicKey[P, B, S], prng io.Reader) (*encryption.SymmetricKey, *Capsule[P, B, S], error)
Encapsulate generates a shared secret and encapsulates it for the given receiver. Returns:
- A symmetric key derived from the shared secret
- A capsule (ephemeral public key) to send to the receiver
If WithSenderPrivateKey was configured, this performs authenticated encapsulation (AuthEncap), otherwise standard encapsulation (Encap).
See: https://www.rfc-editor.org/rfc/rfc9180.html#section-4.1
func (*KEM[P, B, S]) IsAuthenticated ¶
IsAuthenticated returns true if the sender's private key has been configured, indicating that authenticated encapsulation will be used.
type KEMID ¶
KEMID is a two-byte value identifying the key encapsulation mechanism, defined in RFC 9180 Table 2. This implementation supports DHKEM(P-256, HKDF-SHA256) and DHKEM(X25519, HKDF-SHA256).
See: https://www.rfc-editor.org/rfc/rfc9180.html#section-7.1
type KeyGenerator ¶
type KeyGenerator[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], S algebra.PrimeFieldElement[S]] struct { // contains filtered or unexported fields }
KeyGenerator generates HPKE key pairs for the configured cipher suite. Key generation follows the DeriveKeyPair algorithm defined in RFC 9180 Section 4, which uses the KEM's KDF to derive keys from random input keying material (IKM).
See: https://www.rfc-editor.org/rfc/rfc9180.html#section-4
func (*KeyGenerator[P, B, S]) Generate ¶
func (kg *KeyGenerator[P, B, S]) Generate(prng io.Reader) (sk *PrivateKey[S], pk *PublicKey[P, B, S], err error)
Generate creates a new HPKE key pair using randomness from prng. The private key is derived using the KEM's DeriveKeyPair algorithm with random IKM. The public key is the corresponding curve point pk = sk * G.
func (*KeyGenerator[P, B, S]) GenerateWithSeed ¶
func (kg *KeyGenerator[P, B, S]) GenerateWithSeed(ikm []byte) (sk *PrivateKey[S], pk *PublicKey[P, B, S], err error)
GenerateWithSeed creates a new HPKE key pair deterministically from seed material. The seed (IKM) SHOULD have at least Nsk bytes of entropy for the KEM algorithm. This implements the DeriveKeyPair algorithm from RFC 9180 Section 4.
See: https://www.rfc-editor.org/rfc/rfc9180.html#name-derivekeypair
type KeyGeneratorOption ¶
type KeyGeneratorOption[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], S algebra.PrimeFieldElement[S]] = encryption.KeyGeneratorOption[*KeyGenerator[P, B, S], *PrivateKey[S], *PublicKey[P, B, S]]
KeyGeneratorOption is a functional option for configuring the HPKE key generator. Currently no options are defined as HPKE key generation is fully determined by the cipher suite's KEM algorithm.
type Message ¶
type Message = []byte
Message is the plaintext input to or output from HPKE encryption/decryption.
type ModeID ¶
ModeID is a one-byte value indicating the HPKE mode, defined in RFC 9180 Table 1. The four modes provide different authentication guarantees:
- Base (0x00): No sender authentication
- PSK (0x01): Sender authenticated via pre-shared key
- Auth (0x02): Sender authenticated via asymmetric key
- AuthPSK (0x03): Sender authenticated via both PSK and asymmetric key
type PrivateKey ¶
type PrivateKey[S algebra.PrimeFieldElement[S]] = internal.PrivateKey[S]
PrivateKey represents a KEM private key, which is a scalar in the underlying elliptic curve's scalar field. The private key is used for decapsulation and, in authenticated modes, to prove the sender's identity.
type PublicKey ¶
type PublicKey[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], S algebra.PrimeFieldElement[S]] = internal.PublicKey[P, B, S]
PublicKey represents a KEM public key, which is a point on the underlying elliptic curve. The public key is used for encapsulation and to identify the recipient.
type ReceiverContext ¶
type ReceiverContext[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], S algebra.PrimeFieldElement[S]] = internal.ReceiverContext[P, B, S]
ReceiverContext holds the decryption context established by the receiver after key decapsulation. It provides the Open method for decrypting messages and Export for deriving additional secrets. The context maintains sequence numbers that must match the sender's for successful decryption.
See: https://www.rfc-editor.org/rfc/rfc9180.html#section-5.2
func SetupAuthPSKR ¶
func SetupAuthPSKR[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], S algebra.PrimeFieldElement[S]](suite *CipherSuite, receiverPrivatekey *PrivateKey[S], ephemeralPublicKey, senderPublicKey *PublicKey[P, B, S], psk, pskID, info []byte) (*ReceiverContext[P, B, S], error)
SetupAuthPSKR establishes a decryption context for AuthPSK mode (mode_auth_psk = 0x03). This is the receiver-side counterpart to SetupAuthPSKS.
Both the sender's public key and the PSK are verified during decryption. The decryption will fail if either authentication mechanism fails.
Parameters:
- suite: The cipher suite (must match sender's)
- receiverPrivatekey: The recipient's private key (skR)
- ephemeralPublicKey: The capsule (enc) received from the sender
- senderPublicKey: The sender's public key (pkS) for authentication
- psk: The pre-shared key (must match sender's)
- pskID: Identifier for the PSK (must match sender's)
- info: Application-supplied information (must match sender's)
See: https://www.rfc-editor.org/rfc/rfc9180.html#section-5.1.4
func SetupAuthR ¶
func SetupAuthR[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], S algebra.PrimeFieldElement[S]](suite *CipherSuite, receiverPrivatekey *PrivateKey[S], ephemeralPublicKey, senderPublicKey *PublicKey[P, B, S], info []byte) (*ReceiverContext[P, B, S], error)
SetupAuthR establishes a decryption context for Auth mode (mode_auth = 0x02). This is the receiver-side counterpart to SetupAuthS.
The receiver uses the sender's public key to verify the sender's identity. Decryption will fail if the ciphertext was not created using the corresponding sender private key.
Parameters:
- suite: The cipher suite (must match sender's)
- receiverPrivatekey: The recipient's private key (skR)
- ephemeralPublicKey: The capsule (enc) received from the sender
- senderPublicKey: The sender's public key (pkS) for authentication
- info: Application-supplied information (must match sender's)
See: https://www.rfc-editor.org/rfc/rfc9180.html#section-5.1.3
func SetupBaseR ¶
func SetupBaseR[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], S algebra.PrimeFieldElement[S]](suite *CipherSuite, receiverPrivatekey *PrivateKey[S], ephemeralPublicKey *PublicKey[P, B, S], info []byte) (*ReceiverContext[P, B, S], error)
SetupBaseR establishes a decryption context for Base mode (mode_base = 0x00). This is the receiver-side counterpart to SetupBaseS.
Parameters:
- suite: The cipher suite (must match sender's)
- receiverPrivatekey: The recipient's private key (skR)
- ephemeralPublicKey: The capsule (enc) received from the sender
- info: Application-supplied information (must match sender's)
See: https://www.rfc-editor.org/rfc/rfc9180.html#section-5.1.1
func SetupPSKR ¶
func SetupPSKR[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], S algebra.PrimeFieldElement[S]](suite *CipherSuite, receiverPrivatekey *PrivateKey[S], ephemeralPublicKey *PublicKey[P, B, S], psk, pskID, info []byte) (*ReceiverContext[P, B, S], error)
SetupPSKR establishes a decryption context for PSK mode (mode_psk = 0x01). This is the receiver-side counterpart to SetupPSKS.
Parameters:
- suite: The cipher suite (must match sender's)
- receiverPrivatekey: The recipient's private key (skR)
- ephemeralPublicKey: The capsule (enc) received from the sender
- psk: The pre-shared key (must match sender's)
- pskID: Identifier for the PSK (must match sender's)
- info: Application-supplied information (must match sender's)
See: https://www.rfc-editor.org/rfc/rfc9180.html#section-5.1.2
type Scheme ¶
type Scheme[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], S algebra.PrimeFieldElement[S]] struct { // contains filtered or unexported fields }
Scheme is the main HPKE scheme type, parameterised by the elliptic curve point type. It combines a KEM, KDF, and AEAD to provide hybrid public-key encryption as specified in RFC 9180. The scheme supports all four HPKE modes: Base, PSK, Auth, and AuthPSK.
func NewScheme ¶
func NewScheme[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], S algebra.PrimeFieldElement[S]](curve curves.Curve[P, B, S], cipherSuite *CipherSuite) (*Scheme[P, B, S], error)
NewScheme creates a new HPKE scheme parameterised by the given elliptic curve and cipher suite. The curve determines the KEM (key encapsulation mechanism), while the cipher suite specifies the KDF (key derivation function) and AEAD (authenticated encryption) algorithms.
The scheme provides factory methods for creating encrypters, decrypters, and direct access to KEM/DEM operations for more advanced use cases.
func (*Scheme[P, B, S]) AEAD ¶
func (s *Scheme[P, B, S]) AEAD(key *encryption.SymmetricKey) (cipher.AEAD, error)
AEAD returns an AEAD cipher instance initialised with the given symmetric key. This provides direct access to the underlying AEAD algorithm (AES-GCM or ChaCha20Poly1305) for use cases requiring manual key management outside the standard HPKE flow.
func (*Scheme[P, B, S]) CipherSuite ¶
func (s *Scheme[P, B, S]) CipherSuite() *CipherSuite
CipherSuite returns the cipher suite used by this scheme.
func (*Scheme[P, B, S]) DEM ¶
func (s *Scheme[P, B, S]) DEM(receiverPrivateKey *PrivateKey[S], opts ...encryption.DEMOption[*DEM[P, B, S], *Capsule[P, B, S]]) (*DEM[P, B, S], error)
DEM returns a data encapsulation mechanism instance for this scheme. The DEM uses the receiver's private key to decapsulate the shared secret from a capsule. Use WithSenderPublicKey option to enable authenticated decapsulation (Auth mode).
func (*Scheme[P, B, S]) Decrypter ¶
func (s *Scheme[P, B, S]) Decrypter(receiverPrivateKey *PrivateKey[S], opts ...encryption.DecrypterOption[*Decrypter[P, B, S], Message, Ciphertext]) (*Decrypter[P, B, S], error)
Decrypter creates an HPKE decrypter that can open messages encrypted to the receiver's public key. The decrypter requires the receiver's private key and the capsule (ephemeral public key) from the sender. The receiver context is established during construction based on the configured mode.
Required option:
- DecryptingWithCapsule: The capsule (enc) received from the sender
Mode-specific options:
- DecryptingWithApplicationInfo: Set application-specific info parameter (must match sender)
- DecryptingWithAuthentication: Enable Auth mode with sender's public key
- DecryptingWithPreSharedKey: Enable PSK mode with pre-shared key
- DecryptingWithAuthPSK: Enable AuthPSK mode with both
func (*Scheme[P, B, S]) Encrypter ¶
func (s *Scheme[P, B, S]) Encrypter(opts ...encryption.EncrypterOption[*Encrypter[P, B, S], *PublicKey[P, B, S], Message, Ciphertext, *Capsule[P, B, S]]) (*Encrypter[P, B, S], error)
Encrypter creates an HPKE encrypter that can seal messages to a recipient's public key. The encrypter establishes a fresh sender context for each encryption, unless caching is enabled via EncryptingWhileCachingRecentContextualInfo.
Available options configure the HPKE mode:
- EncryptingWithApplicationInfo: Set application-specific info parameter
- EncryptingWithAuthentication: Enable Auth mode with sender's private key
- EncryptingWithPreSharedKey: Enable PSK mode with pre-shared key
- EncryptingWithAuthPSK: Enable AuthPSK mode with both
- EncryptingWhileCachingRecentContextualInfo: Cache context for Export
func (*Scheme[P, B, S]) KEM ¶
func (s *Scheme[P, B, S]) KEM(opts ...encryption.KEMOption[*KEM[P, B, S], *PublicKey[P, B, S], *Capsule[P, B, S]]) (*KEM[P, B, S], error)
KEM returns a key encapsulation mechanism instance for this scheme. In HPKE, the KEM is used to establish a shared secret between sender and receiver. Use WithSenderPrivateKey option to enable authenticated encapsulation (Auth mode).
func (*Scheme[P, B, S]) Keygen ¶
func (s *Scheme[P, B, S]) Keygen(opts ...KeyGeneratorOption[P, B, S]) (*KeyGenerator[P, B, S], error)
Keygen creates a key generator for this HPKE scheme. The key generator produces key pairs compatible with the scheme's KEM algorithm. Key generation follows RFC 9180 Section 4, using DeriveKeyPair with random IKM.
func (*Scheme[P, B, S]) Name ¶
func (*Scheme[P, B, S]) Name() encryption.Name
Name returns the scheme identifier "HPKE".
type SenderContext ¶
type SenderContext[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], S algebra.PrimeFieldElement[S]] = internal.SenderContext[P, B, S]
SenderContext holds the encryption context established by the sender after key encapsulation. It provides the Seal method for encrypting messages and Export for deriving additional secrets. The context maintains sequence numbers to ensure unique nonces for each encryption operation.
See: https://www.rfc-editor.org/rfc/rfc9180.html#section-5.2
func SetupAuthPSKS ¶
func SetupAuthPSKS[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], S algebra.PrimeFieldElement[S]](suite *CipherSuite, receiverPublicKey *PublicKey[P, B, S], senderPrivateKey *PrivateKey[S], psk, pskID, info []byte, prng io.Reader) (sender *SenderContext[P, B, S], err error)
SetupAuthPSKS establishes an encryption context for AuthPSK mode (mode_auth_psk = 0x03). This mode combines both PSK and asymmetric authentication, providing defence in depth.
The sender is authenticated via both mechanisms: the PSK is incorporated into the key schedule, and the sender's private key is used in the encapsulation. Both must be valid for decryption to succeed.
Parameters:
- suite: The cipher suite specifying KEM, KDF, and AEAD algorithms
- receiverPublicKey: The recipient's public key (pkR)
- senderPrivateKey: The sender's private key (skS) for authentication
- psk: The pre-shared key (MUST have at least 32 bytes of entropy)
- pskID: Identifier for the PSK
- info: Application-supplied information (optional; default "")
- prng: Source of randomness for ephemeral key generation
See: https://www.rfc-editor.org/rfc/rfc9180.html#section-5.1.4
func SetupAuthS ¶
func SetupAuthS[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], S algebra.PrimeFieldElement[S]](suite *CipherSuite, receiverPublicKey *PublicKey[P, B, S], senderPrivateKey *PrivateKey[S], info []byte, prng io.Reader) (sender *SenderContext[P, B, S], err error)
SetupAuthS establishes an encryption context for Auth mode (mode_auth = 0x02). This mode authenticates the sender via an asymmetric key pair, allowing the recipient to verify the sender possessed the corresponding private key.
Unlike PSK mode, Auth mode provides non-repudiation: only the holder of skS could have created the ciphertext. However, it requires the receiver to know the sender's public key in advance.
Parameters:
- suite: The cipher suite specifying KEM, KDF, and AEAD algorithms
- receiverPublicKey: The recipient's public key (pkR)
- senderPrivateKey: The sender's private key (skS) for authentication
- info: Application-supplied information (optional; default "")
- prng: Source of randomness for ephemeral key generation
See: https://www.rfc-editor.org/rfc/rfc9180.html#section-5.1.3
func SetupBaseS ¶
func SetupBaseS[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], S algebra.PrimeFieldElement[S]](suite *CipherSuite, receiverPublicKey *PublicKey[P, B, S], info []byte, prng io.Reader) (sender *SenderContext[P, B, S], err error)
SetupBaseS establishes an encryption context for Base mode (mode_base = 0x00). This mode provides encryption to a public key without sender authentication.
Parameters:
- suite: The cipher suite specifying KEM, KDF, and AEAD algorithms
- receiverPublicKey: The recipient's public key (pkR)
- info: Application-supplied information (optional; default "")
- prng: Source of randomness for ephemeral key generation
Returns a SenderContext containing the capsule (enc) to send to the receiver.
See: https://www.rfc-editor.org/rfc/rfc9180.html#section-5.1.1
func SetupPSKS ¶
func SetupPSKS[P curves.Point[P, B, S], B algebra.FiniteFieldElement[B], S algebra.PrimeFieldElement[S]](suite *CipherSuite, receiverPublicKey *PublicKey[P, B, S], psk, pskID, info []byte, prng io.Reader) (sender *SenderContext[P, B, S], err error)
SetupPSKS establishes an encryption context for PSK mode (mode_psk = 0x01). This mode authenticates the sender via a pre-shared key known to both parties.
The PSK provides authentication: the receiver can verify the sender possessed the PSK, but compromise of the PSK allows impersonation.
Parameters:
- suite: The cipher suite specifying KEM, KDF, and AEAD algorithms
- receiverPublicKey: The recipient's public key (pkR)
- psk: The pre-shared key (MUST have at least 32 bytes of entropy)
- pskID: Identifier for the PSK (used to select among multiple PSKs)
- info: Application-supplied information (optional; default "")
- prng: Source of randomness for ephemeral key generation
See: https://www.rfc-editor.org/rfc/rfc9180.html#section-5.1.2