NAME
Crypt::PK::Ed25519 - Digital signature based on Ed25519
SYNOPSIS
use Crypt::PK::Ed25519;my $message = 'hello world';my $signer = Crypt::PK::Ed25519->new->generate_key;my $signature = $signer->sign_message($message);my $public_der = $signer->export_key_der('public');my $verifier = Crypt::PK::Ed25519->new(\$public_der);$verifier->verify_message($signature, $message) or die "ERROR";#Load keymy $pk = Crypt::PK::Ed25519->new;my $pk_hex = "A05D1AEA5830AC9A65CDFB384660D497E3697C46B419CF2CEC85DE8BD245459D";$pk->import_key_raw(pack("H*", $pk_hex), "public");my $sk = Crypt::PK::Ed25519->new;my $sk_hex = "45C109BA6FD24E8B67D23EFB6B92D99CD457E2137172C0D749FE2B5A0C142DAD";$sk->import_key_raw(pack("H*", $sk_hex), "private");#Key generationmy $pk = Crypt::PK::Ed25519->new->generate_key;my $private_der = $pk->export_key_der('private');my $public_der = $pk->export_key_der('public');my $private_pem = $pk->export_key_pem('private');my $public_pem = $pk->export_key_pem('public');my $private_raw = $pk->export_key_raw('private');my $public_raw = $pk->export_key_raw('public');my $private_jwk = $pk->export_key_jwk('private');my $public_jwk = $pk->export_key_jwk('public');
DESCRIPTION
Since: CryptX-0.067
METHODS
new
my $source = Crypt::PK::Ed25519->new();$source->generate_key;my $public_der = $source->export_key_der('public');my $pub = Crypt::PK::Ed25519->new(\$public_der);my $private_pem = $source->export_key_pem('private', 'secret', 'AES-256-CBC');my $priv = Crypt::PK::Ed25519->new(\$private_pem, 'secret');
Passing $filename or "\$buffer" to "new" is equivalent: both forms immediately import the key material into the new object.
generate_key
Uses the bundled "chacha20" PRNG via rng_make_prng(). The exact OS entropy source is handled by the underlying LibTomCrypt RNG setup. Returns the object itself (for chaining).
$pk->generate_key;
import_key
Loads private or public key in DER or PEM format.
my $source = Crypt::PK::Ed25519->new();$source->generate_key;my $public_der = $source->export_key_der('public');my $pub = Crypt::PK::Ed25519->new();$pub->import_key(\$public_der);my $private_pem = $source->export_key_pem('private', 'secret', 'AES-256-CBC');my $priv = Crypt::PK::Ed25519->new();$priv->import_key(\$private_pem, 'secret');
The same method also accepts filenames instead of buffers.
Loading private or public keys from a Perl HASH:
$pk->import_key($hashref);# the $hashref is either a key exported via key2hash$pk->import_key({curve => "ed25519",pub => "A05D1AEA5830AC9A65CDFB384660D497E3697C46B419CF2CEC85DE8BD245459D",priv => "45C109BA6FD24E8B67D23EFB6B92D99CD457E2137172C0D749FE2B5A0C142DAD",});# or a hash with items corresponding to JWK (JSON Web Key)$pk->import_key({kty => "OKP",crv => "Ed25519",d => "RcEJum_STotn0j77a5LZnNRX4hNxcsDXSf4rWgwULa0",x => "oF0a6lgwrJplzfs4RmDUl-NpfEa0Gc8s7IXei9JFRZ0",});
Supported key formats:
# all formats can be loaded from a filemy $pk = Crypt::PK::Ed25519->new($filename);# or from a buffer containing the keymy $pk = Crypt::PK::Ed25519->new(\$buffer_with_key);
- •
-
Ed25519 private keys in PEM format
-----BEGIN ED25519 PRIVATE KEY-----MC4CAQAwBQYDK2VwBCIEIEXBCbpv0k6LZ9I++2uS2ZzUV+ITcXLA10n+K1oMFC2t-----END ED25519 PRIVATE KEY-----
- •
-
Ed25519 private keys in password protected PEM format
-----BEGIN ED25519 PRIVATE KEY-----Proc-Type: 4,ENCRYPTEDDEK-Info: DES-CBC,6A64D756D49C1EFF8xQ7OyfQ10IITNEKcJGZA53Z1yk+NJQU7hrKqXwChZtgWNInhMBJRl9pozLKDSkHv7u6EOve8NY=-----END ED25519 PRIVATE KEY-----
- •
-
PKCS#8 private keys
-----BEGIN PRIVATE KEY-----MC4CAQAwBQYDK2VwBCIEIEXBCbpv0k6LZ9I++2uS2ZzUV+ITcXLA10n+K1oMFC2t-----END PRIVATE KEY-----
- •
-
PKCS#8 encrypted private keys
-----BEGIN ENCRYPTED PRIVATE KEY-----MIGHMEsGCSqGSIb3DQEFDTA+MCkGCSqGSIb3DQEFDDAcBAjPx9JkdpRH2QICCAAwDAYIKoZIhvcNAgkFADARBgUrDgMCBwQIWWieQojaWTcEOGj43SxqHUys4Eb2M27NAkhqpmhosOxKrpGi0L3h8m8ipHE8EwI94NeOMsjfVw60aJuCrssY5vKN-----END ENCRYPTED PRIVATE KEY-----
- •
-
Ed25519 public keys in PEM format
-----BEGIN PUBLIC KEY-----MCowBQYDK2VwAyEAoF0a6lgwrJplzfs4RmDUl+NpfEa0Gc8s7IXei9JFRZ0=-----END PUBLIC KEY-----
- •
-
Ed25519 public key from X509 certificate
-----BEGIN CERTIFICATE-----MIIBODCB66ADAgECAhRWDU9FZBBUZ7KTdX8f7Bco8jsoaTAFBgMrZXAwETEPMA0GA1UEAwwGQ3J5cHRYMCAXDTIwMDExOTEzMDIwMloYDzIyOTMxMTAyMTMwMjAyWjARMQ8wDQYDVQQDDAZDcnlwdFgwKjAFBgMrZXADIQCgXRrqWDCsmmXN+zhGYNSX42l8RrQZzyzshd6L0kVFnaNTMFEwHQYDVR0OBBYEFHCGFtVibAxxWYyRt5wazMpqSZDVMB8GA1UdIwQYMBaAFHCGFtVibAxxWYyRt5wazMpqSZDVMA8GA1UdEwEB/wQFMAMBAf8wBQYDK2VwA0EAqG/+98smzqF/wmFX3zHXSaA67as202HnBJod1Tiurw1f+lr3BX6OMtsDpgRq9O77IF1Qyx/MdJEwwErczOIbAA==-----END CERTIFICATE-----
- •
-
SSH public Ed25519 keys
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL0XsiFcRDp6Hpsoak8OdiiBMJhM2UKszNTxoGS7dJ++
- •
-
SSH public Ed25519 keys (RFC-4716 format)
---- BEGIN SSH2 PUBLIC KEY ----Comment: "256-bit ED25519, converted from OpenSSH"AAAAC3NzaC1lZDI1NTE5AAAAIL0XsiFcRDp6Hpsoak8OdiiBMJhM2UKszNTxoGS7dJ++---- END SSH2 PUBLIC KEY ----
- •
-
Ed25519 private keys in JSON Web Key (JWK) format
See <https://www.rfc-editor.org/rfc/rfc8037>
{"kty":"OKP","crv":"Ed25519","x":"oF0a6lgwrJplzfs4RmDUl-NpfEa0Gc8s7IXei9JFRZ0","d":"RcEJum_STotn0j77a5LZnNRX4hNxcsDXSf4rWgwULa0",}BEWARE: For JWK support you need to have JSON module installed.
- •
-
Ed25519 public keys in JSON Web Key (JWK) format
{"kty":"OKP","crv":"Ed25519","x":"oF0a6lgwrJplzfs4RmDUl-NpfEa0Gc8s7IXei9JFRZ0",}BEWARE: For JWK support you need to have JSON module installed.
import_key_raw
Import raw public/private key - can load raw key data exported by "export_key_raw".
$pk->import_key_raw($key, 'public');$pk->import_key_raw($key, 'private');
export_key_der
Returns the key as a binary DER-encoded string.
my $private_der = $pk->export_key_der('private');#ormy $public_der = $pk->export_key_der('public');
export_key_pem
Returns the key as a PEM-encoded string (ASCII).
my $private_pem = $pk->export_key_pem('private');#ormy $public_pem = $pk->export_key_pem('public');
Support for password protected PEM keys
my $private_pem = $pk->export_key_pem('private', $password);#ormy $private_pem = $pk->export_key_pem('private', $password, $cipher);# supported ciphers: 'DES-CBC'# 'DES-EDE3-CBC'# 'SEED-CBC'# 'CAMELLIA-128-CBC'# 'CAMELLIA-192-CBC'# 'CAMELLIA-256-CBC'# 'AES-128-CBC'# 'AES-192-CBC'# 'AES-256-CBC' (DEFAULT)
export_key_jwk
Returns a JSON string, or a hashref if the optional second argument is true.
Exports public/private keys as a JSON Web Key (JWK).
my $private_json_text = $pk->export_key_jwk('private');#ormy $public_json_text = $pk->export_key_jwk('public');
Also exports public/private keys as a Perl HASH with JWK structure.
my $jwk_hash = $pk->export_key_jwk('private', 1);#ormy $jwk_hash = $pk->export_key_jwk('public', 1);
BEWARE: For JWK support you need to have JSON module installed.
export_key_raw
Returns the raw key as a binary string.
Export raw public/private key
my $private_bytes = $pk->export_key_raw('private');#ormy $public_bytes = $pk->export_key_raw('public');
sign_message
Returns the signature as a binary string. Ed25519 uses a fixed hash internally (SHA-512); unlike RSA or ECDSA there is no $hash_name parameter.
my $signature = $priv->sign_message($message);
verify_message
Returns 1 if the signature is valid, 0 otherwise.
my $valid = $pub->verify_message($signature, $message);
sign_message_ctx
Since: CryptX-0.089
Signs a message using Ed25519ctx (RFC 8032 Section 5.1), which includes a mandatory context string (at most 255 bytes). The context string makes the signature domain-separated: the same key signing the same message with a different context produces a different (and incompatible) signature.
my $signature = $priv->sign_message_ctx($message, $context);
verify_message_ctx
Since: CryptX-0.089
Verifies a signature produced by "sign_message_ctx".
my $valid = $pub->verify_message_ctx($signature, $message, $context);
sign_message_ph
Since: CryptX-0.089
Signs a message using Ed25519ph (RFC 8032 Section 5.1), the "pre-hashed" variant. The message is first hashed with SHA-512 internally before signing. This is useful when signing very large messages or when only a hash of the message is available. An optional context string (at most 255 bytes) can be provided; it defaults to the empty string if omitted.
my $signature = $priv->sign_message_ph($message);my $signature = $priv->sign_message_ph($message, $context);
verify_message_ph
Since: CryptX-0.089
Verifies a signature produced by "sign_message_ph".
my $valid = $pub->verify_message_ph($signature, $message);my $valid = $pub->verify_message_ph($signature, $message, $context);
is_private
my $rv = $pk->is_private;# 1 .. private key loaded# 0 .. public key loaded# undef .. no key loaded
key2hash
Returns a hashref with the key components, or "undef" if no key is loaded.
my $hash = $pk->key2hash;# returns hash like this (or undef if no key loaded):{curve => "ed25519",# raw public key as a hexadecimal stringpub => "A05D1AEA5830AC9A65CDFB384660D497E3697C46B419CF2CEC85DE8BD245459D",# raw private key as a hexadecimal string. undef if key is public onlypriv => "45C109BA6FD24E8B67D23EFB6B92D99CD457E2137172C0D749FE2B5A0C142DAD",}
OpenSSL interoperability
# Generate a key with OpenSSL# openssl genpkey -algorithm ed25519 -out ed25519_priv.pem# openssl pkey -in ed25519_priv.pem -pubout -out ed25519_pub.pem# Load the OpenSSL-generated key in CryptXuse Crypt::PK::Ed25519;my $priv = Crypt::PK::Ed25519->new("ed25519_priv.pem");my $pub = Crypt::PK::Ed25519->new("ed25519_pub.pem");# Sign in CryptX, verify with OpenSSLmy $message = "hello";my $signature = $priv->sign_message($message);# Export CryptX key for OpenSSLmy $pem = $priv->export_key_pem('private');# then: openssl pkey -in priv.pem -text -noout
SEE ALSO
- •
-
<https://en.wikipedia.org/wiki/EdDSA#Ed25519>
- •
-
<https://en.wikipedia.org/wiki/Curve25519>
- •
-
<https://www.rfc-editor.org/rfc/rfc8032>