nacl

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

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

Go to latest
Published: Apr 5, 2021 License: BSD-3-Clause Imports: 6 Imported by: 58

README

go-nacl

GoDoc

This is a pure Go implementation of the API's available in NaCL: https://nacl.cr.yp.to. Compared with the implementation in golang.org/x/crypto/nacl, this library offers all of the API's present in NaCL, better compatibility with NaCL implementations written in other languages, as well as some utilities for generating and loading keys and nonces, and encrypting messages.

Many of them are simple wrappers around functions or libraries available in the Go standard library, or in the golang.org/x/crypto package. Other code I copied directly into this library with the appropriate LICENSE; if a function is longer than, say, 5 lines, I didn't write it myself. There are no dependencies outside of the standard library or golang.org/x/crypto.

The goal is to both show how to implement the NaCL functions in pure Go, and to provide interoperability between messages encrypted/hashed/authenticated in other languages, and available in Go.

Among other benefits, NaCL is designed to be misuse resistant and standardizes on the use of 32 byte keys and 24 byte nonces everywhere. Several helpers are present for generating keys/nonces and loading them from configuration, as well as for encrypting messages. You can generate a key by running openssl rand -hex 32 and use the helpers in your program like so:

import "github.com/kevinburke/nacl"
import "github.com/kevinburke/nacl/secretbox"

func main() {
    key, err := nacl.Load("6368616e676520746869732070617373776f726420746f206120736563726574")
    if err != nil {
        panic(err)
    }
    encrypted := secretbox.EasySeal([]byte("hello world"), key)
    fmt.Println(base64.StdEncoding.EncodeToString(encrypted))
}

The package names match the primitives available in NaCL, with the crypto_ prefix removed. Some function names have been changed to match the Go conventions.

Installation
go get github.com/kevinburke/nacl

Or you can Git clone the code directly to $GOPATH/src/github.com/kevinburke/nacl.

Who am I?

While you probably shouldn't trust random security code from the Internet, I'm reasonably confident that this code is secure. I did not implement any of the hard math (poly1305, XSalsa20, curve25519) myself - I call into golang.org/x/crypto for all of those functions. I also ported over every test I could find from the C/C++ code, and associated RFC's, and ensured that these libraries passed those tests.

I'm a contributor to the Go Standard Library and associated tools, and I've also been paid to do security consulting for startups, and found security problems in consumer sites.

Errata
  • The implementation of crypto_sign uses the ref10 implementation of ed25519 from SUPERCOP, not the current implementation in NaCL. The difference is that the entire 64-byte signature is prepended to the message; in the current version of NaCL, separate bits are prepended and appended to the message.

  • Compared with crypto/ed25519, this library's Sign implementation returns the message along with the signature, and Verify expects the first 64 bytes of the message to be the signature. This simplifies the API and matches the behavior of the ref10 implementation and other NaCL implementations. Sign also flips the order of the message and the private key: Sign(message, privatekey), to match the NaCL implementation.

  • Compared with golang.org/x/crypto/nacl/box, Precompute returns the shared key instead of modifying the input. In several places the code was modified to call functions that now exist in nacl.

  • Compared with golang.org/x/crypto/nacl/secretbox, Seal and Open call the onetimeauth package in this library, instead of calling golang.org/x/crypto/poly1305 directly.

Documentation

Overview

Package nacl is a pure Go implementation of the NaCL cryptography library.

Compared with the implementation in golang.org/x/crypto/nacl, this library offers all of the API's present in NaCL, as well as some utilities for generating and loading keys and nonces, and encrypting messages.

NaCl's goal is to provide all of the core operations needed to build higher-level cryptographic tools, as well as to demonstrate how to implement these tools in Go.

Compared with the equivalent packages in the Go standard library and x/crypto package, we replace some function calls with their equivalents in this package, and make more use of return values (versus writing to a byte array specified at stdin). Most functions should be compatible with their C/C++ counterparts in the library here: https://nacl.cr.yp.to/. In many cases the tests are ported directly to this library.

Index

Examples

Constants

View Source
const HashSize = sha512.Size

HashSize is the size, in bytes, of the result of calling Hash.

View Source
const KeySize = 32

Size of a public or private key in bytes.

View Source
const NonceSize = 24

Size of a nonce in bytes.

View Source
const Version = "0.7"

The software version.

Variables

This section is empty.

Functions

func Hash

func Hash(m []byte) *[HashSize]byte

Hash hashes a message m.

The crypto_hash function is designed to be usable as a strong component of DSA, RSA-PSS, key derivation, hash-based message-authentication codes, hash-based ciphers, and various other common applications. "Strong" means that the security of these applications, when instantiated with crypto_hash, is the same as the security of the applications against generic attacks. In particular, the crypto_hash function is designed to make finding collisions difficult.

Hash is currently an implementation of SHA-512.

func Load64

func Load64(hexkey string) (*[64]byte, error)

Load decodes a 128-byte hex string into a Key. A hex key is suitable for representation in a configuration file. You can generate one by running nacl/sign.GenerateKey(nil).

func Verify

func Verify(a, b []byte) bool

Verify returns true if and only if a and b have equal contents. The time taken is a function of the length of the slices and is independent of the contents. If an attacker controls the length of a, they may be able to determine the length of b (and vice versa).

func Verify16

func Verify16(a, b *[16]byte) bool

Verify16 returns true if and only if a and b have equal contents, without leaking timing information.

func Verify32

func Verify32(a, b *[KeySize]byte) bool

Verify32 returns true if and only if a and b have equal contents, without leaking timing information.

Types

type Key

type Key *[KeySize]byte

Key represents a private or public key for use in encryption or authentication. A key should be random bytes and *not* simply 32 characters in the visible ASCII set.

func Load

func Load(hexkey string) (Key, error)

Load decodes a 64-byte hex string into a Key. A hex key is suitable for representation in a configuration file. You can generate one by running "openssl rand -hex 32".

Example
package main

import (
	"encoding/base64"
	"fmt"

	"github.com/kevinburke/nacl"
)

func main() {
	// Don't use this key for anything real.
	// You can generate one by running openssl rand -hex 32.
	key, err := nacl.Load("6368616e676520746869732070617373776f726420746f206120736563726574")
	if err != nil {
		panic(err)
	}
	fmt.Println(base64.StdEncoding.EncodeToString(key[:]))
}
Output:

Y2hhbmdlIHRoaXMgcGFzc3dvcmQgdG8gYSBzZWNyZXQ=

func NewKey

func NewKey() Key

NewKey returns a new Key with cryptographically random data. NewKey panics if we could not read the correct amount of random data into key.

func Setup

func Setup(nonce Nonce, key Key) (Key, *[16]byte)

Setup produces a sub-key and Salsa20 counter given a nonce and key.

type Nonce

type Nonce *[NonceSize]byte

Nonce is an arbitrary value that should be used only once per (sender, receiver) pair. For example, the lexicographically smaller public key can use nonce 1 for its first message to the other key, nonce 3 for its second message, nonce 5 for its third message, etc., while the lexicographically larger public key uses nonce 2 for its first message to the other key, nonce 4 for its second message, nonce 6 for its third message, etc. Nonces are long enough that randomly generated nonces have negligible risk of collision.

func NewNonce

func NewNonce() Nonce

NewNonce returns a new Nonce with cryptographically random data. It panics if we could not read the correct amount of random data into nonce.

Directories

Path Synopsis
Package auth authenticates a message m using a secret key k.
Package auth authenticates a message m using a secret key k.
Package box authenticates and encrypts messages using public-key cryptography.
Package box authenticates and encrypts messages using public-key cryptography.
cmd
generate-sign-keypair
generate-sign-keypair generates cryptographically secure public and private keys and prints hex encoded representations to stdout.
generate-sign-keypair generates cryptographically secure public and private keys and prints hex encoded representations to stdout.
internal
subtle
Package subtle implements functions that are often useful in cryptographic code but require careful thought to use correctly.
Package subtle implements functions that are often useful in cryptographic code but require careful thought to use correctly.
Package onetimeauth provides primitives for secret-key, single-message authentication.
Package onetimeauth provides primitives for secret-key, single-message authentication.
Package randombytes implements helpers for reading random data.
Package randombytes implements helpers for reading random data.
Package scalarmult provides an implementation of scalar multiplication.
Package scalarmult provides an implementation of scalar multiplication.
Package secretbox encrypts and authenticates small messages.
Package secretbox encrypts and authenticates small messages.
Package sign can be used to verify messages were signed with a given secret key.
Package sign can be used to verify messages were signed with a given secret key.

Jump to

Keyboard shortcuts

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