crypto

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

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

Go to latest
Published: Jun 5, 2019 License: BSD-3-Clause Imports: 10 Imported by: 8

README

Dist-ribut-us Crypto

Wrapper around crypto functions.

GoDoc

All about the types

This package wraps the nacl/box package for key exchange and symmetric encryption, the ed25519 package for signing, sha256 for hashing and provides it's own helper for managing nonce (which relies on crypto/rand).

The primary motivation of this package is to provide types for the various cryptographic primitives. The two underlying cryptographic packages use byte slices for all the data types (keys, nonce, plain-text and cipher-text). I found it easy to confuse the arguments. Giving each primitive it's own type the compiler will help enforce that the arguments to each method are correct.

Correct Use

Communication

Identity is based on a signing key. Two parties that wish to communicate must first have a way to exchange public signing keys securely. Each party then generates a one-time-use exchange key pair (XchgPair). They each sign their public exchange key and send it to the other. Each party then validates the public key they've received against public signature. If that matches, both use their private exchange key with the validated public exchange key to get the same shared secret (note that means privA.Shared(pubB) == pirvB.Shared(pubA) ). That shared secret is a Symmetric key and it can be used to safely exchange messages.

Interrupt

A handful of functions (all related to generating cryptographic random data) can encounter a rare error of running out of entropy. This is unlikely and unrecoverable. The standard Go model of bubbling the error as a return value was not useful in these cases. The error could bubble through several layers only to have the top level panic or exit.

In place of the Go model of bubbling the error, for these functions, an interrupt is used. If crypto encounters an error when generating random data it will log the error and call InterruptHandler. This can be set to another function if main needs to do some clean up before closing. The default behavior is open a new go routine and panic (so that the panic will not interact with recover in another package up the stack) and then block any further execution on the original thread.

Functions that can trigger InterruptHandler:

  • GenerateKey
  • RandomSymmetric
  • RandomNonce
  • RandInt
  • RandUint32
  • RandUint16

Documentation

Overview

Package crypto wraps many of the standard Go crypto tools. The most significant feature is providing types that distinguish XchgPublic and XchgPrivate keys, rather than using slices or arrays of bytes directly.

Crypto also provides an Un-MAC'd variant of the tools from golang.org/x/crypto/nacl/secretbox. Trusting un-MAC'd data is never a good idea, but in the Leap Frog onion routing protocol, layers of encryption are added on to MAC'd data, providing the necesary safety.

There are a number of rare and unlikely errors that all stem from not being able to generate random cryptographic data. In this case (and only this case) we do not use the idiomatic Go technique of bubbling the error up. Generally, nothing can be done, so we panic. If you don't want to panic, the error is placed on ErrChan, along with ErrConfirm. This lets the error handler read the error but keeps blocking the crypto function until it's addressed. Only when ErrConfirm is pulled can the function return. All functions that use this feature are used to generate crypto objects (keys and nonces). They will return nil if there is an error.

tl;dr: don't use unmac'd ciphers alone, only use them on top of MAC'd data. If you don't want to worry about ErrChan, just set PanicOnError to true.

Index

Constants

View Source
const DigestLength = 32

DigestLength is the length of a SHA 256 hash digest

View Source
const ErrBadSignature = errors.String("Signature does not match the message")

ErrBadSignature is available to indicated a process failure due to a bad signature. It is not used in this package.

View Source
const ErrDecryptionFailed = errors.String("Decryption Failed")

ErrDecryptionFailed when no other information is available

View Source
const ErrIncorrectIDSize = errors.String("Incorrect ID size")

ErrIncorrectIDSize when a byte slice length does not equal IDLength

View Source
const ErrWrongDigestLength = errors.String("Wrong Digest Length")

ErrWrongDigestLength is returned when trying to create a digest from data of the wrong length

View Source
const IDLength = 10

IDLength of array

View Source
const KeyLength = 32

KeyLength of array applies to XchgPublic, XchgPrivate and Symmetric keys.

View Source
const NonceLength = 24

NonceLength of array

View Source
const Overhead = box.Overhead

Overhead copies box.Overhead

View Source
const SignPrivLength = 64

SignPrivLength is the length of a private signature key

View Source
const SignatureLength = 64

SignatureLength is the correct length of a signature

Variables

View Source
var InterruptHandler = func(err error) {
	go func() {

		panic(err)
	}()
	<-make(chan bool)
}

InterruptHandler will be called in the case of a set of very rare errors. By default, the InterruptHandler will panic. Only main should change the InterruptHandler.

Functions

func GenerateSignPair

func GenerateSignPair() (*SignPub, *SignPriv)

GenerateSignPair creates a pair of signing keys.

func RandInt

func RandInt(max int) int

RandInt returns a random int generated using crypto/rand

func RandUint16

func RandUint16() uint16

RandUint16 returns a random int generated using crypto/rand

func RandUint32

func RandUint32() uint32

RandUint32 returns a random int generated using crypto/rand

Types

type Digest

type Digest [DigestLength]byte

Digest wraps the output of a hash

func DigestFromHex

func DigestFromHex(hexStr string) (*Digest, error)

DigestFromHex returns a digest from a hex string as would be returned by a call to Hex

func DigestFromSlice

func DigestFromSlice(bs []byte) *Digest

DigestFromSlice converts a byte slice to a public key. The values are copied, so the slice can be modified after.

func DigestFromString

func DigestFromString(str string) (*Digest, error)

DigestFromString returns a digest from a hex string as would be returned by a call to String

func GetDigest

func GetDigest(bs ...[]byte) *Digest

GetDigest returns the sha256 Digest of a byte slice

func (*Digest) Equal

func (d *Digest) Equal(other *Digest) bool

Equal checks if two digests are equal

func (*Digest) Hex

func (d *Digest) Hex() string

Hex returns the hexidecimal string representation of the digest

func (*Digest) Slice

func (d *Digest) Slice() []byte

Slice return the digest as a byte slice

func (*Digest) String

func (d *Digest) String() string

String returns the base64 encoding of the digest

func (*Digest) Symmetric

func (d *Digest) Symmetric() *Symmetric

Symmetric uses a digest to create a shared key

type Hasher

type Hasher interface {
	Write(bs ...[]byte) Hasher
	Digest() *Digest
}

Hasher represents a Hash that can continue to write data

func Hash

func Hash(bs ...[]byte) Hasher

Hash returns a sha256 backed hasher, initilized by writing b to the hash.

type ID

type ID [IDLength]byte

ID is a shorthand used to make referencing public keys easier. An ID is the first 10 bytes of the sha256 of a public key. While the chances of accidental collision should be minimal, malicious collision should not be discounted. ID can be used as to make hash tables more efficient, but should not be substituted for a full key check.

func IDFromArr

func IDFromArr(id *[IDLength]byte) *ID

IDFromArr casts an array to an ID

func IDFromSlice

func IDFromSlice(b []byte) (*ID, error)

IDFromSlice returns an ID from a byte slice. The values are copied, so the slice can be modified after

func IDFromString

func IDFromString(str string) (*ID, error)

IDFromString takes a base64 encoded ID key and returns it as *ID

func (*ID) Arr

func (id *ID) Arr() *[IDLength]byte

Arr returns a reference to the array underlying the ID

func (*ID) Slice

func (id *ID) Slice() []byte

Slice casts the id to a byte slice

func (*ID) String

func (id *ID) String() string

String returns the base64 encoding of the id

type KeyRef

type KeyRef [IDLength]byte

KeyRef is similar to ID for private keys. It can be useful for managing private keys.

func KeyRefFromArr

func KeyRefFromArr(keyref *[IDLength]byte) *KeyRef

KeyRefFromArr casts an array to a KeyRef

func (*KeyRef) Arr

func (keyref *KeyRef) Arr() *[IDLength]byte

Arr returns a reference to the array underlying the KeyRef

type Nonce

type Nonce [NonceLength]byte

Nonce array

func ExtractNonce

func ExtractNonce(cipher []byte) *Nonce

ExtractNonce prefix from a cipher

func NonceFromArr

func NonceFromArr(nonce *[NonceLength]byte) *Nonce

NonceFromArr casts an array to a Nonce

func NonceFromSlice

func NonceFromSlice(nonceSlice []byte) *Nonce

NonceFromSlice casts an array to a Nonce

func NonceFromString

func NonceFromString(nonceStr string) (*Nonce, error)

NonceFromString takes a base64 encoded nonce and returns it as a Nonce

func RandomNonce

func RandomNonce() *Nonce

RandomNonce returns a Nonce with a cryptographically random value.

func (*Nonce) Arr

func (nonce *Nonce) Arr() *[NonceLength]byte

Arr returns a reference to the array underlying the Nonce

func (*Nonce) Inc

func (nonce *Nonce) Inc() *Nonce

Inc increments the Nonce

func (*Nonce) Slice

func (nonce *Nonce) Slice() []byte

Slice casts the nonce to a byte slice

func (*Nonce) String

func (nonce *Nonce) String() string

String returns the base64 encoding of the nonce

type SignPriv

type SignPriv [SignPrivLength]byte

SignPriv is a private key used to sign messages

func SignPrivFromSlice

func SignPrivFromSlice(bs []byte) *SignPriv

SignPrivFromSlice converts a byte slice to a public key. The values are copied, so the slice can be modified after.

func SignPrivFromString

func SignPrivFromString(privStr string) (*SignPriv, error)

SignPrivFromString takes a base64 encoded public key and returns it as a SignPriv

func (*SignPriv) Pub

func (priv *SignPriv) Pub() *SignPub

Pub gets the public key from a private key.

func (*SignPriv) Sign

func (priv *SignPriv) Sign(msg []byte) Signature

Sign returns a 64 byte Signature

func (*SignPriv) Slice

func (priv *SignPriv) Slice() []byte

Slice casts the public key to a byte slice

func (*SignPriv) String

func (priv *SignPriv) String() string

String returns the base64 encoding of the private key

type SignPub

type SignPub key

SignPub is a public key used to verify signatures

func SignPubFromSlice

func SignPubFromSlice(bs []byte) *SignPub

SignPubFromSlice converts a byte slice to a public key. The values are copied, so the slice can be modified after.

func SignPubFromString

func SignPubFromString(pubStr string) (*SignPub, error)

SignPubFromString takes a base64 encoded public key and returns it as a SignPub

func (*SignPub) ID

func (pub *SignPub) ID() *ID

ID returns the ID for a public key.

func (*SignPub) Slice

func (pub *SignPub) Slice() []byte

Slice casts the public key to a byte slice

func (*SignPub) String

func (pub *SignPub) String() string

String returns the base64 encoding of the public key

func (*SignPub) Verify

func (pub *SignPub) Verify(msg []byte, signature Signature) bool

Verify that a the matching private key was used to sign a message

type Signature

type Signature []byte

Signature produced from signing a message

type Symmetric

type Symmetric key

Symmetric key. Symmetric keys are also used as symmetric keys.

func RandomSymmetric

func RandomSymmetric() *Symmetric

RandomSymmetric returns a random symmetric key that can be used for symmetric ciphers

func SymmetricFromArr

func SymmetricFromArr(symmetric *[KeyLength]byte) *Symmetric

SymmetricFromArr casts an array to a symmetric key

func SymmetricFromSlice

func SymmetricFromSlice(bs []byte) *Symmetric

SymmetricFromSlice converts a byte slice to a public key. The values are copied, so the slice can be modified after.

func SymmetricFromString

func SymmetricFromString(symmetricStr string) (*Symmetric, error)

SymmetricFromString takes a base64 encoded public key and returns it as a Symmetric

func (*Symmetric) Arr

func (symmetric *Symmetric) Arr() *[KeyLength]byte

Arr returns a reference to the array underlying the symmetric key

func (*Symmetric) NonceOpen

func (symmetric *Symmetric) NonceOpen(cipher []byte, nonce *Nonce) ([]byte, error)

NonceOpen will decipher a message with a specific nonce

func (*Symmetric) NonceSeal

func (symmetric *Symmetric) NonceSeal(msg []byte, nonce *Nonce) []byte

NonceSeal will seal a message but not prepend the nonce - it matches NonceOpen. If nonce is nil, a zero value nonce will be used

func (*Symmetric) Open

func (symmetric *Symmetric) Open(cipher []byte) ([]byte, error)

Open will decipher a message ciphered with Seal.

func (*Symmetric) Seal

func (symmetric *Symmetric) Seal(msg []byte, nonce *Nonce) []byte

Seal will seal message using a symmetric key and the given nonce. If the nonce is nil, a random nonce is generated. Decyrpted with Open

func (*Symmetric) SealAll

func (symmetric *Symmetric) SealAll(msgs [][]byte, nonce *Nonce) [][]byte

SealAll seals many messages with the same shared key. If nonce is nil, a random nonce will be generated for each message.

func (*Symmetric) SealPackets

func (symmetric *Symmetric) SealPackets(tag []byte, msgs [][]byte, nonce *Nonce, trim int) [][]byte

SealPackets will seal message using a symmetric key and the given nonce. If the nonce is nil, a random nonce is generated. The tag will be prepended, but not encrypted. Trim removes tags from the start of each packet.

func (*Symmetric) Slice

func (symmetric *Symmetric) Slice() []byte

Slice casts the public key to a byte slice

func (*Symmetric) String

func (symmetric *Symmetric) String() string

String returns the base64 encoding of the symmetric key

func (*Symmetric) UnmacdOpen

func (shared *Symmetric) UnmacdOpen(cipher []byte, nonce *Nonce) []byte

UnmacdOpen decrypts a box produced by UnmacdSeal and appends the message to out, which must not overlap box. The output will be Overhead bytes smaller than box. The unsealed box has not been MAC'd and the data should not be trusted unless there is an underlying MAC (as in onion routing)

func (*Symmetric) UnmacdSeal

func (shared *Symmetric) UnmacdSeal(message []byte, nonce *Nonce) []byte

UnmacdSeal appends an encrypted copy of message to out, which must not overlap message. The key and nonce pair must be unique for each distinct message and the output will be Overhead bytes longer than message. Unlike secretbox.Seal, it does not MAC the data. It should only be use on top of a MAC'd ecnryption, as in onion routing.

type XchgPair

type XchgPair struct {
	*XchgPub
	*XchgPriv
}

XchgPair embeds XchgPub and XchgPriv

func GenerateXchgPair

func GenerateXchgPair() *XchgPair

GenerateXchgPair returns a public and private key.

func XchgPairFromSlice

func XchgPairFromSlice(bs []byte) *XchgPair

XchgPairFromSlice takes a slice and returns an XchgPair

func XchgPairFromString

func XchgPairFromString(pairStr string) (*XchgPair, error)

XchgPairFromString takes a two base64 encoded strings and returns a keypair

func (*XchgPair) Priv

func (pair *XchgPair) Priv() *XchgPriv

Priv is shorthand to get the XchgPriv

func (*XchgPair) Pub

func (pair *XchgPair) Pub() *XchgPub

Pub is shorthand to get the XchgPub

func (*XchgPair) Slice

func (pair *XchgPair) Slice() []byte

Slice casts both keypairs to slices and appends the Pub to the end of the Priv.

func (*XchgPair) String

func (pair *XchgPair) String() string

type XchgPriv

type XchgPriv key

XchgPriv key

func XchgPrivFromArr

func XchgPrivFromArr(priv *[KeyLength]byte) *XchgPriv

XchgPrivFromArr casts an array to a private key

func XchgPrivFromSlice

func XchgPrivFromSlice(bs []byte) *XchgPriv

XchgPrivFromSlice converts a byte slice to a public key. The values are copied, so the slice can be modified after.

func XchgPrivFromString

func XchgPrivFromString(privStr string) (*XchgPriv, error)

XchgPrivFromString takes a base64 encoded public key and returns it as a XchgPriv

func (*XchgPriv) AnonOpen

func (priv *XchgPriv) AnonOpen(cipher []byte) ([]byte, error)

AnonOpen decrypts a cipher from AnonSeal or AnonSealSymmetric.

func (*XchgPriv) AnonOpenSymmetric

func (priv *XchgPriv) AnonOpenSymmetric(cipher []byte) ([]byte, *Symmetric, error)

AnonOpenSymmetric decrypts a cipher from AnonSeal or AnonSealSymmetric and returns the symmetric key.

func (*XchgPriv) Arr

func (priv *XchgPriv) Arr() *[KeyLength]byte

Arr returns a reference to the array underlying the private key

func (*XchgPriv) GetKeyRef

func (priv *XchgPriv) GetKeyRef() *KeyRef

GetKeyRef returns the KeyRef for a private key

func (*XchgPriv) Shared

func (priv *XchgPriv) Shared(pub *XchgPub) *Symmetric

Shared returns a Symmetric key from a public and private key

func (*XchgPriv) Slice

func (priv *XchgPriv) Slice() []byte

Slice casts the private key to a byte slice

func (*XchgPriv) String

func (priv *XchgPriv) String() string

String returns the base64 encoding of the private key

type XchgPub

type XchgPub key

XchgPub Key

func XchgPubFromArr

func XchgPubFromArr(pub *[KeyLength]byte) *XchgPub

XchgPubFromArr casts an array to a public key

func XchgPubFromSlice

func XchgPubFromSlice(bs []byte) *XchgPub

XchgPubFromSlice converts a byte slice to a public key. The values are copied, so the slice can be modified after.

func XchgPubFromString

func XchgPubFromString(pubStr string) (*XchgPub, error)

XchgPubFromString takes a base64 encoded public key and returns it as a XchgPub

func (*XchgPub) AnonSeal

func (pub *XchgPub) AnonSeal(msg []byte) []byte

AnonSeal encrypts a message with a random key pair. The Nonce is always 0 and the public key is prepended to the cipher. The recipient can open the message but the sender remains anonymous.

func (*XchgPub) AnonSealSymmetric

func (pub *XchgPub) AnonSealSymmetric(tag, msg []byte) ([]byte, *Symmetric)

AnonSealSymmetric encrypts a message with a random key pair. The Nonce is always 0 and the public key is prepended to the cipher. The recipient can open the message but the sender remains anonymous. This method also returns the symmetric key for the message.

func (*XchgPub) Arr

func (pub *XchgPub) Arr() *[KeyLength]byte

Arr returns a reference to the array underlying the public key

func (*XchgPub) Slice

func (pub *XchgPub) Slice() []byte

Slice casts the public key to a byte slice

func (*XchgPub) String

func (pub *XchgPub) String() string

String returns the base64 encoding of the public key

func (*XchgPub) TagAnonSeal

func (pub *XchgPub) TagAnonSeal(tag, msg []byte) []byte

TagAnonSeal encrypts a message with a random key pair and prepends a byte slice tag. The Nonce is always 0 and the public key is prepended to the cipher. The recipient can open the message but the sender remains anonymous.

Jump to

Keyboard shortcuts

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