/usr/share/perl5/Crypt/DSA/Util.pm is in libcrypt-dsa-perl 1.17-3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 | package Crypt::DSA::Util;
use strict;
use Math::BigInt 1.78 try => 'GMP, Pari';
use Fcntl;
use Carp qw( croak );
use vars qw( $VERSION @ISA @EXPORT_OK );
use Exporter;
BEGIN {
$VERSION = '1.17';
@ISA = qw( Exporter );
@EXPORT_OK = qw( bitsize bin2mp mp2bin mod_inverse mod_exp makerandom isprime );
}
## Nicked from Crypt::RSA::DataFormat.
## Copyright (c) 2001, Vipul Ved Prakash.
sub bitsize {
length(Math::BigInt->new($_[0])->as_bin) - 2;
}
sub bin2mp {
my $s = shift;
$s eq '' ?
Math::BigInt->new(0) :
Math::BigInt->new("0b" . unpack("B*", $s));
}
sub mp2bin {
my $p = Math::BigInt->new(shift);
my $base = Math::BigInt->new(256);
my $res = '';
while ($p != 0) {
my $r = $p % $base;
$p = ($p-$r) / $base;
$res = chr($r) . $res;
}
$res;
}
sub mod_exp {
my($a, $exp, $n) = @_;
$a->copy->bmodpow($exp, $n);
}
sub mod_inverse {
my($a, $n) = @_;
$a->copy->bmodinv($n);
}
sub makerandom {
my %param = @_;
my $size = $param{Size};
my $bytes = int($size / 8) + 1;
my $r = '';
if ( sysopen my $fh, '/dev/random', O_RDONLY ) {
my $read = 0;
while ($read < $bytes) {
my $got = sysread $fh, my($chunk), $bytes - $read;
next unless $got;
die "Error: $!" if $got == -1;
$r .= $chunk;
$read = length $r;
}
close $fh;
}
else {
croak "makerandom requires /dev/random";
}
my $down = $size - 1;
$r = unpack 'H*', pack 'B*', '0' x ( $size % 8 ? 8 - $size % 8 : 0 ) .
'1' . unpack "b$down", $r;
Math::BigInt->new('0x' . $r);
}
# For testing, let us choose our isprime function:
*isprime = \&isprime_algorithms_with_perl;
# from the book "Mastering Algorithms with Perl" by Jon Orwant,
# Jarkko Hietaniemi, and John Macdonald
sub isprime_algorithms_with_perl {
use integer;
my $n = shift;
my $n1 = $n - 1;
my $one = $n - $n1; # not just 1, but a bigint
my $witness = $one * 100;
# find the power of two for the top bit of $n1
my $p2 = $one;
my $p2index = -1;
++$p2index, $p2 *= 2
while $p2 <= $n1;
$p2 /= 2;
# number of interations: 5 for 260-bit numbers, go up to 25 for smaller
my $last_witness = 5;
$last_witness += (260 - $p2index) / 13 if $p2index < 260;
for my $witness_count (1..$last_witness) {
$witness *= 1024;
$witness += int(rand(1024)); # XXXX use good rand
$witness = $witness % $n if $witness > $n;
$witness = $one * 100, redo if $witness == 0;
my $prod = $one;
my $n1bits = $n1;
my $p2next = $p2;
# compute $witness ** ($n - 1)
while (1) {
my $rootone = $prod == 1 || $prod == $n1;
$prod = ($prod * $prod) % $n;
return 0 if $prod == 1 && ! $rootone;
if ($n1bits >= $p2next) {
$prod = ($prod * $witness) % $n;
$n1bits -= $p2next;
}
last if $p2next == 1;
$p2next /= 2;
}
return 0 unless $prod == 1;
}
return 1;
}
sub isprime_gp_pari {
my $n = shift;
my $sn = "$n";
die if $sn =~ /\D/;
my $is_prime = `echo "isprime($sn)" | gp -f -q`;
die "No gp installed?" if $?;
chomp $is_prime;
return $is_prime;
}
sub isprime_paranoid {
my $n = shift;
my $perl = isprime_algorithms_with_perl($n);
my $pari = isprime_gp_pari($n);
die "Perl vs. PARI don't match on '$n'\n" unless $perl == $pari;
return $perl;
}
1;
__END__
=head1 NAME
Crypt::DSA::Util - DSA Utility functions
=head1 SYNOPSIS
use Crypt::DSA::Util qw( func1 func2 ... );
=head1 DESCRIPTION
I<Crypt::DSA::Util> contains a set of exportable utility functions
used through the I<Crypt::DSA> set of libraries.
=head2 bitsize($n)
Returns the number of bits in the I<Math::Pari> integer object
I<$n>.
=head2 bin2mp($string)
Given a string I<$string> of any length, treats the string as a
base-256 representation of an integer, and returns that integer,
a I<Math::Pari> object.
=head2 mp2bin($int)
Given a biginteger I<$int> (a I<Math::Pari> object), linearizes
the integer into an octet string, and returns the octet string.
=head2 mod_exp($a, $exp, $n)
Computes $a ^ $exp mod $n and returns the value. The calculations
are done using I<Math::Pari>, and the return value is a I<Math::Pari>
object.
=head2 mod_inverse($a, $n)
Computes the multiplicative inverse of $a mod $n and returns the
value. The calculations are done using I<Math::Pari>, and the
return value is a I<Math::Pari> object.
=head1 AUTHOR & COPYRIGHTS
Please see the Crypt::DSA manpage for author, copyright,
and license information.
=cut
|