++ed by:

1 PAUSE user

Daisuke Maki


Crypt::DH::GMP - Crypt::DH Using GMP Directly


  use Crypt::DH::GMP;

  my $dh = Crypt::DH::GMP->new(p => $p, g => $g);
  my $val = $dh->compute_secret();

  # If you want compatibility with Crypt::DH (it uses Math::BigInt)
  # then use this flag
  # You /think/ you're using Crypt::DH, but...
  use Crypt::DH::GMP qw(-compat);

  my $dh = Crypt::DH->new(p => $p, g => $g);
  my $val = $dh->compute_secret(); 


Crypt::DH::GMP is a (somewhat) portable replacement to Crypt::DH, implemented mostly in C.

Crypt::DH uses Math::BigInt, which is a very feature-full and fast interface to perform high-precision math. However, with Crypt::DH, there exists several problems:

GMP/Pari libraries are almost always required

GMP and Pari are High precision math libraries which can be used from Math::BigInt. They are great tools, but require the installation of these C libraries.

Crypt::DH (and in turn, Math::BigInt) works without these modules, but when used without them, Crypt::DH is pretty much useless because of its poor performance. This makes the underlying C libraries a requirement.

Crypt::DH suffers from having Math::BigInt in between GMP

Math::BigInt is (again) a god-sent for those of us who require high-precision math from within Perl, but within the usage case that goes from Crypt::DH, Math::BigInt, and finally to GMP|Pari, Crypt::DH suffers dramatically in terms of performance, mainly (I assume) from the fact that it requires several calls that round trip conversions between Perl and GMP.

Based on these, I've decided that it will probably benefit a fair amount of people by introducing a Crypt::DH compatible layer that directly works with the C layer of gmp.

This means that we've essentially eliminated 2 call stacks worth of Perl method calls (which are expensive) and we also only load the 1 (Crypt::DH::GMP) module instead of 3 (Crypt::DH + Math::BigInt + Math::BigInt::GMP)

These add up to a fairly significant increase in performance.


Crypt::DH::GMP absolutely refuses to consider using anything other than strings as its parameters and/or return values therefore if you would like to use Math::BigInt objects as your return values, you can not use Crypt::DH::GMP directly. Instead, you need to be explicit about it:

  use Crypt::DH;
  use Crypt::DH::GMP qw(-compat); # must be loaded AFTER Crypt::DH

Specifying -compat invokes a very nasty hack that overwrites Crypt::DH's symbol table -- this then forces Crypt::DH users to use Crypt::DH::GMP instead, even if you are writing

  my $dh = Crypt::DH->new(...);


By NO MEANS is this an exhaustive benchmark, but here's what I get on my MacBook (OS X 10.5.2, 2GHz Core 2 Duo, 2GB RAM)

  daisuke@beefcake Crypt-DH-GMP$ perl -Mblib tools/benchmark.pl 
        Rate    pp   gmp
  pp  1.70/s    --  -98%
  gmp  112/s 6526%    --

I want it to run for much longer duration, but the above was all I could get going at 1am on this particular day











Computes the key, and returns a string that is byte-padded two's compliment in binary form.


Returns the pub_key as a string that is byte-padded two's compliment in binary form.


Daisuke Maki <daisuke@endeworks.jp>


This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

See http://www.perl.com/perl/misc/Artistic.html