noise

package module
v0.0.4 Latest Latest
Warning

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

Go to latest
Published: Dec 21, 2022 License: MIT Imports: 16 Imported by: 1

README

go-noise

A Go implementation for Waku Noise (35/WAKU2-NOISE, 37/WAKU2-NOISE-SESSIONS, 43/WAKU2-NOISE-PAIRING).

Documentation

Index

Constants

View Source
const ChaChaPoly = 30
View Source
const MaxUint8 = 1<<8 - 1
View Source
const MessageNametagBufferSize = 50
View Source
const MessageNametagLength = 16
View Source
const NoisePaddingBlockSize = 248

The padding blocksize of a transport message

View Source
const Noise_K1K1_25519_ChaChaPoly_SHA256 = 10

Supported Protocol ID for PayloadV2 objects Protocol IDs are defined according to https://rfc.vac.dev/spec/35/#specification

View Source
const Noise_WakuPairing_25519_ChaChaPoly_SHA256 = 14
View Source
const Noise_XK1_25519_ChaChaPoly_SHA256 = 11
View Source
const Noise_XX_25519_ChaChaPoly_SHA256 = 12
View Source
const Noise_XXpsk0_25519_ChaChaPoly_SHA256 = 13
View Source
const None = 0

Variables

View Source
var (
	ErrNametagNotFound    = errors.New("message nametag not found in buffer")
	ErrNametagNotExpected = errors.New("message nametag is present in buffer but is not the next expected nametag. One or more messages were probably lost")
)
View Source
var DH25519 = dh25519{}
View Source
var EmptyPreMessage = []PreMessagePattern{}
View Source
var ErrHandshakeComplete = errors.New("handshake complete")
View Source
var ErrUnexpectedMessageNametag = errors.New("the message nametag of the read message doesn't match the expected one")

Functions

func CommitPublicKey

func CommitPublicKey(h func() hash.Hash, publicKey []byte, r []byte) []byte

CommitPublicKey commits a public key pk for randomness r as H(pk || s)

func IsProtocolIDSupported

func IsProtocolIDSupported(protocolID byte) bool

func PKCS7_Pad

func PKCS7_Pad(payload []byte, paddingSize int) ([]byte, error)

PKCS7_Pad pads a payload according to PKCS#7 as per RFC 5652 https://datatracker.ietf.org/doc/html/rfc5652#section-6.3

func PKCS7_Unpad

func PKCS7_Unpad(payload []byte, paddingSize int) ([]byte, error)

PKCS7_Unpad unpads a payload according to PKCS#7 as per RFC 5652 https://datatracker.ietf.org/doc/html/rfc5652#section-6.3

Types

type CipherState

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

The Cipher State as in https://noiseprotocol.org/noise.html#the-cipherstate-object Contains an encryption key k and a nonce n (used in Noise as a counter)

func NewCipherState

func NewCipherState(k []byte, cipherFn func([]byte) (cipher.AEAD, error)) *CipherState

func (*CipherState) Equals

func (c *CipherState) Equals(b *CipherState) bool

type DHKey

type DHKey interface {
	GenerateKeypair() (Keypair, error)
	DH(privkey, pubkey []byte) ([]byte, error)
	DHLen() int
}

type Handshake

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

func NewHandshake

func NewHandshake(hsPattern HandshakePattern, staticKey Keypair, ephemeralKey Keypair, prologue []byte, psk []byte, preMessagePKs []*NoisePublicKey, initiator bool) (*Handshake, error)

func NewHandshake_K1K1_25519_ChaChaPoly_SHA256

func NewHandshake_K1K1_25519_ChaChaPoly_SHA256(myStaticKeypair Keypair, initiator bool, peerStaticKey []byte, prologue []byte) (*Handshake, error)

NewHandshake_K1K1_25519_ChaChaPoly_SHA256 creates a handshake where both initiator and recever know each other handshake. Only ephemeral keys are exchanged. This handshake is useful in case the initiator needs to instantiate a new separate encrypted communication channel with the responder

func NewHandshake_WakuPairing_25519_ChaChaPoly_SHA256

func NewHandshake_WakuPairing_25519_ChaChaPoly_SHA256(myStaticKeypair Keypair, myEphemeralKeypair Keypair, initiator bool, prologue []byte, receiverEphemeralKey []byte) (*Handshake, error)

NewHandshake_WakuPairing_25519_ChaChaPoly_SHA256

func NewHandshake_XK1_25519_ChaChaPoly_SHA256

func NewHandshake_XK1_25519_ChaChaPoly_SHA256(myStaticKeypair Keypair, initiator bool, responderStaticKey []byte, prologue []byte) (*Handshake, error)

NewHandshake_XK1_25519_ChaChaPoly_SHA256 creates a handshake where the initiator knows the responder public static key. Within this handshake, the initiator and responder reciprocally authenticate their static keys using ephemeral keys. We note that while the responder's static key is assumed to be known to Alice (and hence is not transmitted), The initiator static key is sent to the responder encrypted with a key derived from both parties ephemeral keys and the responder's static key.

func NewHandshake_XX_25519_ChaChaPoly_SHA256

func NewHandshake_XX_25519_ChaChaPoly_SHA256(staticKeypair Keypair, initiator bool, prologue []byte) (*Handshake, error)

NewHandshake_XX_25519_ChaChaPoly_SHA256 creates a handshake where the initiator and responder are not aware of each other static keys

func NewHandshake_XXpsk0_25519_ChaChaPoly_SHA256

func NewHandshake_XXpsk0_25519_ChaChaPoly_SHA256(staticKeypair Keypair, initiator bool, presharedKey []byte, prologue []byte) (*Handshake, error)

NewHandshake_XXpsk0_25519_ChaChaPoly_SHA256 creates a handshake where the initiator and responder are not aware of each other static keys and use a preshared secret to strengthen their mutual authentication

func (*Handshake) Authcode

func (h *Handshake) Authcode() (string, error)

Generates an 8 decimal digits authorization code using HKDF and the handshake state

func (*Handshake) Equals

func (h *Handshake) Equals(b *Handshake) bool

func (*Handshake) FinalizeHandshake

func (h *Handshake) FinalizeHandshake() (*HandshakeResult, error)

Finalizes the handshake by calling Split and assigning the proper Cipher States to users

func (*Handshake) H added in v0.0.2

func (h *Handshake) H() []byte

func (*Handshake) IsComplete

func (h *Handshake) IsComplete() bool

HandshakeComplete indicates whether the handshake process is complete or not

func (*Handshake) LocalEphemeralKeypair added in v0.0.2

func (h *Handshake) LocalEphemeralKeypair() Keypair

func (*Handshake) RemoteEphemeralPublicKey added in v0.0.2

func (h *Handshake) RemoteEphemeralPublicKey() []byte

func (*Handshake) RemoteStaticPublicKey added in v0.0.2

func (h *Handshake) RemoteStaticPublicKey() []byte

func (*Handshake) Step

func (h *Handshake) Step(readPayloadV2 *PayloadV2, transportMessage []byte, messageNametag MessageNametag) (*HandshakeStepResult, error)

Advances 1 step in handshake

Each user in a handshake alternates writing and reading of handshake messages.

If the user is writing the handshake message, the transport message (if not empty) and eventually a non-empty message nametag has to be passed to transportMessage and messageNametag and readPayloadV2 can be left to its default value It the user is reading the handshake message, the read payload v2 has to be passed to readPayloadV2 and the transportMessage can be left to its default values. Decryption is skipped if the PayloadV2 read doesn't have a message nametag equal to messageNametag (empty input nametags are converted to all-0 MessageNametagLength bytes arrays)

func (*Handshake) ToMessageNametag

func (hs *Handshake) ToMessageNametag() (MessageNametag, error)

Uses the cryptographic information stored in the input handshake state to generate a random message nametag In current implementation the messageNametag = HKDF(handshake hash value), but other derivation mechanisms can be implemented

type HandshakePattern

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

The handshake pattern object. It stores the handshake protocol name, the handshake pre message patterns and the handshake message patterns

func GetHandshakePattern

func GetHandshakePattern(protocol byte) (HandshakePattern, error)

func NewHandshakePattern

func NewHandshakePattern(protocolID byte, name string, hashFn func() hash.Hash, cipherFn func([]byte) (cipher.AEAD, error), tagSize int, dhKey DHKey, preMessagePatterns []PreMessagePattern, messagePatterns []MessagePattern) HandshakePattern

func (HandshakePattern) Equals

type HandshakeResult

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

When a handshake is complete, the HandshakeResult will contain the two Cipher States used to encrypt/decrypt outbound/inbound messages The recipient static key rs and handshake hash values h are stored to address some possible future applications (channel-binding, session management, etc.). However, are not required by Noise specifications and are thus optional

func NewHandshakeResult

func NewHandshakeResult(csOutbound *CipherState, csInbound *CipherState) *HandshakeResult

func (*HandshakeResult) ReadMessage

func (hr *HandshakeResult) ReadMessage(readPayload2 *PayloadV2, inboundMessageNametagBuffer *MessageNametagBuffer) ([]byte, error)

Reads an encrypted message using the proper Cipher State Decryption is attempted only if the input PayloadV2 has a messageNametag equal to the one expected

func (*HandshakeResult) WriteMessage

func (hr *HandshakeResult) WriteMessage(transportMessage []byte, outboundMessageNametagBuffer *MessageNametagBuffer) (*PayloadV2, error)

Writes an encrypted message using the proper Cipher State

type HandshakeState

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

The Handshake State as in https://noiseprotocol.org/noise.html#the-handshakestate-object Contains

  • the local and remote ephemeral/static keys e,s,re,rs (if any)
  • the initiator flag (true if the user creating the state is the handshake initiator, false otherwise)
  • the handshakePattern (containing the handshake protocol name, and (pre)message patterns)

This object is further extended from specifications by storing:

  • a message pattern index msgPatternIdx indicating the next handshake message pattern to process
  • the user's preshared psk, if any

func NewHandshakeState

func NewHandshakeState(hsPattern HandshakePattern, psk []byte) *HandshakeState

func (*HandshakeState) Equals

func (h *HandshakeState) Equals(b HandshakeState) bool

func (*HandshakeState) MessageNametag

func (h *HandshakeState) MessageNametag() MessageNametag

Uses the cryptographic information stored in the input handshake state to generate a random message nametag In current implementation the messageNametag = HKDF(handshake hash value), but other derivation mechanisms can be implemented

type HandshakeStepResult

type HandshakeStepResult struct {
	PayloadV2        *PayloadV2
	TransportMessage []byte
}

HandshakeStepResult stores the intermediate result of processing messages patterns

type Keypair

type Keypair struct {
	Private []byte
	Public  []byte
}

func (Keypair) Equals

func (k Keypair) Equals(b Keypair) bool

func (Keypair) IsDefault

func (k Keypair) IsDefault() bool

type MessageDirection

type MessageDirection string

The direction of a (pre)message pattern in canonical form (i.e. Alice-initiated form) as in http://www.noiseprotocol.org/noise.html#alice-and-bob

const (
	Right MessageDirection = "->"
	Left  MessageDirection = "<-"
)

type MessageNametag

type MessageNametag [MessageNametagLength]byte

func BytesToMessageNametag

func BytesToMessageNametag(input []byte) MessageNametag

Converts a sequence or array (arbitrary size) to a MessageNametag

func (MessageNametag) String

func (t MessageNametag) String() string

type MessageNametagBuffer

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

func NewMessageNametagBuffer

func NewMessageNametagBuffer(secret []byte) *MessageNametagBuffer

func (*MessageNametagBuffer) CheckNametag

func (m *MessageNametagBuffer) CheckNametag(messageNametag MessageNametag) error

Checks if the input messageNametag is contained in the input MessageNametagBuffer

func (*MessageNametagBuffer) Delete

func (m *MessageNametagBuffer) Delete(n int)

Deletes the first n elements in buffer and appends n new ones

func (*MessageNametagBuffer) Init

func (m *MessageNametagBuffer) Init()

Initializes the empty Message nametag buffer. The n-th nametag is equal to HKDF( secret || n )

func (*MessageNametagBuffer) Pop

type MessagePattern

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

The message pattern consisting of a message direction and some Noise tokens All Noise tokens are allowed

func NewMessagePattern

func NewMessagePattern(direction MessageDirection, tokens []NoiseTokens) MessagePattern

func (MessagePattern) Equals

func (p MessagePattern) Equals(b MessagePattern) bool

type NoisePublicKey

type NoisePublicKey struct {
	Flag   byte
	Public []byte
}

A Noise public key is a public key exchanged during Noise handshakes (no private part) This follows https://rfc.vac.dev/spec/35/#public-keys-serialization pk contains the X coordinate of the public key, if unencrypted (this implies flag = 0) or the encryption of the X coordinate concatenated with the authorization tag, if encrypted (this implies flag = 1) Note: besides encryption, flag can be used to distinguish among multiple supported Elliptic Curves

func NewNoisePublicKey

func NewNoisePublicKey(flag byte, public []byte) *NoisePublicKey

func (*NoisePublicKey) Decrypt

func (pk *NoisePublicKey) Decrypt(state *CipherState) error

Decrypts decrypts a Noise public key using a Cipher State

func (*NoisePublicKey) Encrypt

func (pk *NoisePublicKey) Encrypt(state *CipherState) error

Encrypt encrypts a Noise public key using a Cipher State

func (*NoisePublicKey) Equals

func (pk *NoisePublicKey) Equals(pk2 *NoisePublicKey) bool

Equals checks equality between two Noise public keys

func (*NoisePublicKey) Serialize

func (pk *NoisePublicKey) Serialize() SerializedNoisePublicKey

Serialize converts a Noise public key to a stream of bytes as in https://rfc.vac.dev/spec/35/#public-keys-serialization

type NoiseTokens

type NoiseTokens string

The Noise tokens appearing in Noise (pre)message patterns as in http://www.noiseprotocol.org/noise.html#handshake-pattern-basics

const (
	E   NoiseTokens = "e"
	S   NoiseTokens = "s"
	ES  NoiseTokens = "es"
	EE  NoiseTokens = "ee"
	SE  NoiseTokens = "se"
	SS  NoiseTokens = "ss"
	PSK NoiseTokens = "psk"
)

type PayloadV2

type PayloadV2 struct {
	ProtocolId       byte
	HandshakeMessage []*NoisePublicKey
	TransportMessage []byte
	MessageNametag   MessageNametag
}

PayloadV2 defines an object for Waku payloads with version 2 as in https://rfc.vac.dev/spec/35/#public-keys-serialization It contains a protocol ID field, the handshake message (for Noise handshakes) and a transport message (for Noise handshakes and ChaChaPoly encryptions)

func DeserializePayloadV2

func DeserializePayloadV2(payload []byte) (*PayloadV2, error)

Deserializes a byte sequence to a PayloadV2 object according to https://rfc.vac.dev/spec/35/. The input serialized payload concatenates the output PayloadV2 object fields as payload = ( protocolId || serializedHandshakeMessageLen || serializedHandshakeMessage || transportMessageLen || transportMessage)

func (*PayloadV2) Equals

func (p *PayloadV2) Equals(p2 *PayloadV2) bool

Checks equality between two PayloadsV2 objects

func (*PayloadV2) Serialize

func (p *PayloadV2) Serialize() ([]byte, error)

Serializes a PayloadV2 object to a byte sequences according to https://rfc.vac.dev/spec/35/ The output serialized payload concatenates the input PayloadV2 object fields as payload = ( protocolId || serializedHandshakeMessageLen || serializedHandshakeMessage || transportMessageLen || transportMessage) The output can be then passed to the payload field of a WakuMessage https://rfc.vac.dev/spec/14/

type PreMessagePattern

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

The pre message pattern consisting of a message direction and some Noise tokens, if any. (if non empty, only tokens e and s are allowed: http://www.noiseprotocol.org/noise.html#handshake-pattern-basics)

func NewPreMessagePattern

func NewPreMessagePattern(direction MessageDirection, tokens []NoiseTokens) PreMessagePattern

func (PreMessagePattern) Equals

type SerializedNoisePublicKey

type SerializedNoisePublicKey []byte

func (SerializedNoisePublicKey) Unserialize

func (s SerializedNoisePublicKey) Unserialize() (*NoisePublicKey, error)

Unserialize converts a serialized Noise public key to a NoisePublicKey object as in https://rfc.vac.dev/spec/35/#public-keys-serialization

type SymmetricState

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

The Symmetric State as in https://noiseprotocol.org/noise.html#the-symmetricstate-object Contains a Cipher State cs, the chaining key ck and the handshake hash value h

func NewSymmetricState

func NewSymmetricState(hsPattern HandshakePattern) *SymmetricState

func (*SymmetricState) Equals

func (s *SymmetricState) Equals(b *SymmetricState) bool

Jump to

Keyboard shortcuts

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