dsfx/pkg/crypto/identity/ed25519.go

87 lines
2.4 KiB
Go

package identity
import (
"crypto/ed25519"
"crypto/rand"
"encoding/base64"
"fmt"
"os"
)
var (
ExportedPublicKeySize = 32
)
func LoadSigningKeyFromFile(filePath string) (ed25519.PrivateKey, error) {
keyBase64, err := os.ReadFile(filePath)
if err != nil {
return nil, err
}
// Decode the base64-encoded master key file.
keyRaw, err := base64.StdEncoding.DecodeString(string(keyBase64))
if err != nil {
return nil, fmt.Errorf("failed to decode master key file: %w", err)
}
if len(keyRaw) != ed25519.PrivateKeySize {
return nil, fmt.Errorf("invalid master key file size: %d", len(keyRaw))
}
return ed25519.PrivateKey(keyRaw), nil
}
// Generate generates a new ED25519 private key for signing.
func Generate() (ed25519.PrivateKey, error) {
_, key, err := ed25519.GenerateKey(rand.Reader)
return key, err
}
// Sign signs the data with the private key.
func Sign(priv ed25519.PrivateKey, data []byte) ([]byte, error) {
return ed25519.Sign(priv, data), nil
}
// Verify verifies the signature of the data with the public key.
func Verify(pub ed25519.PublicKey, data, signature []byte) bool {
return ed25519.Verify(pub, data, signature)
}
// ExportPrivateKey exports the private key as a byte slice.
func ExportPrivateKey(key ed25519.PrivateKey) ([]byte, error) {
return []byte(base64.StdEncoding.EncodeToString(key)), nil
}
// ExportPublicKey exports the public key as a byte slice.
func ExportPublicKey(key ed25519.PublicKey) ([]byte, error) {
encoded := []byte(base64.StdEncoding.EncodeToString(key))
return encoded, nil
}
// ImportPrivateKey imports the private key from a byte slice.
func ImportPrivateKey(keyBytes []byte) (ed25519.PrivateKey, error) {
rawKey, err := base64.StdEncoding.DecodeString(string(keyBytes))
if err != nil {
return nil, fmt.Errorf("failed to decode private key: %w", err)
}
if len(rawKey) != ed25519.PrivateKeySize {
return nil, fmt.Errorf("invalid private key size: %d", len(rawKey))
}
return ed25519.PrivateKey(rawKey), nil
}
// ImportPublicKey imports the public key from a byte slice.
func ImportPublicKey(keyBytes []byte) (ed25519.PublicKey, error) {
decoded, err := base64.StdEncoding.DecodeString(string(keyBytes))
if err != nil {
return nil, fmt.Errorf("failed to decode public key: %w", err)
}
return ed25519.PublicKey(decoded), nil
}
func ToPublicKey(key ed25519.PrivateKey) ed25519.PublicKey {
return key.Public().(ed25519.PublicKey)
}