newplex

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

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

Go to latest
Published: Feb 24, 2026 License: Apache-2.0, MIT Imports: 8 Imported by: 0

README

Newplex

Newplex is a cryptographic framework that provides a unified interface for unkeyed and symmetric-key operations. It is built on a duplex construction using the Simpira-1024 permutation. Inspired by STROBE, Noise Protocol, and Xoodyak, Newplex is optimized for 64-bit architectures (x86-64 and ARM64) to provide 10+ Gb/second performance on modern processors at a 128-bit security level.

Two design principles guide the framework. First, replacing separate hash functions, MACs, stream ciphers, and KDFs with a single duplex construction simplifies the design and implementation of cryptographic schemes--from basic AEAD to multi-party protocols like OPRFs and handshakes. Second, the security of every scheme reduces to the properties of the underlying duplex (indifferentiability from a random oracle, pseudorandom function security, and collision resistance), all bounded by the 256-bit capacity (2**128 against generic attacks). A single security analysis of the duplex and permutation layers covers the entire framework.

⚠️ Security Warning

[!WARNING] This code has not been audited. This design has not been analyzed. The design is documented in design.md; read it and see if the arguments therein are convincing. It is experimental and should not be used for production systems or critical security applications. Use at your own risk.

Installation

go get github.com/codahale/newplex

Usage

On AMD64 and ARM64 architectures, newplex uses hardware AES instructions for performance. On other architectures, or if the purego build tag is used, it falls back to a slower Go implementation with a bit-sliced, constant-time AES round implementation.

The AMD64 implementation requires AES-NI and SSE2. The ARM64 implementation requires ARMv8 Crypto Extensions and ASIMD (NEON).

To force the portable implementation, use the purego build tag:

go build -tags purego ./...
Protocol

Protocol is a high-level API for building cryptographic schemes (e.g., hash functions, MACs, stream ciphers, AEADs, sessions) with built-in domain separation and state management.

// Initialize a protocol with a domain separation string.
p := newplex.NewProtocol("my-app.my-protocol")

// Mix key material and other data into the state.
p.Mix("key", []byte("secret-key-material"))
p.Mix("nonce", []byte("unique-nonce"))

// Mask a message (provides confidentiality only).
plaintext := []byte("Hello, World!")
ciphertext := p.Mask("message", nil, plaintext)

// Or Seal a message (provides confidentiality + authenticity).
sealed := p.Seal("secure-message", nil, plaintext)

// Derive pseudorandom output (like a KDF or Hash).
tag := p.Derive("tag", nil, 32)
Standard Packages

Newplex includes the following cryptographic schemes as sub-packages:

  • newplex/adratchet: Implements a Signal-like asynchronous double ratchet.
  • newplex/aead: Implements cipher.AEAD with support for additional data.
  • newplex/aestream: Implements a streaming authenticated encryption scheme.
  • newplex/digest: Implements hash.Hash (both keyed and unkeyed).
  • newplex/frost: Implements FROST threshold Schnorr signatures.
  • newplex/handshake: Implements a mutually authenticated handshake.
  • newplex/hpke: Implements a hybrid public-key encryption scheme.
  • newplex/mhf: Implements the DEGSample data-dependent memory-hard hash function for password hashing.
  • newplex/oae2: Implements OAE2-secure streaming authenticated encryption with fixed-size blocks.
  • newplex/oprf: Implements an RFC 9497-style Oblivious Pseudorandom Function (OPRF) and Verifiable OPRF (VOPRF).
  • newplex/pake: Implements a CPace-style password-authenticated key exchange (PAKE).
  • newplex/sig: Implements EdDSA-style Schnorr digital signatures.
  • newplex/signcrypt: Implements integrated public-key encryption and signing.
  • newplex/siv: Implements a SIV-style deterministic authentication scheme.
  • newplex/vrf: Implements a verifiable random function.

Design details are in design.md.

Performance

Newplex targets 10+ Gbp/sec performance on modern server processors.

AMD64
goos: linux
goarch: amd64
pkg: github.com/codahale/newplex
cpu: INTEL(R) XEON(R) PLATINUM 8581C CPU @ 2.30GHz
BenchmarkHashScheme/16B                 12040262               100.3 ns/op       159.59 MB/s           0 B/op          0 allocs/op
BenchmarkHashScheme/32B                 12383924                97.94 ns/op      326.72 MB/s           0 B/op          0 allocs/op
BenchmarkHashScheme/64B                 12391802                96.91 ns/op      660.43 MB/s           0 B/op          0 allocs/op
BenchmarkHashScheme/128B                 8559896               143.5 ns/op       892.19 MB/s           0 B/op          0 allocs/op
BenchmarkHashScheme/256B                 5004840               236.5 ns/op      1082.58 MB/s           0 B/op          0 allocs/op
BenchmarkHashScheme/1KiB                 1935332               620.4 ns/op      1650.50 MB/s           0 B/op          0 allocs/op
BenchmarkHashScheme/16KiB                 142461              8313 ns/op        1970.96 MB/s           0 B/op          0 allocs/op
BenchmarkHashScheme/1MiB                    2323            521616 ns/op        2010.24 MB/s           0 B/op          0 allocs/op
BenchmarkPRFScheme/16B                  12368185                97.01 ns/op      164.93 MB/s           0 B/op          0 allocs/op
BenchmarkPRFScheme/32B                  11872790                99.43 ns/op      321.82 MB/s           0 B/op          0 allocs/op
BenchmarkPRFScheme/64B                  12190263                98.16 ns/op      652.01 MB/s           0 B/op          0 allocs/op
BenchmarkPRFScheme/128B                  7932213               149.6 ns/op       855.64 MB/s           0 B/op          0 allocs/op
BenchmarkPRFScheme/256B                  5986339               200.7 ns/op      1275.61 MB/s           0 B/op          0 allocs/op
BenchmarkPRFScheme/1KiB                  1988391               607.1 ns/op      1686.61 MB/s           0 B/op          0 allocs/op
BenchmarkPRFScheme/16KiB                  137037              8758 ns/op        1870.68 MB/s           0 B/op          0 allocs/op
BenchmarkPRFScheme/1MiB                     2091            560482 ns/op        1870.85 MB/s           0 B/op          0 allocs/op
BenchmarkStreamScheme/16B                9501328               124.3 ns/op       128.76 MB/s           0 B/op          0 allocs/op
BenchmarkStreamScheme/32B                9802387               123.3 ns/op       259.56 MB/s           0 B/op          0 allocs/op
BenchmarkStreamScheme/64B               10008786               121.7 ns/op       525.88 MB/s           0 B/op          0 allocs/op
BenchmarkStreamScheme/128B               6941865               172.2 ns/op       743.39 MB/s           0 B/op          0 allocs/op
BenchmarkStreamScheme/256B               5363806               221.7 ns/op      1154.50 MB/s           0 B/op          0 allocs/op
BenchmarkStreamScheme/1KiB               1879706               641.2 ns/op      1596.93 MB/s           0 B/op          0 allocs/op
BenchmarkStreamScheme/16KiB               129224              9273 ns/op        1766.90 MB/s           0 B/op          0 allocs/op
BenchmarkStreamScheme/1MiB                  2012            584774 ns/op        1793.13 MB/s           0 B/op          0 allocs/op
BenchmarkAEADScheme/16B                  5032033               242.6 ns/op       131.91 MB/s           0 B/op          0 allocs/op
BenchmarkAEADScheme/32B                  4939018               241.1 ns/op       199.07 MB/s           0 B/op          0 allocs/op
BenchmarkAEADScheme/64B                  4890608               244.1 ns/op       327.70 MB/s           0 B/op          0 allocs/op
BenchmarkAEADScheme/128B                 4093395               295.3 ns/op       487.67 MB/s           0 B/op          0 allocs/op
BenchmarkAEADScheme/256B                 3391336               356.6 ns/op       762.71 MB/s           0 B/op          0 allocs/op
BenchmarkAEADScheme/1KiB                 1559380               772.3 ns/op      1346.67 MB/s           0 B/op          0 allocs/op
BenchmarkAEADScheme/16KiB                 127945              9371 ns/op        1750.11 MB/s           0 B/op          0 allocs/op
BenchmarkAEADScheme/1MiB                    2013            583608 ns/op        1796.74 MB/s           0 B/op          0 allocs/op
ARM64
goos: darwin                                                                                                                                                                                                                                                             
goarch: arm64                                                                                                                                                                                                                                                            
pkg: github.com/codahale/newplex                                                                                                                                                                                                                                         
cpu: Apple M4 Pro                                                                                                                                                                                                                                                        
BenchmarkHashScheme/16B                 20705578                57.71 ns/op      277.23 MB/s           0 B/op          0 allocs/op                                                                                                                                       
BenchmarkHashScheme/32B                 22098853                53.93 ns/op      593.32 MB/s           0 B/op          0 allocs/op                                                                                                                                       
BenchmarkHashScheme/64B                 21734372                54.93 ns/op     1165.12 MB/s           0 B/op          0 allocs/op                                                                                                                                       
BenchmarkHashScheme/128B                13497021                88.48 ns/op     1446.59 MB/s           0 B/op          0 allocs/op                                                                                                                                       
BenchmarkHashScheme/256B                 7603873               157.3 ns/op      1627.84 MB/s           0 B/op          0 allocs/op                                                                                                                                       
BenchmarkHashScheme/1KiB                 2694968               445.0 ns/op      2301.27 MB/s           0 B/op          0 allocs/op                                                                                                                                       
BenchmarkHashScheme/16KiB                 190098              6272 ns/op        2612.37 MB/s           0 B/op          0 allocs/op                                                                                                                                       
BenchmarkHashScheme/1MiB                    2961            399703 ns/op        2623.39 MB/s           0 B/op          0 allocs/op                                                                                                                                       
BenchmarkPRFScheme/16B                  20697609                57.13 ns/op      280.07 MB/s           0 B/op          0 allocs/op                                                                                                                                       
BenchmarkPRFScheme/32B                  21585451                55.05 ns/op      581.25 MB/s           0 B/op          0 allocs/op                                                                                                                                       
BenchmarkPRFScheme/64B                  21558080                55.18 ns/op     1159.86 MB/s           0 B/op          0 allocs/op                                                                                                                                       
BenchmarkPRFScheme/128B                 13316527                89.84 ns/op     1424.81 MB/s           0 B/op          0 allocs/op                                                                                                                                       
BenchmarkPRFScheme/256B                  9715753               123.1 ns/op      2080.31 MB/s           0 B/op          0 allocs/op                                                                                                                                       
BenchmarkPRFScheme/1KiB                  3111435               385.6 ns/op      2655.78 MB/s           0 B/op          0 allocs/op                                                                                                                                       
BenchmarkPRFScheme/16KiB                  206236              5798 ns/op        2825.93 MB/s           0 B/op          0 allocs/op                                                                                                                                       
BenchmarkPRFScheme/1MiB                     3206            375638 ns/op        2791.45 MB/s           0 B/op          0 allocs/op                                                                                                                                       
BenchmarkStreamScheme/16B               16954888                70.21 ns/op      227.88 MB/s           0 B/op          0 allocs/op                                                                                                                                       
BenchmarkStreamScheme/32B               17085883                70.31 ns/op      455.14 MB/s           0 B/op          0 allocs/op                                                                                                                                       
BenchmarkStreamScheme/64B               16449922                71.60 ns/op      893.84 MB/s           0 B/op          0 allocs/op                                                                                                                                       
BenchmarkStreamScheme/128B              11257392               108.6 ns/op      1178.95 MB/s           0 B/op          0 allocs/op                                                                                                                                       
BenchmarkStreamScheme/256B               8345169               146.1 ns/op      1751.64 MB/s           0 B/op          0 allocs/op                                                                                                                                       
BenchmarkStreamScheme/1KiB               2718831               441.4 ns/op      2320.04 MB/s           0 B/op          0 allocs/op                                                                                                                                       
BenchmarkStreamScheme/16KiB               184890              6514 ns/op        2515.28 MB/s           0 B/op          0 allocs/op                                                                                                                                       
BenchmarkStreamScheme/1MiB                  2780            422931 ns/op        2479.31 MB/s           0 B/op          0 allocs/op                                                                                                                                       
BenchmarkAEADScheme/16B                  7811796               156.5 ns/op       204.47 MB/s           0 B/op          0 allocs/op                                                                                                                                       
BenchmarkAEADScheme/32B                  7802522               153.5 ns/op       312.73 MB/s           0 B/op          0 allocs/op                                                                                                                                       
BenchmarkAEADScheme/64B                  7799248               154.5 ns/op       517.70 MB/s           0 B/op          0 allocs/op                                                                                                                                       
BenchmarkAEADScheme/128B                 6290869               196.5 ns/op       732.93 MB/s           0 B/op          0 allocs/op                                                                                                                                       
BenchmarkAEADScheme/256B                 4994802               236.1 ns/op      1152.09 MB/s           0 B/op          0 allocs/op                                                                                                                                       
BenchmarkAEADScheme/1KiB                 2260888               523.3 ns/op      1987.22 MB/s           0 B/op          0 allocs/op
BenchmarkAEADScheme/16KiB                 184443              6460 ns/op        2538.68 MB/s           0 B/op          0 allocs/op
BenchmarkAEADScheme/1MiB                    2961            410017 ns/op        2557.43 MB/s           0 B/op          0 allocs/op

License

MIT or Apache 2.0.

Documentation

Overview

Package newplex provides an incremental, stateful cryptographic primitive for symmetric-key cryptographic operations (e.g., hashing, encryption, message authentication codes, and authenticated encryption) in complex schemes. Inspired by TupleHash, STROBE, Noise Protocol's stateful objects, Merlin transcripts, DuplexWrap, and Xoodyak's Cyclist mode, Newplex uses the Simpira-1024 permutation to provide 10+ Gb/second performance on modern processors at a 128-bit security level.

On AMD64 and ARM64 architectures, newplex uses the AES-NI instruction set to achieve this level of performance. On other architectures, or if the purego build tag is used, it uses a much-slower Go implementation with a bit-sliced, constant-time AES round implementation.

Example
package main

import (
	"fmt"

	"github.com/codahale/newplex"
)

func main() {
	protocol := newplex.NewProtocol("com.example.kat")
	protocol.Mix("first", []byte("one"))
	protocol.Mix("second", []byte("two"))

	third := protocol.Derive("third", nil, 8)
	fmt.Printf("Derive('third', 8) = %x\n", third)

	plaintext := []byte("this is an example")
	ciphertext := protocol.Mask("fourth", nil, plaintext)
	fmt.Printf("Mask('fourth', '%s') = %x\n", plaintext, ciphertext)

	ciphertext = protocol.Seal("fifth", nil, []byte("this is an example"))
	fmt.Printf("Seal('fifth', '%s') = %x\n", plaintext, ciphertext)

	sixth := protocol.Derive("sixth", nil, 8)
	fmt.Printf("Derive('sixth', 8) = %x\n", sixth)

}
Output:

Derive('third', 8) = 78176ca0f97f7ba2
Mask('fourth', 'this is an example') = 02a181698f527c7818039cad5e65dc714655
Seal('fifth', 'this is an example') = ec9d04766b7fabc40ae93a5b6e950c5bf411faa962577543750b1ef7a4258e5e866f
Derive('sixth', 8) = aa743b650db5458c

Index

Examples

Constants

View Source
const TagSize = 16

TagSize is the number of bytes added to the plaintext by the Seal operation.

Variables

View Source
var ErrInvalidCiphertext = errors.New("newplex: invalid ciphertext")

ErrInvalidCiphertext is returned when the ciphertext is invalid or has been decrypted with the wrong key.

Functions

This section is empty.

Types

type CryptStream

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

CryptStream implements a streaming version of a protocol's Mask or Unmask operation.

N.B.: After the stream has been masked or unmasked, the caller MUST call Close to complete the operation.

func (*CryptStream) Close

func (c *CryptStream) Close() error

Close ends the Mask or Unmask operation and marks the underlying protocol as available for other operations.

func (*CryptStream) XORKeyStream

func (c *CryptStream) XORKeyStream(dst, src []byte)

XORKeyStream XORs each byte in the given slice with a byte from the cipher's key stream. Dst and src must overlap entirely or not at all.

If len(dst) < len(src), XORKeyStream should panic. It is acceptable to pass a dst bigger than src, and in that case, XORKeyStream will only update dst[:len(src)] and will not touch the rest of dst.

Multiple calls to XORKeyStream behave as if the concatenation of the src buffers was passed in a single run. That is, Stream maintains state and does not reset at each XORKeyStream call.

type MixWriter

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

MixWriter allows for the incremental processing of a stream of data into a single Mix operation on a protocol.

func (*MixWriter) Branch

func (m *MixWriter) Branch() *Protocol

Branch returns a clone of the writer's protocol with the Mix operation completed. The original writer and protocol remain unmodified.

func (*MixWriter) Close

func (m *MixWriter) Close() error

Close ends the Mix operation and marks the underlying protocol as available for other operations.

func (*MixWriter) Write

func (m *MixWriter) Write(p []byte) (n int, err error)

type Protocol

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

A Protocol is a stateful object providing fine-grained symmetric-key cryptographic services like hashing, message authentication codes, pseudorandom functions, authenticated encryption, and more.

Protocol instances are not concurrent-safe.

Example (Aead)
package main

import (
	"fmt"

	"github.com/codahale/newplex"
)

func main() {
	encrypt := func(key, nonce, ad, plaintext []byte) []byte {
		// Initialize a protocol with a domain string.
		aead := newplex.NewProtocol("com.example.aead")

		// Mix the key and nonce into the protocol.
		aead.Mix("key", key)
		aead.Mix("nonce", nonce)

		// Mix the authenticated data into the protocol.
		aead.Mix("ad", ad)

		// Seal the plaintext.
		return aead.Seal("message", nil, plaintext)
	}

	decrypt := func(key, nonce, ad, ciphertext []byte) ([]byte, error) {
		// Initialize a protocol with a domain string.
		aead := newplex.NewProtocol("com.example.aead")

		// Mix the key and nonce into the protocol.
		aead.Mix("key", key)
		aead.Mix("nonce", nonce)

		// Mix the authenticated data into the protocol.
		aead.Mix("ad", ad)

		// Open the ciphertext.
		return aead.Open("message", nil, ciphertext)
	}

	key := []byte("my-secret-key")
	nonce := []byte("actually random")
	ad := []byte("some authenticated data")
	plaintext := []byte("hello world")

	ciphertext := encrypt(key, nonce, ad, plaintext)
	fmt.Printf("ciphertext = %x\n", ciphertext)

	plaintext, err := decrypt(key, nonce, ad, ciphertext)
	if err != nil {
		panic(err)
	}
	fmt.Printf("plaintext  = %s\n", plaintext)

}
Output:

ciphertext = 3a8f6fa30018ff130831988969f1c4475a06ddddcd027cd4e707e3
plaintext  = hello world
Example (Hpke)
package main

import (
	"crypto/ecdh"
	"encoding/hex"
	"fmt"

	"github.com/codahale/newplex"
)

func main() {
	encrypt := func(receiver *ecdh.PublicKey, plaintext []byte) []byte {
		// This should be randomly generated, but it would make the test always fail.
		ephemeralPrivBuf, _ := hex.DecodeString("a0b9a9ea71d45df9a8c7cf7da798c4394342993b21f24c7bb3612e573e8a58df")
		ephemeral, _ := ecdh.X25519().NewPrivateKey(ephemeralPrivBuf)

		// Initialize a protocol with a domain string.
		hpke := newplex.NewProtocol("com.example.hpke")

		// Mix the receiver's public key and the ephemeral public key into the protocol.
		hpke.Mix("receiver", receiver.Bytes())
		hpke.Mix("ephemeral", ephemeral.PublicKey().Bytes())

		// Mix the ECDH shared secret into the protocol.
		ss, err := ephemeral.ECDH(receiver)
		if err != nil {
			panic(err)
		}
		hpke.Mix("ecdh", ss)

		// Seal the plaintext and append it to the ephemeral public key.
		return hpke.Seal("message", ephemeral.PublicKey().Bytes(), plaintext)
	}

	decrypt := func(receiver *ecdh.PrivateKey, ciphertext []byte) ([]byte, error) {
		ephemeral, err := ecdh.X25519().NewPublicKey(ciphertext[:32])
		if err != nil {
			panic(err)
		}

		hpke := newplex.NewProtocol("com.example.hpke")
		hpke.Mix("receiver", receiver.PublicKey().Bytes())
		hpke.Mix("ephemeral", ephemeral.Bytes())
		ss, err := receiver.ECDH(ephemeral)
		if err != nil {
			panic(err)
		}
		hpke.Mix("ecdh", ss)
		return hpke.Open("message", nil, ciphertext[32:])
	}

	receiverPrivBuf, _ := hex.DecodeString("c3a9b89b9a9a15da3c7a7e8ce9c96a828744abf52c0239f4180b0948fa3b1c74")
	receiver, _ := ecdh.X25519().NewPrivateKey(receiverPrivBuf)

	message := []byte("hello world")
	ciphertext := encrypt(receiver.PublicKey(), message)
	fmt.Printf("ciphertext = %x\n", ciphertext)

	plaintext, err := decrypt(receiver, ciphertext)
	if err != nil {
		panic(err)
	}
	fmt.Printf("plaintext  = %s\n", plaintext)

}
Output:

ciphertext = 672e904ba78b50b56f896d4b9c2f8018aecfd34038523a6faa4e82e37be4281fbf994b02f43b7d778450dc5ca8a017b07cc18b32082e9160372940
plaintext  = hello world
Example (Mac)
package main

import (
	"fmt"

	"github.com/codahale/newplex"
)

func main() {
	mac := func(key, message []byte) []byte {
		// Initialize a protocol with a domain string.
		mac := newplex.NewProtocol("com.example.mac")

		// Mix the key into the protocol.
		mac.Mix("key", key)

		// Mix the message into the protocol.
		mac.Mix("message", message)

		// Derive 16 bytes of output.
		// Note: The output length is encoded into the derivation, so changing the length will change the output.
		tag := mac.Derive("tag", nil, 16)

		return tag
	}

	key := []byte("my-secret-key")
	message := []byte("hello world")
	tag := mac(key, message)
	fmt.Printf("tag = %x\n", tag)

}
Output:

tag = 26ef9fb8d3008bba635559a8a1bde412
Example (Stream)
package main

import (
	"fmt"

	"github.com/codahale/newplex"
)

func main() {
	encrypt := func(key, nonce, plaintext []byte) []byte {
		// Initialize a protocol with a domain string.
		stream := newplex.NewProtocol("com.example.stream")

		// Mix the key and nonce into the protocol.
		stream.Mix("key", key)
		stream.Mix("nonce", nonce)

		// Encrypt the plaintext without any authenticity.
		return stream.Mask("message", nil, plaintext)
	}

	decrypt := func(key, nonce, ciphertext []byte) []byte {
		// Initialize a protocol with a domain string.
		stream := newplex.NewProtocol("com.example.stream")

		// Mix the key and nonce into the protocol.
		stream.Mix("key", key)
		stream.Mix("nonce", nonce)

		// Decrypt the ciphertext.
		return stream.Unmask("message", nil, ciphertext)
	}

	key := []byte("my-secret-key")
	nonce := []byte("actually random")
	plaintext := []byte("hello world")

	ciphertext := encrypt(key, nonce, plaintext)
	fmt.Printf("ciphertext = %x\n", ciphertext)

	plaintext = decrypt(key, nonce, ciphertext)
	fmt.Printf("plaintext  = %s\n", plaintext)

}
Output:

ciphertext = 45a0a3553319d4c0dc039e
plaintext  = hello world

func NewProtocol

func NewProtocol(domain string) *Protocol

NewProtocol creates a new Protocol with the given domain separation string.

The domain separation string should be unique to the application and specific protocol. It should not contain dynamic data like timestamps or user IDs. A good format is "application-name.protocol-name".

func (*Protocol) AppendBinary

func (p *Protocol) AppendBinary(b []byte) ([]byte, error)

AppendBinary appends the binary representation of the protocol's state to the given slice. It implements encoding.BinaryAppender.

AppendBinary panics if a streaming operation is currently active.

func (*Protocol) Clear

func (p *Protocol) Clear()

Clear erases the protocol's state

func (*Protocol) Clone

func (p *Protocol) Clone() *Protocol

Clone returns a full clone of the receiver.

Clone panics if a streaming operation is currently active.

func (*Protocol) Derive

func (p *Protocol) Derive(label string, dst []byte, n int) []byte

Derive updates the protocol's state with the given label and output length and then generates n bytes of pseudorandom output. It appends the output to dst and returns the resulting slice.

Derive panics if n is negative or if a streaming operation is currently active.

func (*Protocol) Equal

func (p *Protocol) Equal(p2 *Protocol) int

Equal returns 1 if p and p2 are equal, and 0 otherwise.

func (*Protocol) Fork

func (p *Protocol) Fork(label string, leftValue, rightValue []byte) (left, right *Protocol)

Fork returns two copies of the receiver, with the left side having absorbed the left value and the right side having absorbed the right.

func (*Protocol) ForkN

func (p *Protocol) ForkN(label string, values ...[]byte) []*Protocol

ForkN returns N copies of the receiver, with each branch having absorbed the branch-specific value. The receiver is updated with a root-specific branch ID.

Panics if the number of branches is greater than 255.

func (*Protocol) MarshalBinary

func (p *Protocol) MarshalBinary() (data []byte, err error)

MarshalBinary returns the binary representation of the protocol's state. It implements encoding.BinaryMarshaler.

MarshalBinary panics if a streaming operation is currently active.

func (*Protocol) Mask

func (p *Protocol) Mask(label string, dst, plaintext []byte) []byte

Mask updates the protocol's state with the given label, then uses the state to encrypt the given plaintext. It appends the ciphertext to dst and returns the resulting slice.

Mask provides confidentiality but not authenticity. To ensure ciphertext authenticity, use Seal instead.

Ciphertexts produced by Mask do not depend on their length, so the ciphertexts for 'A' and 'AB' will share a prefix. To prevent this, include the message length in a prior Mix operation.

To reuse plaintext's storage for the encrypted output, use plaintext[:0] as dst. Otherwise, the remaining capacity of dst must not overlap plaintext.

Mask panics if a streaming operation is currently active.

func (*Protocol) MaskStream

func (p *Protocol) MaskStream(label string) *CryptStream

MaskStream updates the protocol's state using the given label and returns a cipher.Stream which will mask any data passed to it. This can be used with cipher.StreamReader or cipher.StreamWriter to mask data during IO operations.

N.B.: The returned CryptStream must be closed for the Mask operation to be complete. While the returned CryptStream is open, any other operation on the Protocol will panic.

MaskStream panics if a streaming operation is currently active.

func (*Protocol) Mix

func (p *Protocol) Mix(label string, input []byte)

Mix updates the protocol's state using the given label and input.

Mix panics if a streaming operation is currently active.

func (*Protocol) MixReader

func (p *Protocol) MixReader(label string, r io.Reader) io.ReadCloser

MixReader updates the protocol's state using the given label and whatever data is read from the wrapped io.Reader.

N.B.: The returned io.ReadCloser must be closed for the Mix operation to be complete. While the returned io.ReadCloser is open, any other operation on the Protocol will panic.

MixReader panics if a streaming operation is currently active.

func (*Protocol) MixWriter

func (p *Protocol) MixWriter(label string, w io.Writer) *MixWriter

MixWriter updates the protocol's state using the given label and whatever data is written to the wrapped io.Writer.

N.B.: The returned io.WriteCloser must be closed for the Mix operation to be complete. While the returned io.WriteCloser is open, any other operation on the Protocol will panic.

MixWriter panics if a streaming operation is currently active.

func (*Protocol) Open

func (p *Protocol) Open(label string, dst, ciphertextAndTag []byte) ([]byte, error)

Open updates the protocol's state with the given label and plaintext length, then uses the state to decrypt the given ciphertext, verifying the final TagSize bytes as an authentication tag. If the ciphertext is authentic, it appends the plaintext to dst and returns the resulting slice. Returns ErrInvalidCiphertext if the ciphertext is not authentic.

To reuse ciphertext's storage for the decrypted output, use ciphertext[:0] as dst. Otherwise, the remaining capacity of dst must not overlap ciphertext.

WARNING: Open decrypts the ciphertext in-place before verifying the authentication tag. If the tag is invalid, the decrypted plaintext (which is now in dst) is zeroed out, but the original ciphertext is lost. To preserve the ciphertext in case of error, do not use in-place decryption (i.e., do not use ciphertext[:0] as dst).

Open panics if a streaming operation is currently active.

func (*Protocol) Ratchet

func (p *Protocol) Ratchet(label string)

Ratchet irreversibly modifies the protocol's state, preventing rollback and establishing forward secrecy.

func (*Protocol) Seal

func (p *Protocol) Seal(label string, dst, plaintext []byte) []byte

Seal updates the protocol's state with the given label and plaintext length, then uses the state to encrypt the given plaintext, appending an authentication tag of TagSize bytes. It appends the ciphertext to dst and returns the resulting slice.

To reuse plaintext's storage for the encrypted output, use plaintext[:0] as dst. Otherwise, the remaining capacity of dst must not overlap plaintext.

Seal panics if a streaming operation is currently active.

func (*Protocol) String

func (p *Protocol) String() string

String returns a safe string representation of the protocol's state for debugging purposes.

func (*Protocol) UnmarshalBinary

func (p *Protocol) UnmarshalBinary(data []byte) error

UnmarshalBinary restores the protocol's state from the given binary representation. It implements encoding.BinaryUnmarshaler.

UnmarshalBinary panics if a streaming operation is currently active.

func (*Protocol) Unmask

func (p *Protocol) Unmask(label string, dst, ciphertext []byte) []byte

Unmask updates the protocol's state with the given label, then uses the state to decrypt the given ciphertext. It appends the plaintext to dst and returns the resulting slice.

Unmask provides confidentiality but not authenticity. To ensure ciphertext authenticity, use Seal instead.

To reuse ciphertext's storage for the encrypted output, use ciphertext[:0] as dst. Otherwise, the remaining capacity of dst must not overlap ciphertext.

Unmask panics if a streaming operation is currently active.

func (*Protocol) UnmaskStream

func (p *Protocol) UnmaskStream(label string) *CryptStream

UnmaskStream updates the protocol's state using the given label and returns a cipher.Stream which will unmask any data passed to it. This can be used with cipher.StreamReader or cipher.StreamWriter to unmask data during IO operations.

N.B.: The returned CryptStream must be closed for the Unmask operation to be complete. While the returned CryptStream is open, any other operation on the Protocol will panic.

UnmaskStream panics if a streaming operation is currently active.

Directories

Path Synopsis
Package adratchet implements an asynchronous double ratchet mechanism with Newplex and Ristretto255.
Package adratchet implements an asynchronous double ratchet mechanism with Newplex and Ristretto255.
Package aead provides an implementation of Authenticated Encryption with Associated Data (AEAD) using the Newplex protocol.
Package aead provides an implementation of Authenticated Encryption with Associated Data (AEAD) using the Newplex protocol.
Package aestream provides a streaming authenticated encryption scheme on top of a newplex.Protocol.
Package aestream provides a streaming authenticated encryption scheme on top of a newplex.Protocol.
cmd
ae_proxy command
Command ae_proxy is a Newplex/Ristretto255 authenticated encryption proxy which terminates handshake/aestream connections and makes plaintext connections.
Command ae_proxy is a Newplex/Ristretto255 authenticated encryption proxy which terminates handshake/aestream connections and makes plaintext connections.
ae_reverse_proxy command
Command ae_reverse_proxy is a Newplex/Ristretto255 authenticated encryption reverse proxy which terminates plaintext connections and makes handshake/aestream connections.
Command ae_reverse_proxy is a Newplex/Ristretto255 authenticated encryption reverse proxy which terminates plaintext connections and makes handshake/aestream connections.
pt_connect command
Command pt_connect makes a plaintext connection to a server, writes stdin to the server, and reads data to stdout.
Command pt_connect makes a plaintext connection to a server, writes stdin to the server, and reads data to stdout.
pt_echo command
Command pt_echo listens for plaintext connections, reads data, and writes the same data back.
Command pt_echo listens for plaintext connections, reads data, and writes the same data back.
Package digest provides an implementation of a message digest (hash) using the Newplex protocol.
Package digest provides an implementation of a message digest (hash) using the Newplex protocol.
Package frost implements FROST (Flexible Round-Optimized Schnorr Threshold) signatures using Ristretto255 and Newplex.
Package frost implements FROST (Flexible Round-Optimized Schnorr Threshold) signatures using Ristretto255 and Newplex.
Package handshake implements a mutually-authenticated static-ephemeral handshake using Ristretto255 and Newplex.
Package handshake implements a mutually-authenticated static-ephemeral handshake using Ristretto255 and Newplex.
Package hpke implements a hybrid public key encryption (HPKE) scheme.
Package hpke implements a hybrid public key encryption (HPKE) scheme.
internal
duplex
Package duplex implements a cryptographic duplex construction using the Simpira-1024 permutation.
Package duplex implements a cryptographic duplex construction using the Simpira-1024 permutation.
simpira1024
Package simpira1024 provides an implementation of the Simpira-1024 permutation, also known as [Simpira b=8 V2].
Package simpira1024 provides an implementation of the Simpira-1024 permutation, also known as [Simpira b=8 V2].
Package mhf implements the DEGSample data-dependent memory-hard function from Blocki & Holman (2025), "Towards Practical Data-Dependent Memory-Hard Functions with Optimal Sustained Space Trade-offs." [DEGSample]: https://arxiv.org/pdf/2508.06795
Package mhf implements the DEGSample data-dependent memory-hard function from Blocki & Holman (2025), "Towards Practical Data-Dependent Memory-Hard Functions with Optimal Sustained Space Trade-offs." [DEGSample]: https://arxiv.org/pdf/2508.06795
Package oae2 provides an Online Authenticated Encryption (OAE2) stream implementation.
Package oae2 provides an Online Authenticated Encryption (OAE2) stream implementation.
Package oprf implements an [RFC 9497]-style Oblivious Pseudorandom Function scheme using Newplex and Ristretto255.
Package oprf implements an [RFC 9497]-style Oblivious Pseudorandom Function scheme using Newplex and Ristretto255.
Package pake provides a [Cpace]-style Password-Authenticated Key Exchange (PAKE), which allows two parties which share a possibly low-entropy secret (like a password) to establish a high-entropy shared protocol state for e.g.
Package pake provides a [Cpace]-style Password-Authenticated Key Exchange (PAKE), which allows two parties which share a possibly low-entropy secret (like a password) to establish a high-entropy shared protocol state for e.g.
Package sig implements an EdDSA-style Schnorr digital signature scheme using Ristretto255 and Newplex.
Package sig implements an EdDSA-style Schnorr digital signature scheme using Ristretto255 and Newplex.
Package signcrypt implements an integrated signcryption scheme using Ristretto255 and Newplex.
Package signcrypt implements an integrated signcryption scheme using Ristretto255 and Newplex.
Package siv implements a Synthetic Initialization Vector (SIV) AEAD scheme.
Package siv implements a Synthetic Initialization Vector (SIV) AEAD scheme.
Package vrf implements a verifiable random function (VRF) using Ristretto255 and Newplex.
Package vrf implements a verifiable random function (VRF) using Ristretto255 and Newplex.

Jump to

Keyboard shortcuts

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