Crypt::PK::DH(3)

✨ NAME ✨

Okay so bestie, this is Crypt::PK::DH β€” Public key cryptography based on Diffie-Hellman. Yes, the (3) is there too, iykyk. 🫢


🌈 SYNOPSIS 🌈

Here's the whole synopsis in all its code-y glory β€” every character stays exactly where it belongs, no cap:

### OO interface

#Shared secret
my $alice = Crypt::PK::DH->new();
$alice->generate_key('ike2048');
my $bob = Crypt::PK::DH->new();
$bob->generate_key($alice->params2hash);

my $alice_public = $alice->export_key('public');
my $bob_public = $bob->export_key('public');

my $alice_shared = $alice->shared_secret(Crypt::PK::DH->new(\$bob_public));
my $bob_shared = $bob->shared_secret(Crypt::PK::DH->new(\$alice_public));

#Key generation
my $pk = Crypt::PK::DH->new();
$pk->generate_key(256);
my $private = $pk->export_key('private');
my $public = $pk->export_key('public');

#or use a named IKE group

my $pk = Crypt::PK::DH->new();
$pk->generate_key('ike2048');
my $private = $pk->export_key('private');
my $public = $pk->export_key('public');

#or provide explicit parameters

my $pk = Crypt::PK::DH->new();
$pk->generate_key({ p => $p, g => $g });
my $private = $pk->export_key('private');
my $public = $pk->export_key('public');

πŸ’– DESCRIPTION πŸ’–

Provides Diffie-Hellman key agreement. Use it to generate a DH private/public key pair and to derive a shared secret from your private key and the peer's public key. That's the main character energy of this module, fr fr. πŸ’…

Parameters can come from libtomcrypt's built-in groups, the named IKE groups, an explicit { p => ..., g => ... } hash, or a PEM/DER buffer that contains DH parameters. Lowkey flexible, highkey useful. ✨

Legacy function-style wrappers still exist in code for backwards compatibility, but they are intentionally undocumented. Periodt β€” they're giving "don't ask, don't tell" but for old APIs. πŸ™ˆ


🧚 METHODS 🧚

Vibe check: these are the methods, in order, with every detail preserved. Let's get into it. πŸŽ€

🌸 new 🌸

my $pk = Crypt::PK::DH->new();
$pk->generate_key('ike2048');

my $public_blob = $pk->export_key('public');
my $pub = Crypt::PK::DH->new(\$public_blob);

Passing $filename or \$buffer to new is equivalent: both forms immediately import the key material into the new object. Same energy, different wrapper. πŸ¦‹

πŸ”₯ generate_key πŸ”₯

Uses the bundled chacha20 PRNG via libtomcrypt's rng_make_prng. Returns the object itself (for chaining). Iconic behavior, honestly.

$pk->generate_key($groupsize);
### $groupsize (in bytes) corresponds to DH parameters (p, g) predefined by libtomcrypt
# 96   =>  DH-768
# 128  =>  DH-1024
# 192  =>  DH-1536
# 256  =>  DH-2048
# 384  =>  DH-3072
# 512  =>  DH-4096
# 768  =>  DH-6144
# 1024 =>  DH-8192

The following variants are available since CryptX-0.032:

$pk->generate_key($groupname)
### $groupname selects a named IKE/MODP group from RFC 7296 and RFC 3526.
### The number suffix is the bit size of the prime (p).
# 'ike768'  =>  768-bit MODP (IKE Group 1  - RFC 2409)  -- NOT recommended
# 'ike1024' => 1024-bit MODP (IKE Group 2  - RFC 2409)  -- NOT recommended
# 'ike1536' => 1536-bit MODP (IKE Group 5  - RFC 3526)
# 'ike2048' => 2048-bit MODP (IKE Group 14 - RFC 3526)  -- minimum recommended
# 'ike3072' => 3072-bit MODP (IKE Group 15 - RFC 3526)
# 'ike4096' => 4096-bit MODP (IKE Group 16 - RFC 3526)
# 'ike6144' => 6144-bit MODP (IKE Group 17 - RFC 3526)
# 'ike8192' => 8192-bit MODP (IKE Group 18 - RFC 3526)

Those -- NOT recommended tags are not decorative, bestie. Believe them. 🚨

$pk->generate_key($param_hash)
# $param_hash is { g => $g, p => $p }
# where $g is the generator (base) in a hex string and $p is the prime in a hex string
# practical current limit: custom p/g values must fit into the current XS buffers
# (roughly up to the built-in 8192-bit group sizes)
$pk->generate_key(\$dh_param)
# $dh_param is the content of DER or PEM file with DH parameters
# e.g. openssl dhparam 2048

🌼 import_key 🌼

Loads private or public key (exported by export_key). Very "reuse the key material, slay." πŸ”‘

my $source = Crypt::PK::DH->new();
$source->generate_key('ike2048');

my $public_blob = $source->export_key('public');
my $pub = Crypt::PK::DH->new();
$pub->import_key(\$public_blob);

The same method also accepts a filename instead of \$public_blob. Convenient, no cap.

πŸ¦‹ import_key_raw πŸ¦‹

Since: CryptX-0.032

$pk->import_key_raw($raw_bytes, $type, $params)
# $raw_bytes .. [binary string] raw key data
# $type ....... [string] 'private' or 'public'
# $params ..... [string | hashref] group name (e.g. 'ike2048') or { g => $g, p => $p } with hex strings

Raw bytes in, key data out β€” the comments are doing the heavy lifting here. 🫢

πŸ’… export_key πŸ’…

BEWARE: DH key format change - since v0.049 it is compatible with libtomcrypt 1.18. Do not skip this warning, bestie. It's giving important lore. 😭

my $private = $pk->export_key('private');
#or
my $public = $pk->export_key('public');

πŸŽ€ export_key_raw πŸŽ€

Since: CryptX-0.032

Returns the raw key as a binary string. Raw bytes, no fluff. ✨

$raw_bytes = $dh->export_key_raw('public')
#or
$raw_bytes = $dh->export_key_raw('private')

✨ shared_secret ✨

Returns the shared secret as a binary string (raw bytes). This is the whole "two keys, one secret" moment. πŸ”₯

my $alice = Crypt::PK::DH->new();
$alice->generate_key('ike2048');
my $bob = Crypt::PK::DH->new();
$bob->generate_key($alice->params2hash);

my $alice_public = $alice->export_key('public');
my $bob_public = $bob->export_key('public');

my $alice_shared = $alice->shared_secret(Crypt::PK::DH->new(\$bob_public));
my $bob_shared = $bob->shared_secret(Crypt::PK::DH->new(\$alice_public));

🌸 is_private 🌸

my $rv = $pk->is_private;
# 1 .. private key loaded
# 0 .. public key loaded
# undef .. no key loaded

One, zero, or undef β€” the comments said it all. πŸ’€

πŸ“ size πŸ“

my $size = $pk->size;
# returns key size in bytes or undef if no key loaded

πŸ‘‘ key2hash πŸ‘‘

Returns a hashref with the key components, or undef if no key is loaded. Very "here's the whole vibe in one hash." 🌈

my $hash = $pk->key2hash;

# returns hash like this (or undef if no key loaded):
{
  type => 0,   # integer: 1 .. private, 0 .. public
  size => 256, # integer: key size in bytes
  x => "FBC1062F73B9A17BB8473A2F5A074911FA7F20D28FB...", #private key
  y => "AB9AAA40774D3CD476B52F82E7EE2D8A8D40CD88BF4...", #public key
  g => "2", # generator/base
  p => "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80D...", # prime
}

🧚 params2hash 🧚

Since: CryptX-0.032

my $params = $pk->params2hash;

# returns hash like this (or undef if no key loaded):
{
  g => "2", # generator/base
  p => "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80D...", # prime
}

🌈 SEE ALSO 🌈


okay bye bestie 🫢 β€” this page comes from the User Contributed Perl Documentation corner, and it's perl v5.42.0, dated 2026-05-11 πŸ’–

πŸ“¦ where this page comes from