// 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) } }