github.com/choria-io/go-choria@v0.28.1-0.20240416190746-b3bf9c7d5a45/internal/util/ed25519.go (about) 1 // Copyright (c) 2022, R.I. Pienaar and the Choria Project contributors 2 // 3 // SPDX-License-Identifier: Apache-2.0 4 5 package util 6 7 import ( 8 "crypto/ed25519" 9 "crypto/rand" 10 "encoding/hex" 11 "fmt" 12 "os" 13 14 "github.com/choria-io/tokens" 15 ) 16 17 func Ed25519SignWithSeedFile(f string, msg []byte) ([]byte, error) { 18 _, pri, err := Ed25519KeyPairFromSeedFile(f) 19 if err != nil { 20 return nil, err 21 } 22 23 return Ed25519Sign(pri, msg) 24 } 25 26 func Ed25519Verify(pk ed25519.PublicKey, msg []byte, sig []byte) (bool, error) { 27 if len(pk) != ed25519.PublicKeySize { 28 return false, fmt.Errorf("invalid public key size") 29 } 30 31 return ed25519.Verify(pk, msg, sig), nil 32 } 33 34 func Ed25519Sign(pk ed25519.PrivateKey, msg []byte) ([]byte, error) { 35 if len(pk) != ed25519.PrivateKeySize { 36 return nil, fmt.Errorf("invalid private key size") 37 } 38 39 return ed25519.Sign(pk, msg), nil 40 } 41 42 func Ed25519KeyPairFromSeedFile(f string) (ed25519.PublicKey, ed25519.PrivateKey, error) { 43 ss, err := os.ReadFile(f) 44 if err != nil { 45 return nil, nil, err 46 } 47 48 seed, err := hex.DecodeString(string(ss)) 49 if err != nil { 50 return nil, nil, err 51 } 52 53 return Ed25519KeyPairFromSeed(seed) 54 } 55 56 func Ed25519KeyPairFromSeed(seed []byte) (ed25519.PublicKey, ed25519.PrivateKey, error) { 57 if len(seed) != ed25519.SeedSize { 58 return nil, nil, fmt.Errorf("invalid seed length") 59 } 60 61 priK := ed25519.NewKeyFromSeed(seed) 62 pubK := priK.Public().(ed25519.PublicKey) 63 return pubK, priK, nil 64 } 65 66 func Ed25519KeyPair() (ed25519.PublicKey, ed25519.PrivateKey, error) { 67 return ed25519.GenerateKey(rand.Reader) 68 } 69 70 func Ed25519KeyPairToFile(f string) (ed25519.PublicKey, ed25519.PrivateKey, error) { 71 pubK, priK, err := Ed25519KeyPair() 72 if err != nil { 73 return nil, nil, err 74 } 75 76 err = os.WriteFile(f, []byte(hex.EncodeToString(priK.Seed())), 0600) 77 if err != nil { 78 return nil, nil, err 79 } 80 81 return pubK, priK, nil 82 } 83 84 func IsEncodedEd25519Key(k []byte) bool { 85 return tokens.IsEncodedEd25519Key(k) 86 } 87 88 func IsEncodedEd25519KeyString(k string) bool { 89 return tokens.IsEncodedEd25519Key([]byte(k)) 90 }