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  }