rsacomp.pl
#!/usr/local/bin/perl -w
use strict; $|=1; no strict 'refs'; use Math::BigInt lib => 'GMP';
use CGI; use Benchmark;
sub extended_euclid {
$_[1] or return $_[0], 1, 0;
my ($d, $x, $y) = extended_euclid ($_[1], $_[0] % $_[1]);
$d, $y, $x - $y * ($_[0] / $_[1]);
}
sub modexp {
my ($a, $b, $n) = @_;
my $d = new Math::BigInt (1);
my @b = split //, sprintf "%0b", $b;
for my $i (0..@b-1) {
$d = $d*$d % $n;
$d = $d*$a % $n if $b[$i]
}
$d
}
sub loese_mod_eq {
my ($d, $x, $y) = extended_euclid ($_[0], $_[2]);
$_[1] % $d ? undef : map { ($x * $_[1] / $d % $_[2] + $_ * $_[2] / $d) % $_[2] } 0..$d-1
}
my $r = new CGI;
print $r->header();
my $y = defined $r->param('y') ? $r->param('y') : 16777216;
my $e = defined $r->param('e') ? $r->param('e') : 0;
my $d = defined $r->param('d') ? $r->param('d') : 80964007;
my $p = defined $r->param('p') ? $r->param('p') : 8999;
my $q = defined $r->param('q') ? $r->param('q') : 9001;
my $i = defined $r->param('i') ? $r->param('i') : 100;
my $m = 0;
$y =~ tr/0-9//cd; $m = length ($y) > $m ? length($y) : $m;
$e =~ tr/0-9//cd; $m = length ($e) > $m ? length($e) : $m;
$d =~ tr/0-9//cd; $m = length ($d) > $m ? length($d) : $m;
$p =~ tr/0-9//cd; $m = length ($p) > $m ? length($p) : $m;
$q =~ tr/0-9//cd; $m = length ($q) > $m ? length($y) : $m;
$i =~ tr/0-9//cd; $i = $m < 50 && $i > 0 && $i <= 300 ? $i : $i < 101 && $i > 0 ? $ i : 100;
($y, $e, $d, $p, $q) = map { $_ = length($_) < 250 ? $_ : 1; new Math::BigInt ($_) } $y, $e, $d, $p, $q;
$d = $d == 0 ? [loese_mod_eq ($e, 1, (($p-1) * ($q-1)))]->[0] : $d;
my (undef, $Xp, $Xq) = extended_euclid ($p, $q);
my $n = $p*$q;
my $t1 = $Xq*$q;
my $t2 = $Xp*$p;
my $c2 = [loese_mod_eq ($p,1,$q)]->[0];
sub RSA {
modexp ($y, $d, $n);
}
sub RSASRC {
my ($xp, $xq) = map { $y->copy()->bmodpow ($d % ($_-1) , $_); } $p, $q;
($xp*$t1 + $xq*$t2) % $n
}
sub RSAMRC {
my ($xp, $xq) = map { $y->copy()->bmodpow ($d % ($_-1) , $_); } $p, $q;
$xp + (($xq-$xp) * $c2 % $q) * $p
}
my $fx = RSASRC();
my $fd = $d; my $ffd; my $x;
while ($_ = substr $fd,0,80,'') {
$ffd .= $_."<br />\n";
}
while ($_ = substr $fx,0,80,'') {
$x .= $_."<br />\n";
}
my $sd = $r->param('d');
my $se = $r->param('e');
if ((! defined $sd) && (! defined $se)) { $sd = 80964007 }
print <<HEAD
<html>
<head>
</head>
<body>
<h1>Vergleich von RSA, RSASRC, RSAMRC</h1>
(Eingabeparameter sind auf max 250 Ziffern beschränkt)
HEAD
;
print <<BLERX
<table borders="0" width="100%">
<tr>
<td width="50%" align="left">
<form method="post" enctype="multipart/form-data">
y:<input type="text" size="50" maxlength="400" name="y" value="$y"><br />
d:<input type="text" size="50" maxlength="400" name="d" value="$sd"><br />
e:<input type="text" size="50" maxlength="400" name="e" value="$se"><br />
p:<input type="text" size="50" maxlength="400" name="p" value="$p"><br />
q:<input type="text" size="50" maxlength="400" name="q" value="$q"><br />
Anzahl der Durchläufe (<=300 wenn maxlength < 50, ansonsten <=100):<input type="text" size="5" maxlength="3" name="i" value="$i"><br />
(entweder d oder e angeben (und die jeweils andere Variable als 0); im Zweifel wird d verwendet)<br />
<input type="submit" />
</form>
</td>
<td width="50%" align="center">
210-stellige p und q<br />
<form method="post" enctype="multipart/form-data">
<input type="hidden" name="y" value="16777216">
<input type="hidden" name="e" value="65537">
<input type="hidden" name="d" value="0">
<input type="hidden" name="p" value="643808006803554439230129854961492699151386107534013432918073439524138264842370630061369715394739134090922937332590384720397133335969549256322620979036686633213903952966175107096769180017646161851573147596390153">
<input type="hidden" name="q" value="449417999055441493994709297093108513015373787049558499205492347871729927573118262811508386655998299074566974373711472560655026288668094291699357843464363003144674940345912431129144354948751003607115263071543163">
<input type="hidden" name="i" value="50">
<input type="submit" />
</form>
</td>
</tr>
</table>
<pre>
BLERX
;
timethis ($i, 'RSA', 'RSA');
timethis ($i, 'RSASRC', 'RSASRC');
timethis ($i, 'RSAMRC', 'RSAMRC');
print <<FOOTER
</pre>
<br />
mit
<br />d =<br /> $ffd und <br />x = <br /><b>$x</b><br />
</body>
</html>
FOOTER
;