Files
Olares/cli/pkg/web5/crypto/dsa/eddsa/ed25519.go

83 lines
2.1 KiB
Go

package eddsa
import (
_ed25519 "crypto/ed25519"
"crypto/rand"
"encoding/base64"
"errors"
"fmt"
"github.com/beclab/Olares/cli/pkg/web5/jwk"
)
const (
ED25519JWACurve string = "Ed25519"
ED25519AlgorithmID string = ED25519JWACurve
)
// ED25519GeneratePrivateKey generates a new ED25519 private key
func ED25519GeneratePrivateKey() (jwk.JWK, error) {
publicKey, privateKey, err := _ed25519.GenerateKey(rand.Reader)
if err != nil {
return jwk.JWK{}, err
}
privKeyJwk := jwk.JWK{
KTY: KeyType,
CRV: ED25519JWACurve,
D: base64.RawURLEncoding.EncodeToString(privateKey),
X: base64.RawURLEncoding.EncodeToString(publicKey),
}
return privKeyJwk, nil
}
// ED25519Sign signs the given payload with the given private key
func ED25519Sign(payload []byte, privateKey jwk.JWK) ([]byte, error) {
privateKeyBytes, err := base64.RawURLEncoding.DecodeString(privateKey.D)
if err != nil {
return nil, fmt.Errorf("failed to decode d %w", err)
}
signature := _ed25519.Sign(privateKeyBytes, payload)
return signature, nil
}
// ED25519Verify verifies the given signature against the given payload using the given public key
func ED25519Verify(payload []byte, signature []byte, publicKey jwk.JWK) (bool, error) {
publicKeyBytes, err := base64.RawURLEncoding.DecodeString(publicKey.X)
if err != nil {
return false, err
}
legit := _ed25519.Verify(publicKeyBytes, payload, signature)
return legit, nil
}
// ED25519BytesToPublicKey deserializes the byte array into a jwk.JWK public key
func ED25519BytesToPublicKey(input []byte) (jwk.JWK, error) {
if len(input) != _ed25519.PublicKeySize {
return jwk.JWK{}, errors.New("invalid public key")
}
return jwk.JWK{
KTY: KeyType,
CRV: ED25519JWACurve,
X: base64.RawURLEncoding.EncodeToString(input),
}, nil
}
// ED25519PublicKeyToBytes serializes the given public key int a byte array
func ED25519PublicKeyToBytes(publicKey jwk.JWK) ([]byte, error) {
if publicKey.X == "" {
return nil, errors.New("x must be set")
}
publicKeyBytes, err := base64.RawURLEncoding.DecodeString(publicKey.X)
if err != nil {
return nil, fmt.Errorf("failed to decode x %w", err)
}
return publicKeyBytes, nil
}