-
Notifications
You must be signed in to change notification settings - Fork 31
/
nacl.go
112 lines (100 loc) · 3.96 KB
/
nacl.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
// 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.
package nacl
import (
"crypto/sha512"
"crypto/subtle"
"encoding/hex"
"fmt"
"github.com/kevinburke/nacl/randombytes"
)
// Key represents a private or public key for use in encryption or
// authentication. A key should be random bytes and *not* 32 characters in the
// visible ASCII set.
type Key *[32]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.
type Nonce *[24]byte
// 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".
func Load(hexkey string) (Key, error) {
keyBytes, err := hex.DecodeString(hexkey)
if err != nil {
return nil, err
}
if len(keyBytes) != 32 {
return nil, fmt.Errorf("incorrect key length: %d", len(keyBytes))
}
key := new([32]byte)
copy(key[:], keyBytes)
return key, nil
}
// 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 NewKey() Key {
key := new([32]byte)
randombytes.MustRead(key[:])
return key
}
// NewNonce returns a new Nonce with cryptographically random data. It panics if
// we could not read the correct amount of random data into nonce.
func NewNonce() Nonce {
nonce := new([24]byte)
randombytes.MustRead(nonce[:])
return nonce
}
// Verify returns true if and only if a and b have equal contents.
func Verify(a, b []byte) bool {
return subtle.ConstantTimeCompare(a, b) == 1
}
// Verify16 returns true if and only if a and b have equal contents.
func Verify16(a, b *[16]byte) bool {
if a == nil || b == nil {
panic("nacl: nil input")
}
return subtle.ConstantTimeCompare(a[:], b[:]) == 1
}
// Verify32 returns true if and only if a and b have equal contents.
func Verify32(a, b *[32]byte) bool {
if a == nil || b == nil {
panic("nacl: nil input")
}
return subtle.ConstantTimeCompare(a[:], b[:]) == 1
}
// HashSize is the size, in bytes, of the result of calling Hash.
const HashSize = sha512.Size
// 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 Hash(m []byte) *[HashSize]byte {
out := sha512.Sum512(m)
return &out
}