Skip to content

Commit

Permalink
Amended naming and added additional testing
Browse files Browse the repository at this point in the history
  • Loading branch information
horvski committed Nov 10, 2023
1 parent 0fdc563 commit a4e5328
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 30 deletions.
40 changes: 18 additions & 22 deletions crypto/eddsa.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,74 +9,70 @@ import (
"fmt"
)

// EDDSAGenerateKey returns a random PEM encoded Ed25519 Private Key.
func EDDSAGenerateKey() ([]byte, error) {
// Ed25519GenerateKey returns a random PEM encoded Ed25519 Private Key.
func Ed25519GenerateKey() ([]byte, error) {
_, secret, err := ed25519.GenerateKey(rand.Reader)
if err != nil {
return nil, fmt.Errorf("failed to generate EDDSA private key: %w", err)
return nil, fmt.Errorf("Ed25519GenerateKey: failed to generate EDDSA private key: %w", err)
}
return pemEncodeEdPrivateKey(secret)
}

// EDDSAGenerateKeyFromSeed returns a PEM encoded Ed25519 Private Key from given
// seed. Panics if len(seed) is not SeedSize.
func EDDSAGenerateKeyFromSeed(seed []byte) ([]byte, error) {
secret := ed25519.NewKeyFromSeed(seed) // Panics
return pemEncodeEdPrivateKey(secret)
// Ed25519GenerateKeyFromSeed returns a PEM encoded Ed25519 Private Key from
// `seed`. Panics if len(seed) is not SeedSize.
func Ed25519GenerateKeyFromSeed(seed []byte) ([]byte, error) {
return pemEncodeEdPrivateKey(ed25519.NewKeyFromSeed(seed)) // Panics
}

// EDDSADerivePublicKey returns an EDDSA Public Key from a PEM encoded EDDSA
// Private key.
func EDDSADerivePublicKey(privatekey []byte) ([]byte, error) {
secret, err := edDSADecodeFromPEM(privatekey)
// Ed25519DerivePublicKey returns an ed25519 Public Key from given PEM encoded
// `privatekey`.
func Ed25519DerivePublicKey(privatekey []byte) ([]byte, error) {
secret, err := ed25519DecodeFromPEM(privatekey)
if err != nil {
return nil, fmt.Errorf("EDDSADerivePublicKey: could not decode private key")
}
b, err := x509.MarshalPKIXPublicKey(secret.Public())
if err != nil {
return nil, fmt.Errorf("EDDSADerivePublicKey: failed to marshal PKIX public key: %w", err)
}

return pem.EncodeToMemory(&pem.Block{
Type: "PUBLIC KEY",
Bytes: b,
}), nil
}

// pemEncodeEdPrivateKey is a convenience function for PEM encoding `secret`.
func pemEncodeEdPrivateKey(secret ed25519.PrivateKey) ([]byte, error) {
der, err := x509.MarshalPKCS8PrivateKey(secret)
if err != nil {
return nil, fmt.Errorf("pemEncodeEdPrivateKey: failed to marshal ECDSA private key: %w", err)
}

block := &pem.Block{
Type: "PRIVATE KEY",
Bytes: der,
}
buf := &bytes.Buffer{}

err = pem.Encode(buf, block)
if err != nil {
return nil, fmt.Errorf("pemEncodeEdPrivateKey: failed to encode generated EDDSA private key: pem encoding failed: %w", err)
}

return buf.Bytes(), nil
}

// edDSADecodeFromPEM .
func edDSADecodeFromPEM(privatekey []byte) (ed25519.PrivateKey, error) {
// ed25519DecodeFromPEM returns an ed25519.PrivateKey from given PEM encoded
// `privatekey`.
func ed25519DecodeFromPEM(privatekey []byte) (ed25519.PrivateKey, error) {
block, _ := pem.Decode(privatekey)
if block == nil {
return nil, fmt.Errorf("edDSADecodeFromPEM: failed to read key: no key found")
return nil, fmt.Errorf("ed25519DecodeFromPEM: failed to read key: no key found")
}

priv, err := x509.ParsePKCS8PrivateKey(block.Bytes)
if err != nil {
return nil, fmt.Errorf("edDSADecodeFromPEM: invalid private key: %w", err)
return nil, fmt.Errorf("ed25519DecodeFromPEM: invalid private key: %w", err)
}
secret, ok := priv.(ed25519.PrivateKey)
if !ok {
return nil, fmt.Errorf("edDSADecodeFromPEM: invalid private key: %w", err)
return nil, fmt.Errorf("ed25519DecodeFromPEM: invalid private key: %w", err)
}
return secret, nil
}
22 changes: 14 additions & 8 deletions crypto/eddsa_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package crypto

import (
"crypto/ed25519"
"crypto/x509"
"encoding/pem"
"fmt"
Expand All @@ -11,31 +12,36 @@ import (
"github.com/stretchr/testify/require"
)

func TestEDDSAGenerateKey(t *testing.T) {
key, err := EDDSAGenerateKey()
func TestEd25519GenerateKey(t *testing.T) {
key, err := Ed25519GenerateKey()
require.NoError(t, err)
assert.True(t, strings.HasPrefix(string(key),
"-----BEGIN PRIVATE KEY-----"))
assert.True(t, strings.HasSuffix(string(key),
"-----END PRIVATE KEY-----\n"))
}

func TestEDDSADerivePublicKey(t *testing.T) {
_, err := EDDSADerivePublicKey(nil)
func TestEd25519DerivePublicKey(t *testing.T) {
_, err := Ed25519DerivePublicKey(nil)
assert.Error(t, err)
_, err = EDDSADerivePublicKey([]byte(`-----BEGIN FOO-----
_, err = Ed25519DerivePublicKey([]byte(`-----BEGIN FOO-----
-----END FOO-----`))
assert.Error(t, err)

priv, err := EDDSAGenerateKey()
priv, err := Ed25519GenerateKey()
require.NoError(t, err)
pub, err := EDDSADerivePublicKey(priv)
pub, err := Ed25519DerivePublicKey(priv)
require.NoError(t, err)
block, _ := pem.Decode(pub)
assert.True(t, block != nil)
secret, err := edDSADecodeFromPEM(priv)
secret, err := ed25519DecodeFromPEM(priv)
require.NoError(t, err)
p, err := x509.ParsePKIXPublicKey(block.Bytes)
require.NoError(t, err)
pubKey, ok := p.(ed25519.PublicKey)
assert.True(t, ok)
assert.True(t, fmt.Sprintf("%x", p) == fmt.Sprintf("%x", secret.Public()))
msg := []byte("ed25519")
sig := ed25519.Sign(secret, msg) // Panics
assert.True(t, ed25519.Verify(pubKey, msg, sig))
}

0 comments on commit a4e5328

Please sign in to comment.