ratchet

package module
v0.0.0-...-a49b7e6 Latest Latest
Warning

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

Go to latest
Published: Aug 2, 2024 License: AGPL-3.0 Imports: 13 Imported by: 0

README

cryptonomicon

Modular KEM double ratchet

Go Reference Go Report Card CI

The KEM double ratchet's design is superior to the NIKE double ratchet; besides it being way better for composing fully hybrid post quantum ratchets, it achieves post compromise security in just 2 rounds. Just because it uses a KEM doesn't mean you can't use a NIKE; as with Xwing, you can simply compose NIKEs as KEMs using an adhoc hashed ElGamal construction.

This modular KEM double ratchet design comes from the following 2020 paper: The Double Ratchet: Security Notions, Proofs, and Modularization for the Signal Protocol

Besides this implementation, my other contributions so far, are:

Status

It works. Although there's some more work to be done to make it "production ready" quality code. In particular the current KEM double ratchet implementation does not remove the old instances of the FS AEAD and the FS-Max isn't enforced.

Cryptography suite

This implementation of the modular KEM double ratchet uses the hpqc cryptography library and thus has what is now known in modern parlance as "cryptographic agility" via golang interfaces. Thus, we can use any KEM with this KEM double ratchet and if you aren't completely satisfied any of the available KEMs then roll your own KEM. Combine your favorite classical NIKE with your favorite Post Quantum KEM if Xwing is not the hybrid KEM you are looking for:

	combiner.New(
		"MLKEM768-X448",
		[]kem.Scheme{
			adapter.FromNIKE(x448.Scheme(rand.Reader)),
			mlkem768.Scheme(),
		},
	),

License

AGPLv3

Documentation

Overview

KEM double ratchet

KEM double ratchet

KEM double ratchet

KEM double ratchet

Index

Constants

View Source
const (
	CKA_SeedSize = 64
	CBOROverhead = 26
)
View Source
const (
	// StreamKeyLength is the key size of the stream cipher in bytes.
	StreamKeyLength = 32

	// StreamIVLength is the IV size of the stream cipher in bytes.
	StreamIVLength = 16

	// FSAEADSeedLength is the length of the seed for creating a new FS-AEAD
	FSAEADSeedLength = StreamKeyLength + StreamIVLength + symmetricKeySize

	SeedSize = 64
)
View Source
const (
	PRF_PRNG_Keysize = blake2b.Size
)
View Source
const (
	RatchetSeedSize = CKA_SeedSize + PRF_PRNG_Keysize
)

Variables

This section is empty.

Functions

This section is empty.

Types

type CKAMessage

type CKAMessage struct {
	// PublicKey is the new KEM public key.
	PublicKey []byte
	// Ciphertext is the new KEM ciphertext.
	Ciphertext []byte
}

CKAMessage encapsulates a CKA Message.

type CKAState

type CKAState struct {
	// PublicKey is the KEM public key.
	PublicKey []byte

	// PrivateKey is the KEM private key.
	PrivateKey []byte

	// KEMSchemeName is the unique name for the KEM scheme being used
	// from the HPQC cryptography library.
	KEMSchemeName string
}

CKAState is a state type used by the CKA.

func NewCKA

func NewCKA(kemName string, ikm []byte, isInitiator bool) (*CKAState, error)

NewCKA returns a newly constructed CKA.

func NewCKAState

func NewCKAState(publicKey kem.PublicKey, privateKey kem.PrivateKey, kemName string) (*CKAState, error)

NewCKAState constructs a new SKAState given a keypair.

func (*CKAState) Receive

func (c *CKAState) Receive(message *CKAMessage) ([]byte, error)

Receive performs the CKA Receive operation.

func (*CKAState) Send

func (c *CKAState) Send() (*CKAMessage, []byte, error)

Send performs the CKA Send operation.

type ForwardSecureAEAD

type ForwardSecureAEAD struct {
	PRG *Stream

	AEADKey *[chacha20poly1305.KeySize]byte

	KeyStorage map[uint32][]byte

	ReceiveCount uint32
	ReceiveMax   uint32

	SendCount uint32
	SendMax   uint32
}

ForwardSecureAEAD is a forward-secure AEAD cipher as described in section `4.2 Forward-Secure AEAD` of the paper: https://eprint.iacr.org/2018/1037.pdf The Double Ratchet: Security Notions, Proofs, and Modularization for the Signal Protocol

"Forward-secure authenticated encryption with associated data is a stateful primitive between a sender A and a receiver B and can be considered a single-epoch variant of an SM scheme, a fact that is also evident from its security definition, which resembles that of SM schemes."

func NewFSAEAD

func NewFSAEAD(seed []byte, isSender bool) (*ForwardSecureAEAD, error)

NewFSAEAD creates a new instance of ForwardSecureAEAD

func (*ForwardSecureAEAD) Max

func (f *ForwardSecureAEAD) Max(max uint32)

func (*ForwardSecureAEAD) Receive

func (f *ForwardSecureAEAD) Receive(ciphertext, ad []byte) ([]byte, error)

Receive implements the FSAEAD receive op.

func (*ForwardSecureAEAD) Reset

func (f *ForwardSecureAEAD) Reset()

func (*ForwardSecureAEAD) Send

func (f *ForwardSecureAEAD) Send(message, ad []byte) ([]byte, []byte)

Send implements the FSAEAD send op.

func (*ForwardSecureAEAD) Stop

func (f *ForwardSecureAEAD) Stop() uint32

type PRF_PRNG

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

func NewPRF_PRNG

func NewPRF_PRNG(key []byte) (*PRF_PRNG, error)

func (*PRF_PRNG) Up

func (p *PRF_PRNG) Up(b []byte) []byte

type Ratchet

type Ratchet struct {
	IsA bool

	States map[uint32]*ForwardSecureAEAD

	Max      uint32
	Root     *PRF_PRNG
	CKAState *CKAState

	CurrentMessage *CKAMessage

	PrevSendCount uint32
	EpochCount    uint32

	KEMSchemeName string
}

func FromBlob

func FromBlob(b []byte) (*Ratchet, error)

func New

func New(seed []byte, isA bool) (*Ratchet, error)

func (*Ratchet) Marshal

func (r *Ratchet) Marshal() ([]byte, error)

func (*Ratchet) Receive

func (r *Ratchet) Receive(ciphertext []byte) ([]byte, error)

Receive decrypts the ciphertext and returns the plaintext or an error.

func (*Ratchet) Reset

func (r *Ratchet) Reset()

func (*Ratchet) Send

func (r *Ratchet) Send(message []byte) []byte

Send comsumes the given message and returns a ciphertext.

func (*Ratchet) WithMax

func (r *Ratchet) WithMax(max uint32) *Ratchet

type Stream

type Stream struct {
	Key *[StreamKeyLength]byte
	Iv  *[StreamIVLength]byte
}

Stream is the Sphinx stream cipher.

func NewStream

func NewStream(key *[StreamKeyLength]byte, iv *[StreamIVLength]byte) *Stream

NewStream returns a new Stream implementing the Sphinx Stream Cipher with the provided key and IV.

func (*Stream) KeyStream

func (s *Stream) KeyStream(dst []byte)

KeyStream fills the buffer dst with key stream output.

func (*Stream) Reset

func (s *Stream) Reset()

Jump to

Keyboard shortcuts

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