Documentation
¶
Overview ¶
package strobe implements the STROBE@v1.0.2 framework.
See also the specification https://strobe.sourceforge.io/specs/.
A more complex protocol might have many different meanings for the same operation. A natural pattern to ensure parseability is to precede each operation with a comment in the transcript that disambiguates it. Such information is usually provided anyway through protocol an operation called framing.
Index ¶
- Constants
- Variables
- type Flag
- type Options
- type Role
- type SecurityLevel
- type Strobe
- func (s *Strobe) AD(data []byte, opts *Options) error
- func (s *Strobe) Clone() *Strobe
- func (s *Strobe) KEY(key []byte, streaming bool) error
- func (s *Strobe) MarshalJSON() ([]byte, error)
- func (s *Strobe) PRF(dst []byte, streaming bool) error
- func (s *Strobe) RATCHET(length int, meta ...bool) error
- func (s *Strobe) RecvCLR(data []byte, opts *Options) error
- func (s *Strobe) RecvENC(ciphertext []byte, opts *Options) ([]byte, error)
- func (s *Strobe) RecvMAC(mac []byte, opts *Options) error
- func (s *Strobe) SendCLR(data []byte, opts *Options) error
- func (s *Strobe) SendENC(data []byte, opts *Options) ([]byte, error)
- func (s *Strobe) SendMAC(dst []byte, opts *Options) error
- func (s *Strobe) UnmarshalJSON(data []byte) error
Examples ¶
Constants ¶
const MagicASCII = "STROBEv1.0.2"
MagicASCII specifies a human-readable STROBE version.
Variables ¶
var ( // ErrAuthenticationFailed is the error returned by RecvMAC when MAC is invalid ErrAuthenticationFailed = errors.New("authentication failed") // ErrInvalidSecurityLevel is the error returned by New when the specified security level is // unsupported ErrInvalidSecurityLevel = errors.New("only 128 or 256 bit security is supported") )
Functions ¶
This section is empty.
Types ¶
type Flag ¶
type Flag uint8
Flag defines the behavior of each of Strobe's operations. Currently, 6 features are available. The operation is encoded as one byte, where the least significant 6 bits are its flags.
Currently, 6 flags are avaiable.
- I = 1<<0, "inbound". If set, this flag means that the operation moves data from the transport, to the cipher, to the application. An operation without the I flag set is said to be "outbound". The I flag is clear on all send operations, and set on all recv operations.
- A = 1<<1, "application". If set, this flag means that the operation has data coming to or from the application side.
- An operation with I and A both set outputs bytes to the application.
- An operation with A set but I clear takes input from the application.
- C = 1<<2, "cipher". If set, this flag means that the operation's output depends cryptographically on the Strobe cipher state. For operations which don't have I or T flags set, neither party produces output with this operation. In that case, the C flag instead means that the operation acts as a rekey or ratchet.
- T = 1<<3, "transport". If set, this flag means that the operation sends or receives data using the transport. An operation has T set if and only if it has send or recv in its name.
- An operation with I and T both set receives data from the transport.
- An operation with T set but I clear sends data to the transport.
- M = 1<<4, "meta". If set, this flag means that the operation is handling framing, transcript comments or some other sort of protocol metadata. It doesn't affect how the operation is performed.
- K = 1<<5, "keytree". This flag is reserved for a certain protocol-level countermeasure against side-channel analysis. It does affect how an operation is performed. For all operations in this STROBE specification, the K flag must be clear.
- The flags 1<<6 and 1<<7 are reserved for future versions.
type Options ¶
type Options struct {
// Meta specifies the data to operate on is meta.
Meta bool
// Streaming specifies the data will be processed in a streaming fashion, one byte at a time.
// This also means the current input data follows the previous one.
Streaming bool
}
Options define common options for different operations.
type Role ¶
type Role uint8
Role defines roles of party involved in the protocol.
const ( // Undecided is a party which has neither sent nor received any messages. Undecided Role = 0 // Initiator is party to a protocol who sent a message to the transport before receiving any // messages from the transport. Initiator Role = 1 << (iota - 1) // Responder is a party to a protocol who received a message from the transport before sending // any messages to the transport. // @note Respsonder has different value from that in the spec, // https://strobe.sourceforge.io/specs/, which is 1. Responder )
To disambiguate the two parties of a network protocol, STROBE assigns them each a role as an initiator or responder.
Parties start out as undecided, and become an initiator or responder if and when they send or receive a message via the transport.
type SecurityLevel ¶
type SecurityLevel int
SecurityLevel defines the security level of the protocol.
const ( // Bit128 targets a security level of 128 bits. Bit128 SecurityLevel = 128 // Bit256 targets a security level of 256 bits. Bit256 SecurityLevel = 256 )
type Strobe ¶
type Strobe struct {
// contains filtered or unexported fields
}
Strobe implements STROBE framework, offering a sequence of operations as
- AD: Provide associated data
- KEY: Provide cipher key
- CLR: Send or receive cleartext data
- ENC: Send or receive encrypted data
- MAC: Send or receive message authentication code
- PRF: Extract hash / pseudorandom data
- RATCHET: Prevent rollback
STROBE follows a little-endian convention.
func New ¶
func New(proto string, level SecurityLevel) (*Strobe, error)
New constructs a customized STROBE engine.
proto serves for customization, personalization, domain separation or diversification.
ONLY KeccakF1600 is supported for now
func (*Strobe) AD ¶
AD adds associated data to the state. This data must be known to both parties, and will not be transmitted. Future outputs from the Strobe object will depend on the supplied data. If opts.Meta is set, the data will be used to describes the protocol's interpretation of the following operation.
All Strobe protocols must begin with an AD operation containing a domain separation string.
Further reference sees <6.1.1. AD: Provide associated data>: https://strobe.sourceforge.io/specs/#ops.bare.ad
func (*Strobe) KEY ¶
KEY sets a symmetric key. If there is already a key, the new key will be cryptographically combined with it. This key will be used to produce all future cryptographic outputs from the STROBE object.
@dev data WILL BE MODIFIED IN PLACED.
Further reference sees <6.1.2. KEY: Provide cipher key>: https://strobe.sourceforge.io/specs/#ops.bare.key
func (*Strobe) MarshalJSON ¶
MarshalJSON marshals the instance as JSON to export.
func (*Strobe) PRF ¶
PRF extracts pseudorandom data which is a deterministic function of the state. This data can be treated as a hash of all preceeding operations, messages and keys.
Just as with a MAC, the PRF operation supports streaming, and a shorter PRF call will return a prefix of a longer one.
@dev data WILL BE MODIFIED IN PLACED.
Further reference sees <6.1.6. PRF: Extract hash / pseudorandom data>: https://strobe.sourceforge.io/specs/#ops.bare.prf
Example ¶
package main
import (
"bytes"
"fmt"
"github.com/sammyne/strobe"
)
func main() {
const (
proto = "PRF streaming demo"
securityLevel = strobe.Bit128
key = "hello-world"
)
s, err := strobe.New(proto, securityLevel)
if err != nil {
panic(fmt.Sprintf("failed to initialize encryptor: %v", err))
}
if err := s.KEY([]byte(key), false); err != nil {
panic(fmt.Sprintf("fail to KEY: %v", err))
}
s2 := s.Clone()
var prf1 [32]byte
if err := s.PRF(prf1[:], false); err != nil {
panic(fmt.Sprintf("fail to PRF: %v", err))
}
fmt.Printf("%x\n", prf1[:])
{ // first 20 bytes
var prf2 [20]byte
if err := s2.PRF(prf2[:], false); err != nil {
panic(fmt.Sprintf("fail to PRF2: %v", err))
}
fmt.Printf("%x\n", prf2[:])
if !bytes.Equal(prf1[:len(prf2)], prf2[:]) {
panic(fmt.Sprintf("invalid prefix: expect %x, got %x", prf1[:len(prf2)], prf2[:]))
}
}
{ // last 12 bytes
var prf2 [12]byte
if err := s2.PRF(prf2[:], true); err != nil {
panic(fmt.Sprintf("fail to PRF2: %v", err))
}
fmt.Printf("%x\n", prf2[:])
if !bytes.Equal(prf1[len(prf1)-len(prf2):], prf2[:]) {
panic(fmt.Sprintf("invalid prefix: expect %x, got %x", prf1[:len(prf2)], prf2[:]))
}
}
}
Output: 0b8bc840017bf7f3cd4493eae67ac4504fc7f60a15e2d9f576f1a3e947193f7e 0b8bc840017bf7f3cd4493eae67ac4504fc7f60a 15e2d9f576f1a3e947193f7e
func (*Strobe) RATCHET ¶
RATCHET has no input other than a length, and no output. Instead, it modifies the state in an irreversible way. If meta[0] is true, then length either 0 or R is suggested as a way to forcibly align to the beginning of a block, which has a few niche use cases.
RATCHET serves to prevent rollback.
Further reference sees <6.1.7. RATCHET: Prevent rollback>: https://strobe.sourceforge.io/specs/#ops.bare.ratchet
func (*Strobe) RecvCLR ¶
RecvCLR receives a message in clear text. RecvCLR don't verify the integrity of the incoming message. For this, follow SendCLR with SendMAC on the sending side, and follow RecvCLR with RecvMAC on the receiving side.
@dev data WILL BE MODIFIED IN PLACED.
Futher reference sees <6.1.3. CLR: Send or receive cleartext data>: https://strobe.sourceforge.io/specs/#ops.bare.clr
func (*Strobe) RecvENC ¶
RecvENC decrypts the ciphertext received from the transport, and return the decrypted plaintext.
RecvENC doesn't require uniqueness for security, so long as a RecvMAC operation is run before the received data is used.
The RecvENC operations don't verify the integrity of the incoming message. For this, use SendMAC after SendENC on the sending side, and RecvMAC after RecvENC on the receiving side. The receiving side must run RecvMAC before using the decrypted message.
@dev data WILL BE MODIFIED IN PLACED.
Futher reference sees <6.1.4. ENC: Send or receive encrypted data>: https://strobe.sourceforge.io/specs/#ops.bare.enc
func (*Strobe) RecvMAC ¶
RecvMAC receives and checks a MAC. If errors out, the receiving party should abort the protocol.
This is appropriate for checking the integrity of framing data.
@dev data WILL BE MODIFIED IN PLACED.
As for further warning and notes, please check section 6.1.5 of the STROBE spec: https://strobe.sourceforge.io/specs/#ops.bare.mac .
func (*Strobe) SendCLR ¶
SendCLR sends a data in clear text.
If opts.Meta is set, the data serves for framing, such as specifying message type and length before sending the actual message.
The recipient should call the RecvCLR so as to synchronize the running hash state with the sender.
@dev data WILL BE MODIFIED IN PLACED.
Futher reference sees <6.1.3. CLR: Send or receive cleartext data>: https://strobe.sourceforge.io/specs/#ops.bare.clr
func (*Strobe) SendENC ¶
SendENC encrypts the data and returns the ciphertext to send to the transport.
@dev data WILL BE MODIFIED IN PLACED.
Futher reference sees <6.1.4. ENC: Send or receive encrypted data>: https://strobe.sourceforge.io/specs/#ops.bare.enc
func (*Strobe) SendMAC ¶
SendMAC computes and sends a message authentication code (MAC).
This is appropriate for checking the integrity of framing data.
@dev data WILL BE MODIFIED IN PLACED.
As for further warning and notes, please check section 6.1.5 of the STROBE spec: https://strobe.sourceforge.io/specs/#ops.bare.mac .
func (*Strobe) UnmarshalJSON ¶
UnmarshalJSON unmarshals instance from JSON. The given data should be that has been exported by MarshalJSON.