diff options
| author | Jared Horvat <horvski@gmail.com> | 2023-12-17 13:25:56 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-12-17 15:25:56 -0500 |
| commit | 914960f60a3c8ccb56d018b2d3fe8484ee9976d7 (patch) | |
| tree | 30369f20cb0206e2e31dd1618a230bd0cd39a614 /funcs | |
| parent | 36fb3f05006bdab3f9b96400a9043cfe7430cc1d (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.go | 49 | ||||
| -rw-r--r-- | funcs/crypto_test.go | 50 |
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() |
