if $p is very large (and it's not a Math::BigInt), $p-1 can overflow and return "inf", causing the loop below to just loop forever looking for relative primeness against infinity.
sub gen_k {
my($p) = @_;
[...]
my $p_minus1 = $p - 1;
[...]
$k = Math::BigInt->new($k);
while (1) {
last if Math::BigInt::bgcd($k, $p_minus1) == 1;
$k++;
}