The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Crypt::PK::DH - Public key cryptography based on Diffie-Hellman

SYNOPSIS

 ### OO interface

 #Encryption: Alice
 my $pub = Crypt::PK::DH->new('Bob_pub_dh1.key');
 my $ct = $pub->encrypt("secret message");
 #
 #Encryption: Bob (received ciphertext $ct)
 my $priv = Crypt::PK::DH->new('Bob_priv_dh1.key');
 my $pt = $priv->decrypt($ct);

 #Signature: Alice
 my $priv = Crypt::PK::DH->new('Alice_priv_dh1.key');
 my $sig = $priv->sign_message($message);
 #
 #Signature: Bob (received $message + $sig)
 my $pub = Crypt::PK::DH->new('Alice_pub_dh1.key');
 $pub->verify_message($sig, $message) or die "ERROR";

 #Shared secret
 my $priv = Crypt::PK::DH->new('Alice_priv_dh1.key');
 my $pub = Crypt::PK::DH->new('Bob_pub_dh1.key');
 my $shared_secret = $priv->shared_secret($pub);

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

 or

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

 or

 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');

 ### Functional interface

 #Encryption: Alice
 my $ct = dh_encrypt('Bob_pub_dh1.key', "secret message");
 #Encryption: Bob (received ciphertext $ct)
 my $pt = dh_decrypt('Bob_priv_dh1.key', $ct);

 #Signature: Alice
 my $sig = dh_sign_message('Alice_priv_dh1.key', $message);
 #Signature: Bob (received $message + $sig)
 dh_verify_message('Alice_pub_dh1.key', $sig, $message) or die "ERROR";

 #Shared secret
 my $shared_secret = dh_shared_secret('Alice_priv_dh1.key', 'Bob_pub_dh1.key');

METHODS

new

  my $pk = Crypt::PK::DH->new();
  #or
  my $pk = Crypt::PK::DH->new($priv_or_pub_key_filename);
  #or
  my $pk = Crypt::PK::DH->new(\$buffer_containing_priv_or_pub_key);

generate_key

Uses Yarrow-based cryptographically strong random number generator seeded with random data taken from /dev/random (UNIX) or CryptGenRandom (Win32).

 $pk->generate_key($keysize);
 ### $keysize (in bytes) corresponds to DH params (p, g) predefined by libtomcrypt
 # 96   =>  DH-768
 # 128  =>  DH-1024
 # 160  =>  DH-1280
 # 192  =>  DH-1536
 # 224  =>  DH-1792
 # 256  =>  DH-2048
 # 320  =>  DH-2560
 # 384  =>  DH-3072
 # 512  =>  DH-4096

The following variants are available since CryptX-0.032

 $pk->generate_key($name)
 ### $name corresponds to values defined in RFC7296 and RFC3526
 # ike768  =>  768-bit MODP (Group 1)
 # ike1024 => 1024-bit MODP (Group 2)
 # ike1536 => 1536-bit MODP (Group 5)
 # ike2048 => 2048-bit MODP (Group 14)
 # ike3072 => 3072-bit MODP (Group 15)
 # ike4096 => 4096-bit MODP (Group 16)
 # ike6144 => 6144-bit MODP (Group 17)
 # ike8192 => 8192-bit MODP (Group 18)

 $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

import_key

Loads private or public key (exported by "export_key").

  $pk->import_key($filename);
  #or
  $pk->import_key(\$buffer_containing_key);

import_key_raw

Since: CryptX-0.032

  $pk->import_key_raw($raw_bytes, $type, $params)
  ### $raw_bytes is a binary string containing the key
  ### $type is either 'private' or 'public'
  ### $param is either a name ('ike2038') or hash containing the p,g values { g=>$g, p=>$p }
  ### in hex strings

export_key

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

export_key_raw

Since: CryptX-0.032

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

encrypt

 my $pk = Crypt::PK::DH->new($pub_key_filename);
 my $ct = $pk->encrypt($message);
 #or
 my $ct = $pk->encrypt($message, $hash_name);

 #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest

decrypt

 my $pk = Crypt::PK::DH->new($priv_key_filename);
 my $pt = $pk->decrypt($ciphertext);

sign_message

 my $pk = Crypt::PK::DH->new($priv_key_filename);
 my $signature = $priv->sign_message($message);
 #or
 my $signature = $priv->sign_message($message, $hash_name);

 #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest

verify_message

 my $pk = Crypt::PK::DH->new($pub_key_filename);
 my $valid = $pub->verify_message($signature, $message)
 #or
 my $valid = $pub->verify_message($signature, $message, $hash_name);

 #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest

sign_hash

 my $pk = Crypt::PK::DH->new($priv_key_filename);
 my $signature = $priv->sign_hash($message_hash);

verify_hash

 my $pk = Crypt::PK::DH->new($pub_key_filename);
 my $valid = $pub->verify_hash($signature, $message_hash);

shared_secret

 # Alice having her priv key $pk and Bob's public key $pkb
 my $pk  = Crypt::PK::DH->new($priv_key_filename);
 my $pkb = Crypt::PK::DH->new($pub_key_filename);
 my $shared_secret = $pk->shared_secret($pkb);

 # Bob having his priv key $pk and Alice's public key $pka
 my $pk = Crypt::PK::DH->new($priv_key_filename);
 my $pka = Crypt::PK::DH->new($pub_key_filename);
 my $shared_secret = $pk->shared_secret($pka);  # same value as computed by Alice

is_private

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

size

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

key2hash

 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
}

FUNCTIONS

dh_encrypt

DH based encryption as implemented by libtomcrypt. See method "encrypt" below.

 my $ct = dh_encrypt($pub_key_filename, $message);
 #or
 my $ct = dh_encrypt(\$buffer_containing_pub_key, $message);
 #or
 my $ct = dh_encrypt($pub_key_filename, $message, $hash_name);

 #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest

Encryption works similar to the Crypt::PK::ECC encryption whereas shared DH key is computed, and the hash of the shared key XOR'ed against the plaintext forms the ciphertext.

dh_decrypt

DH based decryption as implemented by libtomcrypt. See method "decrypt" below.

 my $pt = dh_decrypt($priv_key_filename, $ciphertext);
 #or
 my $pt = dh_decrypt(\$buffer_containing_priv_key, $ciphertext);

dh_sign_message

Generate DH signature as implemented by libtomcrypt. See method "sign_message" below.

 my $sig = dh_sign_message($priv_key_filename, $message);
 #or
 my $sig = dh_sign_message(\$buffer_containing_priv_key, $message);
 #or
 my $sig = dh_sign_message($priv_key, $message, $hash_name);

dh_verify_message

Verify DH signature as implemented by libtomcrypt. See method "verify_message" below.

 dh_verify_message($pub_key_filename, $signature, $message) or die "ERROR";
 #or
 dh_verify_message(\$buffer_containing_pub_key, $signature, $message) or die "ERROR";
 #or
 dh_verify_message($pub_key, $signature, $message, $hash_name) or die "ERROR";

dh_sign_hash

Generate DH signature as implemented by libtomcrypt. See method "sign_hash" below.

 my $sig = dh_sign_hash($priv_key_filename, $message_hash);
 #or
 my $sig = dh_sign_hash(\$buffer_containing_priv_key, $message_hash);

dh_verify_hash

Verify DH signature as implemented by libtomcrypt. See method "verify_hash" below.

 dh_verify_hash($pub_key_filename, $signature, $message_hash) or die "ERROR";
 #or
 dh_verify_hash(\$buffer_containing_pub_key, $signature, $message_hash) or die "ERROR";

dh_shared_secret

DH based shared secret generation. See method "shared_secret" below.

 #on Alice side
 my $shared_secret = dh_shared_secret('Alice_priv_dh1.key', 'Bob_pub_dh1.key');

 #on Bob side
 my $shared_secret = dh_shared_secret('Bob_priv_dh1.key', 'Alice_pub_dh1.key');

SEE ALSO