Alt-Crypt-RSA-BigInt

 view release on metacpan or  search on metacpan

Changes.old  view on Meta::CPAN


  * Modified Crypt::RSA::encrypt() to return an error when the keysize is
    too small for use with the selected scheme.

  * Modified Crypt::RSA ::ES::* and ::SS::* to work with keysizes 
    that are not multiples of 8.

  * Wrote ::DataFormat::octet_len() to computes the octet length of
    an integer.

  * Wrote exportable ::Debug::debuglevel(). Use debuglevel(1) to turn on
    debugging.


1.34                                                        April 7, 2001 

  * Wrote crypt-rsa-interoperablity.pod that contains the structure for a
    Crypt::RSA interoperability chart. Added an entry for RSAREF 2.0
    signatures and encryption

  * Support for decryption using the Chinese Remainder Threorum
    in ::Primitives::decrypt(). Patch by Benjamin Trott

Changes.old  view on Meta::CPAN


 * Wrote ::SS:PKCS1v15 (that implements PKCS #1 v1.5 signatures) and a test
   for it (t/14-es-pkcs1v15.t)

 * Renamed ::ES::PKCS1_v1_5 to ::ES::PKCS1v15. The underscores were
   driving me nuts

 * Wrote ::DataFormat::h2osp() - Hex to Octet String Primitive, that
   converts hex strings/numbers of arbitrary length into octet strings

 * Couple of small changes to ::Debug::debug()


1.32                                                        April 5, 2001

 * Wrote ::ES::PKCS1_v1_5 that implements PKCS #1 v1.5 padded encryption,
   and a test for it (t/13-es-pkcs1v15.t)


1.31                                                        April 3, 2001

inc/Devel/CheckLib.pm  view on Meta::CPAN

            );
        } else { # Unix-ish: gcc, Sun, AIX (gcc, cc), ...
            @sys_cmd = (
                @$cc,
                @$ld,
                $cfile,
                (map { "-I$_" } @incpaths),
                "-o", "$exefile"
            );
        }
        warn "# @sys_cmd\n" if $args{debug};
        my $rv = $args{debug} ? system(@sys_cmd) : _quiet_system(@sys_cmd);
        push @missing, $header if $rv != 0 || ! -x $exefile;
        _cleanup_exe($exefile);
        unlink $ofile if -e $ofile;
        unlink $cfile;
    } 

    # now do each library in turn with headers
    my($ch, $cfile) = File::Temp::tempfile(
        'assertlibXXXXXXXX', SUFFIX => '.c'
    );

inc/Devel/CheckLib.pm  view on Meta::CPAN

            @sys_cmd = (
                @$cc,
                @$ld,
                $cfile,
                "-o", "$exefile",
                (map { "-I$_" } @incpaths),
                (map { "-L$_" } @libpaths),
                "-l$lib",
            );
        }
        warn "# @sys_cmd\n" if $args{debug};
        my $rv = $args{debug} ? system(@sys_cmd) : _quiet_system(@sys_cmd);
        push @missing, $lib if $rv != 0 || ! -x $exefile;
        my $absexefile = File::Spec->rel2abs($exefile);
        $absexefile = '"'.$absexefile.'"' if $absexefile =~ m/\s/;
        push @wrongresult, $lib if $rv == 0 && -x $exefile && system($absexefile) != 0;
        unlink $ofile if -e $ofile;
        _cleanup_exe($exefile);
    } 
    unlink $cfile;

    my $miss_string = join( q{, }, map { qq{'$_'} } @missing );

lib/Crypt/RSA/Debug.pm  view on Meta::CPAN

## Crypt::RSA::Debug
##
## Copyright (c) 2001, Vipul Ved Prakash.  All rights reserved.
## This code is free software; you can redistribute it and/or modify
## it under the same terms as Perl itself.

use vars qw(@ISA @EXPORT_OK);
require Exporter;
@ISA = qw(Exporter);

@EXPORT_OK = qw(debug debuglevel); 

my $DEBUG = 0; 

sub debug{
    return unless $DEBUG;
    my ($caller, undef) = caller;
    my (undef,undef,$line,$sub) = caller(1); $sub =~ s/.*://;
    $sub = sprintf "%12s()%4d", $sub, $line;
    $sub .= " |  " . (shift);  
    $sub =~ s/\x00/[0]/g; 
    $sub =~ s/\x01/[1]/g; 
    $sub =~ s/\x02/[2]/g; 
    $sub =~ s/\x04/[4]/g; 
    $sub =~ s/\x05/[5]/g; 
    $sub =~ s/\xff/[-]/g; 
    $sub =~ s/[\x00-\x1f]/\./g; 
    $sub =~ s/[\x7f-\xfe]/_/g;
    print "$sub\n";
}


sub debuglevel { 

    my ($level) = shift;
    $DEBUG = $level;

}


=head1 NAME

Crypt::RSA::Debug - Debug routine for Crypt::RSA.

=head1 SYNOPSIS

    use Crypt::RSA::Debug qw(debug);
    debug ("oops!");

=head1 DESCRIPTION

The module provides support for the I<print> method of debugging!

=head1 FUNCTION 

=over 4

=item B<debug> String

Prints B<String> on STDOUT, along with caller's function name and line number.

=item B<debuglevel> Integer

Sets the class data I<debuglevel> to specified value. The value
defaults to 0. Callers can use the debuglevel facility by
comparing $Crypt::RSA::DEBUG to the desired debug level before
generating a debug statement.

=back

=head1 AUTHOR

Vipul Ved Prakash, E<lt>mail@vipul.netE<gt>

=cut

1;

lib/Crypt/RSA/ES/OAEP.pm  view on Meta::CPAN

## Crypt::RSA::ES::OAEP 
##
## Copyright (c) 2001, Vipul Ved Prakash.  All rights reserved.
## This code is free software; you can redistribute it and/or modify
## it under the same terms as Perl itself.

use base 'Crypt::RSA::Errorhandler';
use Math::Prime::Util  qw/random_bytes/;
use Crypt::RSA::DataFormat qw(bitsize os2ip i2osp octet_xor mgf1 octet_len);
use Crypt::RSA::Primitives;
use Crypt::RSA::Debug      qw(debug);
use Digest::SHA            qw(sha1);
use Sort::Versions         qw(versioncmp);
use Carp;

$Crypt::RSA::ES::OAEP::VERSION = '1.99';

sub new { 
    my ($class, %params) = @_;
    my $self = bless { primitives => new Crypt::RSA::Primitives, 
                       P          => "",

lib/Crypt/RSA/ES/OAEP.pm  view on Meta::CPAN

    }
    return $self;
}


sub encrypt { 
    my ($self, %params) = @_; 
    my $key = $params{Key}; my $M = $params{Message} || $params{Plaintext};
    return $self->error ("Missing Message or Plaintext parameter", \$key, \%params) unless $M;
    return $self->error ($key->errstr, \$M, $key, \%params) unless $key->check;
    my $k = octet_len ($key->n);  debug ("octet_len of modulus: $k");
    my $em = $self->encode ($M, $self->{P}, $k-1) || 
        return $self->error ($self->errstr, \$M, $key, \%params);
    my $m = os2ip ($em);
    my $c = $self->{primitives}->core_encrypt ( Plaintext => $m, Key => $key );
    my $ec = i2osp ($c, $k);  debug ("ec: $ec");
    return $ec;
}    


sub decrypt { 
    my ($self, %params) = @_;
    my $key = $params{Key}; my $C = $params{Cyphertext} || $params{Ciphertext}; 
    return $self->error ("Missing Cyphertext or Ciphertext parameter", \$key, \%params) unless $C;
    return $self->error ($key->errstr, $key, \%params) unless $key->check;
    my $k = octet_len ($key->n);  

lib/Crypt/RSA/ES/OAEP.pm  view on Meta::CPAN

    }
    my $phash = $self->hash ($P);
    my $db = $phash . $PS . chr(1) . $M; 
    my $seed = random_bytes($hlen);
    my $dbmask = $self->mgf ($seed, $emlen-$hlen);
    my $maskeddb = octet_xor ($db, $dbmask);
    my $seedmask = $self->mgf ($maskeddb, $hlen);
    my $maskedseed = octet_xor ($seed, $seedmask);
    my $em = $maskedseed . $maskeddb;

    debug ("emlen == $emlen");
    debug ("M == $M [" . length($M) . "]"); 
    debug ("PS == $PS [$pslen]"); 
    debug ("phash == $phash [" . length($phash) . "]"); 
    debug ("seed == $seed [" . length($seed) . "]"); 
    debug ("seedmask == $seedmask [" . length($seedmask) . "]"); 
    debug ("db == $db [" . length($db) . "]"); 
    debug ("dbmask == $dbmask [" . length($dbmask) . "]"); 
    debug ("maskeddb == $maskeddb [" . length($maskeddb) . "]"); 
    debug ("em == $em [" . length($em) . "]"); 

    return $em;
}


sub decode { 
    my ($self, $em, $P) = @_; 
    my $hlen = $$self{hlen};

    debug ("P == $P");
    return $self->error ("Decoding error.", \$P) if length($em) < 2*$hlen+1;
    my $maskedseed = substr $em, 0, $hlen; 
    my $maskeddb = substr $em, $hlen; 
    my $seedmask = $self->mgf ($maskeddb, $hlen);
    my $seed = octet_xor ($maskedseed, $seedmask);
    my $dbmask = $self->mgf ($seed, length($em) - $hlen);
    my $db = octet_xor ($maskeddb, $dbmask); 
    my $phash = $self->hash ($P); 

    debug ("em == $em [" . length($em) . "]"); 
    debug ("phash == $phash [" . length($phash) . "]"); 
    debug ("seed == $seed [" . length($seed) . "]"); 
    debug ("seedmask == $seedmask [" . length($seedmask) . "]"); 
    debug ("maskedseed == $maskedseed [" . length($maskedseed) . "]"); 
    debug ("db == $db [" . length($db) . "]"); 
    debug ("maskeddb == $maskeddb [" . length($maskeddb) . "]"); 
    debug ("dbmask == $dbmask [" . length($dbmask) . "]"); 

    my ($phashorig) = substr $db, 0, $hlen;
    debug ("phashorig == $phashorig [" . length($phashorig) . "]"); 
    return $self->error ("Decoding error.", \$P) unless $phashorig eq $phash; 
    $db = substr $db, $hlen;
    my ($chr0, $chr1) = (chr(0), chr(1));
    my ($ps, $m);
    debug ("db == $db [" . length($db) . "]"); 
    unless ( ($ps, undef, $m) = $db =~ /^($chr0*)($chr1)(.*)$/s ) { 
        return $self->error ("Decoding error.", \$P);
    } 

    return $m;
}


sub hash { 
    my ($self, $data) = @_;

lib/Crypt/RSA/ES/PKCS1v15.pm  view on Meta::CPAN

## Crypt::RSA::ES::PKCS1v15
##
## Copyright (c) 2001, Vipul Ved Prakash.  All rights reserved.
## This code is free software; you can redistribute it and/or modify
## it under the same terms as Perl itself.

use base 'Crypt::RSA::Errorhandler';
use Math::Prime::Util qw/random_bytes/;
use Crypt::RSA::DataFormat qw(bitsize octet_len os2ip i2osp);
use Crypt::RSA::Primitives;
use Crypt::RSA::Debug      qw(debug);
use Carp;

$Crypt::RSA::ES::PKCS1v15::VERSION = '1.99';

sub new { 
    my ($class, %params) = @_;
    my $self = bless { primitives => new Crypt::RSA::Primitives, 
                       VERSION    => $Crypt::RSA::ES::PKCS1v15::VERSION,
                      }, $class;
    if ($params{Version}) { 

lib/Crypt/RSA/ES/PKCS1v15.pm  view on Meta::CPAN

    }
    return $self;
}


sub encrypt { 
    my ($self, %params) = @_; 
    my $key = $params{Key}; my $M = $params{Message} || $params{Plaintext};
    return $self->error ("No Message or Plaintext parameter", \$key, \%params) unless $M;
    return $self->error ($key->errstr, \$M, $key, \%params) unless $key->check;
    my $k = octet_len ($key->n);  debug ("octet_len of modulus: $k");
    my $em = $self->encode ($M, $k-1) || 
        return $self->error ($self->errstr, \$M, $key, \%params);
        debug ("encoded: $em");
    my $m = os2ip ($em);
    my $c = $self->{primitives}->core_encrypt (Plaintext => $m, Key => $key);
    my $ec = i2osp ($c, $k);  debug ("cyphertext: $ec");
    return $ec;
}    


sub decrypt { 
    my ($self, %params) = @_;
    my $key = $params{Key}; my $C = $params{Cyphertext} || $params{Ciphertext};
    return $self->error ("No Cyphertext or Ciphertext parameter", \$key, \%params) unless $C;
    return $self->error ($key->errstr, $key, \%params) unless $key->check;
    my $k = octet_len ($key->n);
    my $c = os2ip ($C);
    debug ("bitsize(c): " . bitsize($c));
    debug ("bitsize(n): " . bitsize($key->n));
    if (bitsize($c) > bitsize($key->n)) { 
        return $self->error ("Decryption error.", $key, \%params) 
    }
    my $m = $self->{primitives}->core_decrypt (Cyphertext => $c, Key => $key) || 
        return $self->error ("Decryption error.", $key, \%params);
    my $em = i2osp ($m, $k-1) || 
        return $self->error ("Decryption error.", $key, \%params);
    my $M; $self->errstrrst;  # reset the errstr
    unless ($M = $self->decode ($em)) { 
        return $self->error ("Decryption error.", $key, \%params) if $self->errstr();

lib/Crypt/RSA/ES/PKCS1v15.pm  view on Meta::CPAN

    my $em = chr(2).$PS.chr(0).$M;
    return $em;
}


sub decode { 
    my ($self, $em) = @_; 

    return $self->error ("Decoding error.") if length($em) < 10;

    debug ("to decode: $em");
    my ($chr0, $chr2) = (chr(0), chr(2));
    my ($ps, $M);
    unless ( ($ps, $M) = $em =~ /^$chr2(.*?)$chr0(.*)$/s ) { 
        return $self->error ("Decoding error.");
    }
    return $self->error ("Decoding error.") if length($ps) < 8; 
    return $M;
}


lib/Crypt/RSA/Primitives.pm  view on Meta::CPAN

use warnings;

## Crypt::RSA::Primitives -- Cryptography and encoding primitives
##                           used by Crypt::RSA.
##
## Copyright (c) 2001, Vipul Ved Prakash.  All rights reserved.
## This code is free software; you can redistribute it and/or modify
## it under the same terms as Perl itself.

use base 'Crypt::RSA::Errorhandler';
use Crypt::RSA::Debug qw(debug);
use Math::BigInt try => 'GMP, Pari';
use Carp;

sub new {
    return bless {}, shift;
}


sub core_encrypt {

    # procedure:
    # c = (m ** e) mod n

    my ($self, %params) = @_;
    my $key = $params{Key};
    $self->error ("Bad key.", \%params, $key) unless $key->check();
    my $plaintext = (defined $params{Message}) ? $params{Message} : $params{Plaintext};
    $plaintext = Math::BigInt->new("$plaintext") if ref($plaintext) ne 'Math::BigInt';
    debug ("pt == $plaintext");

    my $e = $key->e;
    my $n = $key->n;
    return $self->error ("Numeric representation of plaintext is out of bound.",
                          \$plaintext, $key, \%params) if $plaintext > $n;
    my $c = $plaintext->bmodpow($e, $n);
    debug ("ct == $c");
    $n = undef;
    $e = undef;
    return $c;
}


sub core_decrypt {

    # procedure:
    # p = (c ** d) mod n

lib/Crypt/RSA/Primitives.pm  view on Meta::CPAN

        my $dp = $key->dp;
        my $dq = $key->dq;
        my $p2 = ($cyphertext % $p)->bmodpow($dp, $p);
        my $q2 = ($cyphertext % $q)->bmodpow($dq, $q);
        $pt = $p2 + ($p * ((($q2 - $p2) * $u) % $q));
    }
    else {
        $pt = $cyphertext->copy->bmodpow($d, $n);
    }

    debug ("ct == $cyphertext");
    debug ("pt == $pt");
    return $pt;
}


sub core_sign {

    my ($self, %params) = @_;
    $params{Cyphertext} = $params{Message} || $params{Plaintext};
    return $self->core_decrypt (%params);

lib/Crypt/RSA/SS/PKCS1v15.pm  view on Meta::CPAN


## Crypt::RSA::SS:PKCS1v15
##
## Copyright (c) 2001, Vipul Ved Prakash.  All rights reserved.
## This code is free software; you can redistribute it and/or modify
## it under the same terms as Perl itself.

use base 'Crypt::RSA::Errorhandler';
use Crypt::RSA::DataFormat qw(octet_len os2ip i2osp h2osp);
use Crypt::RSA::Primitives;
use Crypt::RSA::Debug qw(debug);
use Digest::SHA qw(sha1 sha224 sha256 sha384 sha512);
use Digest::MD5 qw(md5);
use Digest::MD2 qw(md2);

$Crypt::RSA::SS::PKCS1v15::VERSION = '1.99';

# See if we have a bug-fixed RIPEMD-160.
my $ripe_hash = undef;
if (eval { require Crypt::RIPEMD160; $Crypt::RIPEMD160::VERSION >= 0.05; }) {
  $ripe_hash = sub { my $r=new Crypt::RIPEMD160; $r->add(shift); $r->digest();};

lib/Crypt/RSA/SS/PKCS1v15.pm  view on Meta::CPAN

    my $em = i2osp ($m, $k) ||
        return $self->error ("Invalid signature.", \$M, \$S, $key, \%params);
    my $em1;
    unless ($em1 = $self->encode ($M, $k)) {
        return $self->error ($self->errstr, \$key, \%params, \$M)
            if $self->errstr eq "Message too long.";
        return $self->error ("Modulus too short.", \$key, \%params, \$M)
            if $self->errstr eq "Intended encoded message length too short.";
    }

    debug ("em: $em"); debug ("em1: $em1");

    return 1 if $em eq $em1;
    return $self->error ("Invalid signature.", \$M, \$key, \%params);

}


sub encode {

    my ($self, $M, $emlen) = @_;

lib/Crypt/RSA/SS/PSS.pm  view on Meta::CPAN

## Crypt::RSA::SS:PSS
##
## Copyright (c) 2001, Vipul Ved Prakash.  All rights reserved.
## This code is free software; you can redistribute it and/or modify
## it under the same terms as Perl itself.

use base 'Crypt::RSA::Errorhandler';
use Math::Prime::Util qw/random_bytes/;
use Crypt::RSA::DataFormat qw(octet_len os2ip i2osp octet_xor mgf1);
use Crypt::RSA::Primitives;
use Crypt::RSA::Debug qw(debug);
use Digest::SHA qw(sha1);

$Crypt::RSA::SS::PSS::VERSION = '1.99';

sub new { 
    my ($class, %params) = @_;
    my $self = bless { primitives => new Crypt::RSA::Primitives, 
                       hlen       => 20,
                       VERSION    => $Crypt::RSA::SS::PSS::VERSION,
                     }, $class;

lib/Crypt/RSA/SS/PSS.pm  view on Meta::CPAN

    my ($self, $M, $EM) = @_; 
    my $hlen = $$self{hlen}; 
    my $emlen = length ($EM); 
    return $self->error ("Encoded message too short.", \$M, \$EM) if $emlen < (2*$hlen); 
    my $H = substr $EM, 0, $hlen; 
    my $maskeddb = substr $EM, $hlen; 
    my $dbmask = $self->mgf ($H, $emlen-$hlen);
    my $db = octet_xor ($maskeddb, $dbmask); 
    my $salt = substr $db, 0, $hlen;
    my $PS = substr $db, $hlen; 
    my $check = chr(0) x ($emlen-(2*$hlen)); debug ("PS: $PS");
    return $self->error ("Inconsistent.") unless $check eq $PS; 
    my $H1 = $self->hash ("$salt$M");
    return 1 if $H eq $H1; 
    return $self->error ("Inconsistent.");
} 


sub hash { 
    my ($self, $data) = @_;
    return sha1 ($data);

xt/ripemd160.pl  view on Meta::CPAN

#!/usr/bin/env perl
use warnings;
use strict;

use Crypt::RSA::Key;
use Crypt::RSA::SS::PKCS1v15;
use Crypt::RSA::Key::Public;
use Crypt::RSA::Key::Private;
use Crypt::RSA::Debug qw/debuglevel/;

my $message =  "Fancy this, that we've made a right hash out of things.";

my ($pub, $priv) = Crypt::RSA::Key->new->generate  (
                        Size => 768, 
                        Identity => 'me', 
                        Password => 'oh no you dont', 
                    );

for (qw(RipeMD-160)) { 

xt/sha384.pl  view on Meta::CPAN

#!/usr/bin/env perl
use warnings;
use strict;

use Crypt::RSA::Key;
use Crypt::RSA::SS::PKCS1v15;
use Crypt::RSA::Key::Public;
use Crypt::RSA::Key::Private;
use Crypt::RSA::Debug qw/debuglevel/;
debuglevel(3);

my $message =  "Fancy this, that we've made a right hash out of things.";

my ($pub, $priv) = Crypt::RSA::Key->new->generate  (
                        Size => 768, 
                        Identity => 'me', 
                        Password => 'oh no you dont', 
                    );

for (qw(SHA256 SHA384 SHA512)) { 



( run in 1.361 second using v1.01-cache-2.11-cpan-49f99fa48dc )