我试图通过在perl中编码算法来理解椭圆曲线加密。但是获取有关实施ECC的详细信息非常困难。 所以我收集了所有信息并开始编码。
起初我搜索了有关简单曲线的信息,我在此处找到了它:http://www.hjp.at/doc/rfc/rfc5639.html。几条曲线从160到512位。当然,我从最小的一个开始。
编辑:犯了很多错误,主要是由于缺乏信息。但现在这个例子有效。
这是我的perl脚本:
use bignum;
use Math::BigInt::Random;
my $p = hex "E95E4A5F737059DC60DFC7AD95B3D8139515620F";
my $a = hex "340E7BE2A280EB74E2BE61BADA745D97E8F7C300";
my $b = hex "1E589A8595423412134FAA2DBDEC95C8D8675E58";
my $x = hex "BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3";
my $y = hex "1667CB477A1A8EC338F94741669C976316DA6321";
my $q = hex "E95E4A5F737059DC60DF5991D45029409E60FC09";
my $bitLength = 160;
sub point_doubling {
my ($px, $py) = @_;
return $px, $py if $px == 0 && $py == 0;
my $slope_numerator = 3 * $px * $px + $a;
my $slope_denominator = 2 * $py;
my $slope_denominator_inverse_modulo = $slope_denominator->bmodinv($p);
my $slope_inverse_product = $slope_numerator * $slope_denominator_inverse_modulo;
my $slope = $slope_inverse_product % $p;
my $rx = (($slope * $slope - 2 * $px)) % $p;
my $ry = (($slope * ($px - $rx) - $py)) % $p;
return ($rx, $ry);
}
sub point_addition {
my ($px, $py, $qx, $qy) = @_;
return point_doubling($px, $py) if $px == $qx && $py == $qy;
return $px, $py if $qx == 0 && $qy == 0;
return $qx, $qy if $px == 0 && $py == 0;
my $slope_numerator = $qy - $py;
my $slope_denominator = $qx - $px;
my $slope_denominator_inverse_modulo = $slope_denominator->bmodinv($p);
my $slope_inverse_product = $slope_numerator * $slope_denominator_inverse_modulo;
my $slope = $slope_inverse_product % $p;
my $rx = (($slope * $slope - $px - $qx)) % $p;
my $ry = (($slope * ($px - $rx) - $py)) % $p;
return ($rx, $ry);
}
sub scalar_product {
my ($k, $nx, $ny) = @_;
my ($qx, $qy) = (0, 0);
my $bit = 1;
for my $bitCounter (1..$bitLength) {
if ($k & $bit) {
($qx, $qy) = point_addition($nx, $ny, $qx, $qy);
}
($nx, $ny) = point_doubling($nx, $ny);
$bit <<= 1;
}
return ($qx, $qy);
}
sub check_point_on_curve {
my ($qx, $qy) = @_;
return $qy * $qy % $p == ($qx * $qx * $qx + $a * $qx + $b) % $p ||
$qy == 0 && $qx == 0;
}
print "Test if G is in curve:\n";
if (check_point_on_curve($x, $y)) {
print "G is a point on the curve\n";
} else {
die "ERROR: G is NOT a point on the curve\n";
}
# Creating the private key.
# 1.) A random integer dA with 0 < dA < q
my $dA = random_bigint(max => $q);
print "Private key chosen as $dA\n";
# 2.) Calculate the public key QA
my ($qax, $qay) = scalar_product($dA, $x, $y);
print "Public key calculated to ($qax, $qay)\n";
if (check_point_on_curve($qax, $qay)) {
print "Public key is a point on the curve\n";
} else {
die "ERROR: Public key is NOT a point on the curve\n";
}
结果看起来像这样:
Test if G is in curve:
G is a point on the curve
Private key chosen as 14682691932678591389241030591930855095113892
Public key calculated to (1114548639616364108201749083649167655259366359581, 418437095262665064210367316915287142897094980157)
Public key is a point on the curve
感谢您的帮助。