117 lines
3.1 KiB
Go
117 lines
3.1 KiB
Go
// Package eddsa implements the EdDSA signature schemes as per RFC 8032
|
|
// https://tools.ietf.org/html/rfc8032. Note: Currently only Ed25519 is supported
|
|
package eddsa
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/beclab/Olares/cli/pkg/web5/jwk"
|
|
)
|
|
|
|
const (
|
|
JWA string = "EdDSA"
|
|
KeyType string = "OKP"
|
|
)
|
|
|
|
var algorithmIDs = map[string]bool{
|
|
ED25519AlgorithmID: true,
|
|
}
|
|
|
|
// GeneratePrivateKey generates an EdDSA private key for the given algorithm
|
|
func GeneratePrivateKey(algorithmID string) (jwk.JWK, error) {
|
|
switch algorithmID {
|
|
case ED25519AlgorithmID:
|
|
return ED25519GeneratePrivateKey()
|
|
default:
|
|
return jwk.JWK{}, fmt.Errorf("unsupported algorithm: %s", algorithmID)
|
|
}
|
|
}
|
|
|
|
// GetPublicKey builds an EdDSA public key from the given EdDSA private key
|
|
func GetPublicKey(privateKey jwk.JWK) jwk.JWK {
|
|
return jwk.JWK{
|
|
KTY: privateKey.KTY,
|
|
CRV: privateKey.CRV,
|
|
X: privateKey.X,
|
|
}
|
|
}
|
|
|
|
// Sign generates a cryptographic signature for the given payload with the given private key
|
|
//
|
|
// # Note
|
|
//
|
|
// The function will automatically detect the given EdDSA cryptographic curve from the given private key
|
|
func Sign(payload []byte, privateKey jwk.JWK) ([]byte, error) {
|
|
if privateKey.D == "" {
|
|
return nil, errors.New("d must be set")
|
|
}
|
|
|
|
switch privateKey.CRV {
|
|
case ED25519JWACurve:
|
|
return ED25519Sign(payload, privateKey)
|
|
default:
|
|
return nil, fmt.Errorf("unsupported curve: %s", privateKey.CRV)
|
|
}
|
|
}
|
|
|
|
// Verify verifies the given signature over a given payload by the given public key
|
|
//
|
|
// # Note
|
|
//
|
|
// The function will automatically detect the given EdDSA cryptographic curve from the given public key
|
|
func Verify(payload []byte, signature []byte, publicKey jwk.JWK) (bool, error) {
|
|
switch publicKey.CRV {
|
|
case ED25519JWACurve:
|
|
return ED25519Verify(payload, signature, publicKey)
|
|
default:
|
|
return false, fmt.Errorf("unsupported curve: %s", publicKey.CRV)
|
|
}
|
|
}
|
|
|
|
// GetJWA returns the [JWA] for the given EdDSA key
|
|
//
|
|
// # Note
|
|
//
|
|
// The only supported [JWA] is "EdDSA"
|
|
//
|
|
// [JWA]: https://datatracker.ietf.org/doc/html/rfc7518
|
|
func GetJWA(jwk jwk.JWK) (string, error) {
|
|
return JWA, nil
|
|
}
|
|
|
|
// BytesToPublicKey deserializes the given byte array into a jwk.JWK for the given cryptographic algorithm
|
|
func BytesToPublicKey(algorithmID string, input []byte) (jwk.JWK, error) {
|
|
switch algorithmID {
|
|
case ED25519AlgorithmID:
|
|
return ED25519BytesToPublicKey(input)
|
|
default:
|
|
return jwk.JWK{}, fmt.Errorf("unsupported algorithm: %s", algorithmID)
|
|
}
|
|
}
|
|
|
|
// PublicKeyToBytes serializes the given public key into a byte array
|
|
func PublicKeyToBytes(publicKey jwk.JWK) ([]byte, error) {
|
|
switch publicKey.CRV {
|
|
case ED25519JWACurve:
|
|
return ED25519PublicKeyToBytes(publicKey)
|
|
default:
|
|
return nil, fmt.Errorf("unsupported curve: %s", publicKey.CRV)
|
|
}
|
|
}
|
|
|
|
// SupportsAlgorithmID informs as to whether or not the given algorithm ID is supported by this package
|
|
func SupportsAlgorithmID(id string) bool {
|
|
return algorithmIDs[id]
|
|
}
|
|
|
|
// AlgorithmID returns the algorithm ID for the given jwk.JWK
|
|
func AlgorithmID(jwk *jwk.JWK) (string, error) {
|
|
switch jwk.CRV {
|
|
case ED25519JWACurve:
|
|
return ED25519AlgorithmID, nil
|
|
default:
|
|
return "", fmt.Errorf("unsupported curve: %s", jwk.CRV)
|
|
}
|
|
}
|