summaryrefslogtreecommitdiff
path: root/funcs
diff options
context:
space:
mode:
authorJared Horvat <horvski@gmail.com>2023-12-17 13:25:56 -0700
committerGitHub <noreply@github.com>2023-12-17 15:25:56 -0500
commit914960f60a3c8ccb56d018b2d3fe8484ee9976d7 (patch)
tree30369f20cb0206e2e31dd1618a230bd0cd39a614 /funcs
parent36fb3f05006bdab3f9b96400a9043cfe7430cc1d (diff)
Add support for Ed25519 (#1900)
* Add support for Ed25519 * Amended naming and added additional testing * Added changes from Dave's review * Next review: Fixed casing on error messages for linter | Fixed version number * Added Dave's suggestions in docs and updated built docs * Final push from Dave's review | Wrap crypto example in docs in quotes
Diffstat (limited to 'funcs')
-rw-r--r--funcs/crypto.go49
-rw-r--r--funcs/crypto_test.go50
2 files changed, 99 insertions, 0 deletions
diff --git a/funcs/crypto.go b/funcs/crypto.go
index 41c752c7..e3628fad 100644
--- a/funcs/crypto.go
+++ b/funcs/crypto.go
@@ -7,8 +7,11 @@ import (
"crypto/sha1" //nolint: gosec
"crypto/sha256"
"crypto/sha512"
+ "encoding/base64"
+ "encoding/hex"
"fmt"
"strings"
+ "unicode/utf8"
"golang.org/x/crypto/bcrypt"
@@ -287,6 +290,52 @@ func (f *CryptoFuncs) ECDSADerivePublicKey(privateKey string) (string, error) {
return string(out), err
}
+// Ed25519GenerateKey -
+// Experimental!
+func (f *CryptoFuncs) Ed25519GenerateKey() (string, error) {
+ if err := checkExperimental(f.ctx); err != nil {
+ return "", err
+ }
+ out, err := crypto.Ed25519GenerateKey()
+ return string(out), err
+}
+
+// Ed25519GenerateKeyFromSeed -
+// Experimental!
+func (f *CryptoFuncs) Ed25519GenerateKeyFromSeed(encoding, seed string) (string, error) {
+ if err := checkExperimental(f.ctx); err != nil {
+ return "", err
+ }
+ if !utf8.ValidString(seed) {
+ return "", fmt.Errorf("given seed is not valid UTF-8") // Don't print out seed (private).
+ }
+ var seedB []byte
+ var err error
+ switch encoding {
+ case "base64":
+ seedB, err = base64.StdEncoding.DecodeString(seed)
+ case "hex":
+ seedB, err = hex.DecodeString(seed)
+ default:
+ return "", fmt.Errorf("invalid encoding given: %s - only 'hex' or 'base64' are valid options", encoding)
+ }
+ if err != nil {
+ return "", fmt.Errorf("could not decode given seed: %w", err)
+ }
+ out, err := crypto.Ed25519GenerateKeyFromSeed(seedB)
+ return string(out), err
+}
+
+// Ed25519DerivePublicKey -
+// Experimental!
+func (f *CryptoFuncs) Ed25519DerivePublicKey(privateKey string) (string, error) {
+ if err := checkExperimental(f.ctx); err != nil {
+ return "", err
+ }
+ out, err := crypto.Ed25519DerivePublicKey([]byte(privateKey))
+ return string(out), err
+}
+
// EncryptAES -
// Experimental!
func (f *CryptoFuncs) EncryptAES(key string, args ...interface{}) ([]byte, error) {
diff --git a/funcs/crypto_test.go b/funcs/crypto_test.go
index 90f6bdff..4d1b5660 100644
--- a/funcs/crypto_test.go
+++ b/funcs/crypto_test.go
@@ -2,6 +2,7 @@ package funcs
import (
"context"
+ "encoding/base64"
"strconv"
"strings"
"testing"
@@ -167,6 +168,55 @@ func TestECDSADerivePublicKey(t *testing.T) {
"-----END PUBLIC KEY-----\n"))
}
+func TestEd25519GenerateKey(t *testing.T) {
+ c := testCryptoNS()
+ key, err := c.Ed25519GenerateKey()
+ require.NoError(t, err)
+
+ assert.True(t, strings.HasPrefix(key,
+ "-----BEGIN PRIVATE KEY-----"))
+ assert.True(t, strings.HasSuffix(key,
+ "-----END PRIVATE KEY-----\n"))
+}
+
+func TestEd25519GenerateKeyFromSeed(t *testing.T) {
+ c := testCryptoNS()
+ enc := ""
+ seed := ""
+ _, err := c.Ed25519GenerateKeyFromSeed(enc, seed)
+ assert.Error(t, err)
+
+ enc = "base64"
+ seed = "0000000000000000000000000000000" // 31 bytes, instead of wanted 32.
+ _, err = c.Ed25519GenerateKeyFromSeed(enc, seed)
+ assert.Error(t, err)
+
+ seed += "0" // 32 bytes.
+ b64seed := base64.StdEncoding.EncodeToString([]byte(seed))
+ key, err := c.Ed25519GenerateKeyFromSeed(enc, b64seed)
+ require.NoError(t, err)
+
+ assert.True(t, strings.HasPrefix(key,
+ "-----BEGIN PRIVATE KEY-----"))
+ assert.True(t, strings.HasSuffix(key,
+ "-----END PRIVATE KEY-----\n"))
+}
+
+func TestEd25519DerivePublicKey(t *testing.T) {
+ c := testCryptoNS()
+
+ _, err := c.Ed25519DerivePublicKey("")
+ assert.Error(t, err)
+
+ key, _ := c.Ed25519GenerateKey()
+ pub, err := c.Ed25519DerivePublicKey(key)
+ require.NoError(t, err)
+ assert.True(t, strings.HasPrefix(pub,
+ "-----BEGIN PUBLIC KEY-----"))
+ assert.True(t, strings.HasSuffix(pub,
+ "-----END PUBLIC KEY-----\n"))
+}
+
func TestRSACrypt(t *testing.T) {
t.Parallel()