Viewing File: /usr/local/cpanel/3rdparty/perl/536/cpanel-lib/Crypt/Perl/Ed25519/KeyBase.pm
package Crypt::Perl::Ed25519::KeyBase;
use strict;
use warnings;
use Crypt::Perl::Ed25519::Math;
use Crypt::Perl::X;
use Digest::SHA ();
use parent qw( Crypt::Perl::KeyBase );
use constant {
SIGN_BYTE_LENGTH => 64,
OID_Ed25519 => '1.3.101.112',
};
use constant _ASN1_BASE => q<
-- cf. RFC 3280 4.1.1.2
-- XXX COPIED FROM RSA TEMPLATE MODULE
AlgorithmIdentifier ::= SEQUENCE {
algorithm OBJECT IDENTIFIER,
parameters ANY DEFINED BY algorithm OPTIONAL
}
>;
use constant _JWK_THUMBPRINT_JSON_ORDER => qw( crv kty x );
sub to_der {
my ($self) = @_;
require Crypt::Perl::ASN1;
my $asn1 = Crypt::Perl::ASN1->new()->prepare(
_ASN1_BASE() . $self->_ASN1()
)->find('FG_Key');
return $asn1->encode( {
version => 0,
algorithmIdentifier => {
algorithm => OID_Ed25519(),
},
$self->_to_der_args(),
} );
}
# TODO: refactor; duplicated w/ RSA
sub to_pem {
my ($self) = @_;
require Crypt::Format;
return Crypt::Format::der2pem( $self->to_der(), $self->_PEM_HEADER() );
}
sub get_public {
my ($self) = @_;
return $self->{'_public'};
}
sub get_struct_for_public_jwk {
my ($self) = @_;
require MIME::Base64;
return {
kty => 'OKP',
crv => 'Ed25519',
x => MIME::Base64::encode_base64url($self->{'_public'}),
}
}
sub verify {
my ($self, $msg, $sig) = @_;
if (SIGN_BYTE_LENGTH() != length $sig) {
die Crypt::Perl::X::create('Generic', sprintf('Invalid length (%d) of Ed25519 signature: %v.02x', length($sig), $sig));
}
my $public_ar = $self->{'_public_ar'};
my $sig_ar = [ unpack 'C*', $sig ];
my @sm = ( @$sig_ar, unpack( 'C*', $msg ) );
my @m = (0) x @sm;
@m = @sm;
@m[ 32 .. 63 ] = @{$public_ar};
my @p = map { [ Crypt::Perl::Ed25519::Math::gf0() ] } 1 .. 4;
my @q = map { [ Crypt::Perl::Ed25519::Math::gf0() ] } 1 .. 4;
if ( Crypt::Perl::Ed25519::Math::unpackneg( \@q, $public_ar ) ) {
return !1;
}
my @h = unpack 'C*', Digest::SHA::sha512( pack 'C*', @m );
Crypt::Perl::Ed25519::Math::reduce(\@h);
Crypt::Perl::Ed25519::Math::scalarmult(\@p, \@q, \@h);
my @latter_sm = @sm[32 .. $#sm];
Crypt::Perl::Ed25519::Math::scalarbase( \@q, \@latter_sm );
@sm[32 .. $#sm] = @latter_sm;
Crypt::Perl::Ed25519::Math::add( \@p, \@q );
my $t_ar = Crypt::Perl::Ed25519::Math::pack(\@p);
if( Crypt::Perl::Ed25519::Math::crypto_verify_32(\@sm, 0, $t_ar, 0)) {
return !1;
}
my $n = @sm - SIGN_BYTE_LENGTH;
return $n >= 0;
}
sub _verify_binary_key_part {
if (32 != length $_[1]) {
die Crypt::Perl::X::create('Generic', sprintf('Invalid length (%d) of Ed25519 key piece: %v.02x', length($_[1]), $_[1]));
}
return;
}
1;
Back to Directory
File Manager