Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add crypto GenerateEntropy() and GenerateHexNonce() #57

Merged
merged 7 commits into from
Feb 21, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add EntropySize per PR suggestion, add additional test cases, add rel…
…evant doc comment
KendallWeihe committed Feb 21, 2024
commit e0132856faff42493e860ca25e3525f3c65f399e
20 changes: 15 additions & 5 deletions crypto/entropy.go
Original file line number Diff line number Diff line change
@@ -6,7 +6,19 @@ import (
"errors"
)

func GenerateEntropy(n int) ([]byte, error) {
type EntropySize int

const (
// Directly set the sizes according to NIST recommendations for entropy
// defined here: https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf
Entropy112 EntropySize = 112 / 8 // 14 bytes
Entropy128 EntropySize = 128 / 8 // 16 bytes
Entropy192 EntropySize = 192 / 8 // 24 bytes
Entropy256 EntropySize = 256 / 8 // 32 bytes
)

// GenerateEntropy generates a random byte array of size n bytes
func GenerateEntropy(n EntropySize) ([]byte, error) {
if n <= 0 {
return nil, errors.New("entropy byte size must be > 0")
}
@@ -21,10 +33,8 @@ func GenerateEntropy(n int) ([]byte, error) {
}

// GenerateNonce generates a hex-encoded nonce by calling GenerateEntropy with a size of 16 bytes (128 bits)
func GenerateNonce() (string, error) {
// 16 bytes was chosen because 16 bytes = 128 bits which is considered minimally sufficient
// https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf
bytes, err := GenerateEntropy(16)
func GenerateNonce(n EntropySize) (string, error) {
bytes, err := GenerateEntropy(n)
if err != nil {
return "", err
}
32 changes: 27 additions & 5 deletions crypto/entropy_test.go
Original file line number Diff line number Diff line change
@@ -9,10 +9,16 @@ import (
)

func Test_GenerateEntropy(t *testing.T) {
size := 16
bytes, err := crypto.GenerateEntropy(size)
bytes, err := crypto.GenerateEntropy(crypto.Entropy128)
assert.NoError(t, err)
assert.Equal(t, size, len(bytes))
assert.Equal(t, int(crypto.Entropy128), len(bytes))
}

func Test_GenerateEntropy_CustomeSize(t *testing.T) {
KendallWeihe marked this conversation as resolved.
Show resolved Hide resolved
customSize := 99
bytes, err := crypto.GenerateEntropy(crypto.EntropySize(customSize))
assert.NoError(t, err)
assert.Equal(t, customSize, len(bytes))
}

func Test_GenerateEntropy_InvalidSize(t *testing.T) {
@@ -26,10 +32,26 @@ func Test_GenerateEntropy_InvalidSize(t *testing.T) {
}

func Test_GenerateNonce(t *testing.T) {
nonce, err := crypto.GenerateNonce()
nonce, err := crypto.GenerateNonce(crypto.Entropy128)
assert.NoError(t, err)
assert.Equal(t, int(crypto.Entropy128)*2, len(nonce))

_, err = hex.DecodeString(nonce)
assert.NoError(t, err)
assert.Equal(t, 32, len(nonce))
}

func Test_GenerateNonce_CustomSize(t *testing.T) {
customSize := 99
nonce, err := crypto.GenerateNonce(crypto.EntropySize(99))
assert.NoError(t, err)
assert.Equal(t, customSize*2, len(nonce))

_, err = hex.DecodeString(nonce)
assert.NoError(t, err)
}

func Test_GenerateNonce_InvalidSize(t *testing.T) {
nonce, err := crypto.GenerateNonce(0)
assert.Error(t, err)
assert.Equal(t, "", nonce)
}