Documentation
¶
Overview ¶
Package lockstitch provides an incremental, stateful cryptographic primitive for symmetric-key cryptographic operations (e.g., hashing, encryption, message authentication codes, and authenticated encryption) in complex protocols. Inspired by TupleHash, STROBE, Noise Protocol's stateful objects, Merlin transcripts, and Xoodyak's Cyclist mode, Lockstitch uses SHA-256, AES-128, and GMAC to provide 10+ Gb/sec performance on modern processors at a 128-bit security level.
Index ¶
- Constants
- Variables
- type Protocol
- func (p *Protocol) AppendBinary(b []byte) ([]byte, error)
- func (p *Protocol) Clone() *Protocol
- func (p *Protocol) Decrypt(label string, dst, ciphertext []byte) []byte
- func (p *Protocol) Derive(label string, dst []byte, n int) []byte
- func (p *Protocol) Encrypt(label string, dst, plaintext []byte) []byte
- func (p *Protocol) MarshalBinary() (data []byte, err error)
- func (p *Protocol) Mix(label string, input []byte)
- func (p *Protocol) Open(label string, dst, ciphertext []byte) ([]byte, error)
- func (p *Protocol) Seal(label string, dst, plaintext []byte) []byte
- func (p *Protocol) UnmarshalBinary(data []byte) error
Examples ¶
Constants ¶
const ( // TagSize is the number of bytes added to the plaintext by the Seal operation. TagSize = 16 // MaxDeriveSize is the maximum number of bytes which can be produced by a single Protocol.Derive operation. MaxDeriveSize = 64 * 1024 * 1024 * 1024 // 64 GiB )
Variables ¶
var ErrInvalidCiphertext = errors.New("lockstitch: 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 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, pseudo-random functions, authenticated encryption, and more.
Protocol instances are not concurrent-safe.
Example (Aead) ¶
var ciphertext []byte
{
// Initialize a protocol with a domain string.
aead := lockstitch.NewProtocol("com.example.aead")
// Mix the key into the protocol.
key := []byte("my-secret-key")
aead.Mix("key", key)
// Mix the authenticated data into the protocol.
ad := []byte("some authenticated data")
aead.Mix("ad", ad)
// Seal the plaintext.
plaintext := []byte("hello world")
ciphertext = aead.Seal("message", nil, plaintext)
fmt.Printf("%x\n", ciphertext)
}
{
// Initialize a protocol with a domain string.
aead := lockstitch.NewProtocol("com.example.aead")
// Mix the key into the protocol.
key := []byte("my-secret-key")
aead.Mix("key", key)
// Mix the authenticated data into the protocol.
ad := []byte("some authenticated data")
aead.Mix("ad", ad)
// Open the ciphertext.
plaintext, err := aead.Open("message", nil, ciphertext)
if err != nil {
panic(err)
}
fmt.Printf("%s\n", plaintext)
}
Output: fd58696cf39e4f44138a22a6ebaa374b6fe00fe0bce5f59e501d70 hello world
Example (Mac) ¶
// Initialize a protocol with a domain string.
mac := lockstitch.NewProtocol("com.example.mac")
// Mix the key into the protocol.
key := []byte("my-secret-key")
mac.Mix("key", key)
// Mix the message into the protocol.
message := []byte("hello world")
mac.Mix("message", message)
// Derive 16 bytes of output.
// Note: The output length (128 bits) is encoded into the derivation, so
// changing the length will change the output.
tag := mac.Derive("tag", nil, 16)
fmt.Printf("%x\n", tag)
Output: 8072172e62079021ab8cdb8834071584
Example (Stream) ¶
var ciphertext, nonce []byte
{
// Initialize a protocol with a domain string.
stream := lockstitch.NewProtocol("com.example.stream")
// Mix the key into the protocol.
key := []byte("my-secret-key")
stream.Mix("key", key)
// Mix a nonce into the protocol.
nonce = []byte("actually random")
stream.Mix("nonce", nonce)
// Encrypt the plaintext.
plaintext := []byte("hello world")
ciphertext = stream.Encrypt("message", nil, plaintext)
fmt.Printf("%x\n", ciphertext)
}
{
// Initialize a protocol with a domain string.
stream := lockstitch.NewProtocol("com.example.stream")
// Mix the key into the protocol.
key := []byte("my-secret-key")
stream.Mix("key", key)
// Mix a nonce into the protocol.
nonce = []byte("actually random")
stream.Mix("nonce", nonce)
// Decrypt the ciphertext.
plaintext := stream.Decrypt("message", nil, ciphertext)
fmt.Printf("%s\n", plaintext)
}
Output: 342bcef28cbd46ac1b3cbc hello world
func NewProtocol ¶
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) Clone ¶
Clone returns an exact, deep copy of the receiver Protocol. The cloned protocol shares no state with the original.
func (*Protocol) Decrypt ¶
Decrypt decrypts the given ciphertext using the protocol's current state as the key, then ratchets the protocol's state using the label and input. It appends the plaintext to dst and returns the resulting slice.
Decrypt provides confidentiality but not authenticity. If you need to ensure the ciphertext hasn't been modified, use Open instead.
To reuse ciphertext's storage for the decrypted output, use ciphertext[:0] as dst. Otherwise, the remaining capacity of dst must not overlap ciphertext.
func (*Protocol) Derive ¶
Derive generates pseudorandom output from the Protocol's current state, the label, and the output length, then ratchets the Protocol's state with the label and output length. It appends the output to dst and returns the resulting slice.
Derive panics if n is negative or greater than MaxDeriveSize to strictly avoid birthday-bound attacks.
func (*Protocol) Encrypt ¶
Encrypt encrypts the plaintext using the protocol's current state as the key, then ratchets the protocol's state using the label and input. It appends the ciphertext to dst and returns the resulting slice.
Encrypt provides confidentiality but not authenticity. If you need to ensure the ciphertext hasn't been modified, use Seal instead.
To reuse plaintext's storage for the encrypted output, use plaintext[:0] as dst. Otherwise, the remaining capacity of dst must not overlap plaintext.
func (*Protocol) MarshalBinary ¶
func (*Protocol) Open ¶
Open decrypts the given slice in place using the protocol's current state as the key, 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; otherwise, ErrInvalidCiphertext is returned.
To reuse ciphertext's storage for the decrypted output, use ciphertext[:0] as dst. Otherwise, the remaining capacity of dst must not overlap ciphertext.
func (*Protocol) Seal ¶
Seal encrypts the given plaintext using the protocol's current state as the key, appending an authentication tag of TagSize bytes, then ratchets the protocol's state using the label and input. It appends the ciphertext and authentication tag 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.
func (*Protocol) UnmarshalBinary ¶
Directories
¶
| Path | Synopsis |
|---|---|
|
internal
|
|
|
aes
Package aes provides concise implementations of AES-CTR for confidentiality and AES-GMAC for authenticity.
|
Package aes provides concise implementations of AES-CTR for confidentiality and AES-GMAC for authenticity. |
|
tuplehash
Package tuplehash implements various routines from [NIST SP 800-185].
|
Package tuplehash implements various routines from [NIST SP 800-185]. |