Documentation
¶
Index ¶
- Constants
- func NewIV() []byte
- func RandomBytes(n int) []byte
- func RandomnessSource() io.Reader
- func SetFixedRandomness(newValue bool)
- type Chatter
- func (c *Chatter) EndSession(partnerIdentity *PublicKey) error
- func (c *Chatter) FinalizeHandshake(partnerIdentity, partnerEphemeral *PublicKey) (*SymmetricKey, error)
- func (c *Chatter) InitiateHandshake(partnerIdentity *PublicKey) (*PublicKey, error)
- func (c *Chatter) ReceiveMessage(message *Message) (string, error)
- func (c *Chatter) ReturnHandshake(partnerIdentity, partnerEphemeral *PublicKey) (*PublicKey, *SymmetricKey, error)
- func (c *Chatter) SendMessage(partnerIdentity *PublicKey, plaintext string) (*Message, error)
- type FixedRandom
- type FixedRandomReader
- type KeyPair
- type Message
- type PrivateKey
- type PublicKey
- type Session
- type SymmetricKey
- func (k *SymmetricKey) AuthenticatedDecrypt(ciphertext, additionalData, iv []byte) (string, error)
- func (k *SymmetricKey) AuthenticatedEncrypt(plaintext string, additionalData, iv []byte) []byte
- func (k *SymmetricKey) DeriveKey(label byte) *SymmetricKey
- func (k *SymmetricKey) Duplicate() *SymmetricKey
- func (k *SymmetricKey) String() string
- func (k *SymmetricKey) Zeroize()
Constants ¶
const CHAIN_LABEL = 0x02
Label for ratcheting the main chain of keys
const FINGERPRINT_LENGTH = 16 //128-bit key fingerprints
const HANDSHAKE_CHECK_LABEL byte = 0x01
Label for generating a check key from the initial root. Used for verifying the results of a handshake out-of-band.
const HASH_OUTPUT_LENGTH = 32 // SHA-256
const IV_LENGTH = 12 // 128-bit nonces
const KEY_LABEL = 0x03
Label for deriving message keys from chain keys.
const SYMMETRIC_KEY_LENGTH = 32 // 256-bit keys
Variables ¶
This section is empty.
Functions ¶
func RandomBytes ¶
RandomBytes fills a buffer with the requested number of bytes. The data is read from the system PRNG
func RandomnessSource ¶
RandomnessSource reveals the real or test randomness source
func SetFixedRandomness ¶
func SetFixedRandomness(newValue bool)
Types ¶
type Chatter ¶
Chatter represents a chat participant. Each Chatter has a single long-term key Identity, and a map of open sessions with other users (indexed by their identity keys). You should not need to modify this.
func NewChatter ¶
func NewChatter() *Chatter
NewChatter creates and initializes a new Chatter object. A long-term identity key is created and the map of sessions is initialized. You should not need to modify this code.
func (*Chatter) EndSession ¶
EndSession erases all data for a session with the designated partner. All outstanding key material should be zeroized and the session erased.
func (*Chatter) FinalizeHandshake ¶
func (c *Chatter) FinalizeHandshake(partnerIdentity, partnerEphemeral *PublicKey) (*SymmetricKey, error)
FinalizeHandshake lets the initiator receive the responder's ephemeral key and finalize the handshake. Part of this code has been provided, you will need to fill in the key derivation code. The partner which calls this method is the initiator.
func (*Chatter) InitiateHandshake ¶
InitiateHandshake prepares the first message sent in a handshake, containing an ephemeral DH share. The partner which initiates should be the first to choose a new DH ratchet value. Part of this code has been provided for you, you will need to fill in the key derivation code.
func (*Chatter) ReceiveMessage ¶
ReceiveMessage is used to receive the given message and return the correct plaintext. This method is where most of the key derivation, ratcheting and out-of-order message handling logic happens.
func (*Chatter) ReturnHandshake ¶
func (c *Chatter) ReturnHandshake(partnerIdentity, partnerEphemeral *PublicKey) (*PublicKey, *SymmetricKey, error)
ReturnHandshake prepares the first message sent in a handshake, containing an ephemeral DH share. Part of this code has been provided for you, you will need to fill in the key derivation code. The partner which calls this method is the responder.
type FixedRandom ¶
type FixedRandom struct {
// contains filtered or unexported fields
}
Simple PRNG based on SHA256 hashing from a constant intput
func (*FixedRandom) Update ¶
func (a *FixedRandom) Update()
Update updates the internal state, when necessary
type FixedRandomReader ¶
type FixedRandomReader struct {
// contains filtered or unexported fields
}
Needed to comply with reader interface
type KeyPair ¶
type KeyPair struct { PrivateKey PrivateKey PublicKey PublicKey }
KeyPair represents a public and private key pair. In this application we are only doing Diffie-Hellman exchanges. The public key is g^x and the private key is the exponent x.
func NewKeyPair ¶
func NewKeyPair() *KeyPair
NewKeyPair creates a new key pair. It panics in the case of randomness failure.
func (*KeyPair) Fingerprint ¶
Fingerprint returns the fingerprint of the underlying public key.
type Message ¶
type Message struct { Sender *PublicKey Receiver *PublicKey NextDHRatchet *PublicKey Counter int LastUpdate int Ciphertext []byte IV []byte }
Message represents a message as sent over an untrusted network. The first 5 fields are send unencrypted (but should be authenticated). The ciphertext contains the (encrypted) communication payload. You should not need to modify this.
func (*Message) EncodeAdditionalData ¶
EncodeAdditionalData encodes all of the non-ciphertext fields of a message into a single byte array, suitable for use as additional authenticated data in an AEAD scheme. You should not need to modify this code.
type PrivateKey ¶
type PrivateKey struct {
Key []byte
}
PrivateKey represents a "private key". This is simply a random buffer representing a secret exponent.
func (*PrivateKey) Zeroize ¶
func (k *PrivateKey) Zeroize()
Zeroize overwrites the buffer storing a private key with 0 bytes.
type PublicKey ¶
PrivateKey represents a public key, which is an elliptic curve point. Represented by two integers X, Y.
func (*PublicKey) Fingerprint ¶
Fingerprint returns a hash representation of a public key. This is useful for a shorter value that uniquely identifies the key, but cannot be used to recover the key itself.
type Session ¶
type Session struct { MyDHRatchet *KeyPair PartnerDHRatchet *PublicKey RootChain *SymmetricKey SendChain *SymmetricKey ReceiveChain *SymmetricKey StaleReceiveKeys map[int]*SymmetricKey SendCounter int LastUpdate int ReceiveCounter int }
Session represents an open session between one chatter and another. You should not need to modify this, though you can add additional fields if you want to.
type SymmetricKey ¶
type SymmetricKey struct {
Key []byte
}
SymmetricKey represents a symmetric key, which is simply a buffer of random bytes.
func CombineKeys ¶
func CombineKeys(keys ...*SymmetricKey) *SymmetricKey
CombineKeys takes any number of keys as input and combines them into a new key. This combined key is a hash of the input keys so does not reveal any info about them. This does not zeroize the input keys. Note that the order the keys are passed in matters.
func DHCombine ¶
func DHCombine(publicKey *PublicKey, privateKey *PrivateKey) *SymmetricKey
DHCombine performs a Diffie-Hellman exchange between a public key and a private key. For example, if the public key is g^a and the private key is b, this returns a key derived by hashing g^ab. This is immediatly converted to a SymmetricKey.
func NewSymmetricKey ¶
func NewSymmetricKey() *SymmetricKey
NewSymmetricKey creates a new random symmetric key. Note: you should not need to call this for your chat application. Every key needed will be derived from DH outputs and chains of keys.
func (*SymmetricKey) AuthenticatedDecrypt ¶
func (k *SymmetricKey) AuthenticatedDecrypt(ciphertext, additionalData, iv []byte) (string, error)
AuthenticatedDecrypt uses a key k to decrypt a given ciphertext and a buffer additionalData of data for authentication (but not encryption). If the ciphertext or additionalData have been modified, an error will be returned.
func (*SymmetricKey) AuthenticatedEncrypt ¶
func (k *SymmetricKey) AuthenticatedEncrypt(plaintext string, additionalData, iv []byte) []byte
AuthenticatedEncrypt uses a key k to encrypt a given plaintext and a buffer additionalData of data for authentication (but not encryption). Since AESGCM is a stream cipher, semantic security requires a new random IV for every encryption.
func (*SymmetricKey) DeriveKey ¶
func (k *SymmetricKey) DeriveKey(label byte) *SymmetricKey
DeriveKey evalutes a key derivation function (KDF) on a key and returns the result. The label modifiers how the KDF operates. Note that the original key is left intact and not zeroized.
func (*SymmetricKey) Duplicate ¶
func (k *SymmetricKey) Duplicate() *SymmetricKey
Duplicate produces an exact copy of a given key
func (*SymmetricKey) String ¶
func (k *SymmetricKey) String() string
String representation of a symmetric key.
func (*SymmetricKey) Zeroize ¶
func (k *SymmetricKey) Zeroize()
Zeroize overwrites the key bytes with zero bytes