Initial Commit

This commit is contained in:
Riley Schneider
2025-12-03 16:38:10 +01:00
parent c5e26bf594
commit b732d8d4b5
17680 changed files with 5977495 additions and 2 deletions

View File

@@ -0,0 +1,53 @@
package Crypt::OpenPGP::Key::Public::DSA;
use strict;
use Crypt::DSA::Key;
use Crypt::OpenPGP::Key::Public;
use Crypt::OpenPGP::ErrorHandler;
use base qw( Crypt::OpenPGP::Key::Public Crypt::OpenPGP::ErrorHandler );
sub can_sign { 1 }
sub abbrev { 'D' }
sub init {
my $key = shift;
$key->{key_data} = shift || Crypt::DSA::Key->new;
$key;
}
sub keygen {
my $class = shift;
my %param = @_;
require Crypt::DSA;
my $dsa = Crypt::DSA->new;
my $sec = $dsa->keygen( %param );
my $pub = bless { }, 'Crypt::DSA::Key';
for my $e (qw( p q g pub_key )) {
$pub->$e( $sec->$e() );
}
($pub, $sec);
}
sub public_props { qw( p q g y ) }
sub sig_props { qw( r s ) }
sub y { $_[0]->{key_data}->pub_key(@_[1..$#_]) }
sub size { $_[0]->{key_data}->size }
sub verify {
my $key = shift;
my($sig, $dgst) = @_;
require Crypt::DSA;
my $dsa = Crypt::DSA->new;
my $dsa_sig = Crypt::DSA::Signature->new;
$dsa_sig->r($sig->{r});
$dsa_sig->s($sig->{s});
$dsa->verify(
Key => $key->{key_data},
Digest => $dgst,
Signature => $dsa_sig
);
}
1;

View File

@@ -0,0 +1,79 @@
package Crypt::OpenPGP::Key::Public::ElGamal;
use strict;
use Crypt::OpenPGP::Util qw( bitsize);
use Crypt::OpenPGP::Key::Public;
use Crypt::OpenPGP::ErrorHandler;
use base qw( Crypt::OpenPGP::Key::Public Crypt::OpenPGP::ErrorHandler );
sub can_encrypt { 1 }
sub abbrev { 'g' }
sub public_props { qw( p g y ) }
sub crypt_props { qw( a b ) }
sub sig_props { qw( a b ) }
sub size { bitsize($_[0]->p) }
sub init {
my $key = shift;
$key->{key_data} = shift || Crypt::OpenPGP::ElGamal::Public->new;
$key;
}
sub keygen {
return $_[0]->error("ElGamal key generation is not supported");
}
sub encrypt {
my $key = shift;
my($M) = @_;
$key->{key_data}->encrypt($M);
}
package Crypt::OpenPGP::ElGamal::Public;
use strict;
use Crypt::OpenPGP::Util qw( mod_exp );
use Math::BigInt;
sub new { bless {}, $_[0] }
sub encrypt {
my $key = shift;
my($M) = @_;
my $k = gen_k($key->p);
my $a = mod_exp($key->g, $k, $key->p);
my $b = mod_exp($key->y, $k, $key->p);
$b->bmod($key->p);
{ a => $a, b => $b * $M };
}
sub gen_k {
my($p) = @_;
## XXX choose bitsize based on bitsize of $p
my $bits = 198;
my $p_minus1 = $p - 1;
my $k = Crypt::OpenPGP::Util::get_random_bigint($bits);
while (1) {
last if Math::BigInt::bgcd($k, $p_minus1) == 1;
$k++;
}
$k;
}
sub _getset {
my $e = shift;
sub {
my $key = shift;
$key->{$e} = shift if @_;
$key->{$e};
}
}
*p = _getset('p');
*g = _getset('g');
*y = _getset('y');
1;

View File

@@ -0,0 +1,82 @@
package Crypt::OpenPGP::Key::Public::RSA;
use strict;
use Crypt::RSA::Key::Public;
use Crypt::OpenPGP::Digest;
use Crypt::OpenPGP::Util qw( bitsize bin2mp mp2bin );
use Crypt::OpenPGP::Key::Public;
use Crypt::OpenPGP::ErrorHandler;
use base qw( Crypt::OpenPGP::Key::Public Crypt::OpenPGP::ErrorHandler );
sub can_encrypt { 1 }
sub can_sign { 1 }
sub abbrev { 'R' }
sub public_props { qw( n e ) }
sub crypt_props { qw( c ) }
sub sig_props { qw( c ) }
sub init {
my $key = shift;
$key->{key_data} = shift || Crypt::RSA::Key::Public->new;
$key;
}
sub keygen {
my $class = shift;
my %param = @_;
$param{Password} = $param{Passphrase};
require Crypt::RSA::Key;
my $chain = Crypt::RSA::Key->new;
my($pub, $sec) = $chain->generate( %param );
return $class->error( $chain->errstr ) unless $pub && $sec;
($pub, $sec);
}
sub size { bitsize($_[0]->{key_data}->n) }
sub check { $_[0]->{key_data}->check }
sub encrypt {
my $key = shift;
my($M) = @_;
require Crypt::RSA::Primitives;
my $prim = Crypt::RSA::Primitives->new;
my $c = $prim->core_encrypt( Key => $key->{key_data}, Plaintext => $M ) or
return $key->error($prim->errstr);
{ c => $c }
}
sub verify {
my $key = shift;
my($sig, $dgst) = @_;
my $k = $key->bytesize;
require Crypt::RSA::Primitives;
my $prim = Crypt::RSA::Primitives->new;
my $c = $sig->{c};
my $m = $prim->core_verify( Key => $key->{key_data}, Signature => $c) or
return;
$m = mp2bin($m, $k - 1);
my $hash_alg = Crypt::OpenPGP::Digest->alg($sig->{hash_alg});
my $M = encode($dgst, $hash_alg, $k - 1);
$m eq $M;
}
{
my %ENCODING = (
MD2 => pack('H*', '3020300C06082A864886F70D020205000410'),
MD5 => pack('H*', '3020300C06082A864886F70D020505000410'),
SHA1 => pack('H*', '3021300906052B0E03021A05000414'),
);
sub encode {
my($dgst, $hash_alg, $mlen) = @_;
my $alg = $ENCODING{$hash_alg};
my $m = $alg . $dgst;
my $padlen = $mlen - length($m) - 2;
my $pad = chr(255) x $padlen;
chr(1) . $pad . chr(0) . $m;
}
}
1;