Skip Menu |

This queue is for tickets about the Crypt-OpenPGP CPAN distribution.

Report information
The Basics
Id: 68018
Status: open
Priority: 0/
Queue: Crypt-OpenPGP

People
Owner: Nobody in particular
Requestors: brobison [...] gmail.com
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: 1.06 Crypt::OpenPGP::encrypt hangs in OpenPGP/Key/Public/ElGamal.pm:gen_k()
Date: Sat, 7 May 2011 23:55:35 -0500
To: bug-Crypt-OpenPGP [...] rt.cpan.org
From: Brian Robison <brobison [...] gmail.com>
Here's a skeletal test case, with specific keys redacted: ----- #!/usr/bin/perl -w use Crypt::OpenPGP; my $pub_key = <PUB_KEY>; my $sec_key = <SEC_KEY>; my $key_id = <KEY_ID>; my $passphrase = shift; die "Usage: $0 passphrase" if (! $passphrase); my $data = "this is a test"; my $new_crypt = &encrypt($key_id, $pub_key, $data); sub encrypt { my ($key_id, $pub_key, $data) = @_; my $pubring = Crypt::OpenPGP::KeyRing->new(Data => $pub_key); my $pgp = Crypt::OpenPGP->new(PubRing => $pubring); # This hangs! return $pgp->encrypt( KeyID => $key_id, Data => $data, Armour => 1, ); } ----- I found the problem in OpenPGP/Key/Public/ElGamal.pm:gen_k(): sub gen_k { my($p) = @_; ## XXX choose bitsize based on bitsize of $p my $bits = 198; my $p_minus1 = $p - 1; # --- LINE 58: BUG! --- require Crypt::Random; my $k = Crypt::Random::makerandom( Size => $bits, Strength => 0 ); # We get back a Math::Pari object, but need a Math::BigInt $k = Math::BigInt->new($k); while (1) { last if Math::BigInt::bgcd($k, $p_minus1) == 1; $k++; } $k; } At line 58, $p_minus is actually an "inf" perl int, Math::BigInt::bgcd() returns NaN, and the loop never exits. Replacing line 58 with the following solved the problem (not necessarily the best fix, but it shows the point): my $p_minus1 = Math::BigInt->new($p); $p_minus1->bsub(1); Here're the additional details: Distribution: Crypt-OpenPGP-1.06 Perl: v5.10.1 OS: FreeBSD 8.2-STABLE
I'm also running into this error on perl 5.8.8. It also appears to be broken in 1.05. encrypt() works if I roll back to 1.04. Any chance of getting a release to fix this? Thanks! :-)
From: Christian Ruppert <idl0r [...] qasl.de>
On Sun May 08 00:55:45 2011, brobison@gmail.com wrote: Show quoted text
> Here's a skeletal test case, with specific keys redacted: > > ----- > #!/usr/bin/perl -w > > use Crypt::OpenPGP; > > my $pub_key = <PUB_KEY>; > my $sec_key = <SEC_KEY>; > > my $key_id = <KEY_ID>; > > my $passphrase = shift; > die "Usage: $0 passphrase" if (! $passphrase); > > my $data = "this is a test"; > my $new_crypt = &encrypt($key_id, $pub_key, $data); > > sub encrypt { > my ($key_id, $pub_key, $data) = @_; > my $pubring = Crypt::OpenPGP::KeyRing->new(Data => $pub_key); > my $pgp = Crypt::OpenPGP->new(PubRing => $pubring); > > # This hangs! > return $pgp->encrypt( > KeyID => $key_id, > Data => $data, > Armour => 1, > ); > } > ----- > > I found the problem in OpenPGP/Key/Public/ElGamal.pm:gen_k(): > > sub gen_k { > my($p) = @_; > ## XXX choose bitsize based on bitsize of $p > my $bits = 198; > my $p_minus1 = $p - 1; # --- LINE 58: BUG! --- > > require Crypt::Random; > my $k = Crypt::Random::makerandom( Size => $bits, Strength => 0 ); > # We get back a Math::Pari object, but need a Math::BigInt > $k = Math::BigInt->new($k); > while (1) { > last if Math::BigInt::bgcd($k, $p_minus1) == 1; > $k++; > } > $k; > } > > At line 58, $p_minus is actually an "inf" perl int, Math::BigInt::bgcd() > returns NaN, and the loop never exits. > > Replacing line 58 with the following solved the problem (not
necessarily the Show quoted text
> best fix, but it shows the point): > > my $p_minus1 = Math::BigInt->new($p); > $p_minus1->bsub(1); > > Here're the additional details: > > Distribution: Crypt-OpenPGP-1.06 > Perl: v5.10.1 > OS: FreeBSD 8.2-STABLE
Confirmed and the proposed "fix" helps.
Hm, I just did some tests with 1.03 and 1.06 and I am not sure if that is related but: Create a new RSA key using gpg --gen-key (in my case size 4096) and one Elgamal key (in my case size 3072). Export the public keys using "gpg --export --armor $keyid >testkey". #!/usr/bin/perl -w use strict; use Crypt::OpenPGP::KeyRing; use Crypt::OpenPGP; my $key; open(my $fh, '<', $ARGV[0]) or die "Error: $!\n"; { local $/ = undef; $key = <$fh>; } close($fh); my $pubring = new Crypt::OpenPGP::KeyRing(Data => $key); my $pgp = new Crypt::OpenPGP(PubRing => $pubring); my $encrypted = $pgp->encrypt(Data => "foobar", Recipients => "@", Cipher => "CAST5", Armour => 1); Run that little test script with both keys and both versions. The encryption with RSA in 1.06 is *almost* as fast as in 1.03 (IMHO slightly slower) but now do the same with the ElGamal one. In 1.03 it's pretty fast and takes about a second or so but then try it with 1.06 and the "fix" above. perl test.pl testkey3 49.64s user 0.84s system 89% cpu 56.258 total So it is noticable slower than in 1.03. (Haven't tried 1.04 or 1.05).