Viewing File: /usr/local/cpanel/3rdparty/perl/536/cpanel-lib/Crypt/Perl/ECDSA/Generate.pm
package Crypt::Perl::ECDSA::Generate;
=encoding utf-8
=head1 NAME
Crypt::Perl::ECDSA::Generate - ECDSA key generation
=head1 SYNOPSIS
use Crypt::Perl::ECDSA::Generate ();
#$prkey is a C::P::E::PrivateKey instance.
my $prkey = Crypt::Perl::ECDSA::Generate::by_curve_name('secp521r1');
my $signature = $prkey->sign('Hello!');
die 'Wut' if $prkey->verify('Hello!', $signature);
#You can also, in case it’s useful, do this. It’s probably
#only useful if you’re developing a new curve or something … ??
my $prkey2 = Crypt::Perl::ECDSA::Generate::by_explicit_curve(
{
p => Crypt::Perl::BigInt->new(...),
a => ...,
b => ...,
n => ...,
h => ...,
gx => ...,
gy => ...,
},
);
=head1 DISCUSSION
Thankfully, this is easy enough on processors that it’s feasible
in pure Perl!
=cut
use strict;
use warnings;
use Crypt::Perl::BigInt ();
use Crypt::Perl::Math ();
use Crypt::Perl::RNG ();
use Crypt::Perl::ECDSA::EC::DB ();
use Crypt::Perl::ECDSA::EC::Curve ();
use Crypt::Perl::ECDSA::PrivateKey ();
#The curve name is optional; if given, only the name will be encoded
#into the key rather than the explicit curve parameters.
sub by_curve_name {
my ($curve_name) = @_;
my $key_parts = _generate(
Crypt::Perl::ECDSA::EC::DB::get_curve_data_by_name($curve_name),
);
return Crypt::Perl::ECDSA::PrivateKey->new_by_curve_name($key_parts, $curve_name);
}
*by_name = *by_curve_name; #legacy
sub by_explicit_curve {
my ($curve_hr) = @_;
my $key_parts = _generate($curve_hr);
return Crypt::Perl::ECDSA::PrivateKey->new($key_parts, $curve_hr);
}
#from generateKeyPairHex() in jsrsasign
sub _generate {
my ($curve_hr) = @_;
my $biN = $curve_hr->{'n'};
my $biPrv = Crypt::Perl::Math::randint( $biN );
#my $G = '04' . join(q<>, map { substr( $_->as_hex(), 2 ) } @{$curve}{'gx','gy'});
#$G = Crypt::Perl::BigInt->from_hex($full_g);
my $curve = Crypt::Perl::ECDSA::EC::Curve->new( @{$curve_hr}{'p', 'a', 'b'} );
my $G = $curve->decode_point( @{$curve_hr}{'gx','gy'});
my $epPub = $G->multiply($biPrv);
my $biX = $epPub->get_x()->to_bigint();
my $biY = $epPub->get_y()->to_bigint();
my $key_hex_len = 2 * Crypt::Perl::Math::ceil( $curve->keylen() / 8 );
my ($hx, $hy) = map { substr( $_->as_hex(), 2 ) } $biX, $biY;
$_ = sprintf "%0${key_hex_len}s", $_ for ($hx, $hy);
my $biPub = Crypt::Perl::BigInt->from_hex("04$hx$hy");
return {
version => 0,
private => $biPrv,
public => $biPub,
};
}
#sub generate {
# my ($curve_name) = @_
#
# my $curve_hr = Crypt::Perl::ECDSA::EC::DB::get_curve_data_by_name($curve_name);
#
# my $bytes = $curve_hr->{'n'}->as_hex() / 2 - 1;
# my $ns2 = $curve_hr->{'n'} - 2;
#
# do {
# my $priv = _gen_bignum($bytes);
# next if $priv > $ns2;
#
# $priv += 1;
#
# return _key_from_private($curve_hr, $priv);
# } while 1;
#}
#
#sub _key_from_private {
# return _keypair( $curve_hr, $priv );
#}
#
#sub _keypair {
# my ($curve_hr, $priv) = @_;
#
# $priv %= $curve_hr->{'n'};
#
# my $full_g = '04' . join(q<>, map { substr( $_->as_hex(), 2 ) } @{$curve}{'gx','gy'});
# $full_g = Crypt::Perl::BigInt->from_hex($full_g);
#
# return {
# priv => $priv,
# pub => $full_g * $priv,
# };
#}
#
#sub _gen_bignum {
# my ($bits) = @_;
#
# return Crypt::Perl::BigInt->from_bin( Crypt::Perl::RNG::bit_string($bits) );
#}
1;
Back to Directory
File Manager