Crypt-Rijndael_PP

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

Revision history for Perl extension Crypt::Rijndael_PP.

0.04  Thu Aug 16 10:54:01 2001
    - fixed some bugs in the test suite (if Crypt::Rijndael, or Crypt::CBC are not
	  available)
	- added a new CBC Test
	- removed "t" from MANIFEST

0.03  Mit Aug 15 12:41:36 2001
    - added test suite (updated MANIFEST)
	
0.02  Son Aug 12 22:07:45 2001
	- a lot of bugfixes (0.01 did not realy work)

0.01  Sun Oct  8 20:16:02 2000
	- original version; created by h2xs 1.20 with options

README  view on Meta::CPAN

    use "Crypt::Rijndael" where available. This implementation is really
    slow, but I am working on it.

SYNOPSIS
     # Functional style
     use Crypt::Rijndael_PP ':all';

     $key = '1234567890ABCDEF' x 4; # 256bit hex number

     # keysize = 256bit, blocksize = 128bit
     $c_txt = rijndael_encrypt($key, MODE_CBC, $data,  256, 128);
     $p_txt = rijndael_decrypt($key, MODE_CBC, $c_txt, 256, 128);

     # OO style
     # same interface as Crypt::Rijndael
     use Crypt::Rijndael_PP;

     $cipher = Crypt::Rijndael_PP->new( pack('H*', $key), MODE_CBC );

     $c_txt = $cipher->encrypt($data);
     $p_txt = $cipher->decrypt($c_txt);

DESCRIPTION
    This modules shares the OO style interface with "Crypt::Rijndael" from
    Rafael R. Sevilla.

    *   Supported modes: Electronic CodeBook (MODE_ECB) and Cipher Block
        Chaining (MODE_CBC). Please use "Crypt::CBC" for CBC-Mode, as my CBC
        is not compatible with neither "Crypt::CBC" nor "Crypt::Rijndael"
        and it is subject to change in the near future. When using
        "Crypt::CBC" this module is 100% compatible to "Crypt::Rijndael" and
        you can decrypt and encrypt your data with both modules!

    *   Supported keysizes: 128, 192 and 256 (default)

    *   Supported blocksizes: 128 (default), 192 and 256

    If the size of the key does not match the given keysize then the key is
    padded with "0" (hex) or truncated to the right size.

    The last data block is padded with "\0" if it does not match a multiple
    of the blocksize.

    Warnings a raised in both cases.

EXAMPLES
    Using "Crypt::CBC"

     use Crypt::CBC;

     my $key = 'my secret key';
     my $input = 'The answer is 42.';
     my $cipher = new Crypt::CBC($key,'Rijndael_PP');

     my $ciphertext = $cipher->encrypt($input);
     my $plaintext  = $cipher->decrypt($ciphertext);

     # - or -

     #!/usr/local/bin/perl -w
     #
     # Usage: r.pl e "my secret key" < in > out
     #
     use strict;
     use Crypt::CBC;
     die "Usage: $0 mode([ed]) key\n" unless @ARGV == 2;
     my $cipher = new Crypt::CBC($ARGV[1],'Rijndael_PP');
     $cipher->start($ARGV[0]);
     my $buffer;
     while( read(STDIN, $buffer, 1024) ) {
             print $cipher->crypt($buffer);
     }
     print $cipher->finish;

LIMITATIONS
    This implementation is really slow. I'm trying to tweak the performance
    in coming releases.

    CBC-Mode is not yet compatible to "Crypt::Rijndael". But you are advised
    to use "Crypt::CBC" for this mode anyway.

SEE ALSO
    Crypt::Rijndael

    Crypt::CBC

    <http://csrc.nist.gov/encryption/aes/>

COPYRIGHT
    This library is free software; you can redistribute it and/or modify it
    under the same terms as Perl itself.

     Copyright 2001 Christian Lackas
     Copyright 2000 Vincent Rijmen and Joan Daemen

Rijndael_PP.pm  view on Meta::CPAN

use Carp;

use vars qw'$VERSION @EXPORT @EXPORT_OK %EXPORT_TAGS @ISA';
require Exporter;

@ISA = 'Exporter';
$VERSION = 0.05;
@EXPORT_OK = qw(
	blockDecrypt blockEncrypt blockEncryptRound blockDecryptRound
	cipherUpdateRounds cipherInit makeKey
	MODE_ECB MODE_CBC MODE_CFB1
	DIR_ENCRYPT DIR_DECRYPT
);
@EXPORT = qw(rijndael_encrypt rijndael_decrypt);
%EXPORT_TAGS = (
	all => [@EXPORT_OK,@EXPORT],
	modes => [qw(MODE_ECB MODE_CBC MODE_CFB1)],
	directions => [qw(DIR_ENCRYPT DIR_DECRYPT)],
	CAPI => [qw(cipherInit makeKey blockDecrypt blockEncrypt)]
);


# boxes-ref.dat
use constant Logtable => [
  0,   0,  25,   1,  50,   2,  26, 198,  75, 199,  27, 104,  51, 238, 223,   3, 
100,   4, 224,  14,  52, 141, 129, 239,  76, 113,   8, 200, 248, 105,  28, 193, 
125, 194,  29, 181, 249, 185,  39, 106,  77, 228, 166, 114, 154, 201,   9, 120, 

Rijndael_PP.pm  view on Meta::CPAN


##################################
# api-ref.c

# define     DIR_ENCRYPT     0    /*  Are we encrpyting?  */
sub DIR_ENCRYPT() { 0 }
# define     DIR_DECRYPT     1    /*  Are we decrpyting?  */
sub DIR_DECRYPT() { 1 }
# define     MODE_ECB        1    /*  Are we ciphering in ECB mode?   */
sub MODE_ECB() { 1 }
# define     MODE_CBC        2    /*  Are we ciphering in CBC mode?   */
sub MODE_CBC() { 2 }
# define     MODE_CFB1       3    /*  Are we ciphering in 1-bit CFB mode? */
sub MODE_CFB1() { 3 }
# define     TRUE            1
sub TRUE() { 1 }
# define     FALSE           0
sub FALSE() { 0 }
# define	BITSPERBLOCK		128		/* Default number of bits in a cipher block */
sub BITSPERBLOCK() { 128 }

# /*  Error Codes - CHANGE POSSIBLE: inclusion of additional error codes  */

Rijndael_PP.pm  view on Meta::CPAN

#{
#	int i, j, t;

sub cipherInit($$;$) {
	
	my ($cipher, $mode, $IV) = @_;
	
	my $i;

#	
#	if ((mode == MODE_ECB) || (mode == MODE_CBC) || (mode == MODE_CFB1)) {
#		cipher->mode = mode;
#	} else {
#		return BAD_CIPHER_MODE;
#	}

	if ($mode == MODE_ECB or $mode == MODE_CBC or $mode == MODE_CFB1) {
		$cipher->{mode} = $mode
	} else {
		die "BAD_CIPHER_MODE";
	}

#	
#	if (IV != NULL) {
#		for(i = 0; i < cipher->blockLen/8; i++) {		
#			t = IV[2*i];
#			if ((t >= '0') && (t <= '9')) j = (t - '0') << 4;

Rijndael_PP.pm  view on Meta::CPAN

#                (key->keyLen != 128 && key->keyLen != 192 && key->keyLen != 256)) {
#                return BAD_KEY_MAT;
#        }

	if (not defined $key or $key->{direction} != DIR_ENCRYPT or
	    ($key->{keyLen} != 128 and $key->{keyLen} != 192 and $key->{keyLen} != 256)) {
		die "BAD_KEY_MAT"
	}

#        if (cipher == NULL ||
#                (cipher->mode != MODE_ECB && cipher->mode != MODE_CBC && cipher->mode != MODE_CFB1) ||
#                (cipher->blockLen != 128 && cipher->blockLen != 192 && cipher->blockLen != 256)) {
#                return BAD_CIPHER_STATE;
#        }
	
	if (not defined $cipher or ($cipher->{mode} != MODE_ECB and $cipher->{mode} != MODE_CBC and $cipher->{mode} != MODE_CFB1) or
	    ($cipher->{blockLen} != 128 and $cipher->{blockLen} != 192 and $cipher->{blockLen} != 256)) {
		die "BAD_CIPHER_STATE";
	}
	
#
#
#	numBlocks = inputLen/cipher->blockLen;

	$numBlocks = $inputLen/$cipher->{blockLen};

Rijndael_PP.pm  view on Meta::CPAN

			rijndaelEncrypt(@block, $key->{keyLen}, $cipher->{blockLen}, $key->{keySched});
			for $j (0..$cipher->{blockLen}/32-1) {
				for $t (0..3) {
					$outBuffer->[4*$j+$t] = $block[$t][$j];
				}
			}
		}
	}

#		
#	case MODE_CBC:
#		for (j = 0; j < cipher->blockLen/32; j++) {
#			for(t = 0; t < 4; t++)
#			/* parse initial value into rectangular array */
#					block[t][j] = cipher->IV[t+4*j] & 0xFF;
#			}
#		for (i = 0; i < numBlocks; i++) {
#			for (j = 0; j < cipher->blockLen/32; j++) {
#				for(t = 0; t < 4; t++)
#				/* parse input stream into rectangular array and exor with 
#				   IV or the previous ciphertext */

Rijndael_PP.pm  view on Meta::CPAN

#			}
#			rijndaelEncrypt (block, key->keyLen, cipher->blockLen, key->keySched);
#			for (j = 0; j < cipher->blockLen/32; j++) {
#				/* parse rectangular array into output ciphertext bytes */
#				for(t = 0; t < 4; t++)
#					outBuffer[4*j+t] = (BYTE) block[t][j];
#			}
#		}
#		break;

	elsif ($cipher->{mode} == MODE_CBC) {
		for $j (0..$cipher->{blockLen}/32-1) {
			for $t (0..3) {
				$block[$t][$j] = $cipher->{IV}[$t+4*$j] & 0xFF
			}
		}
		for $i (0..$numBlocks-1) {
			for $j (0..$cipher->{blockLen}/32-1) {
				for $t (0..3) {
					$block[$t][$j] ^= $input->[4*$j+$t] & 0xFF;
				}

Rijndael_PP.pm  view on Meta::CPAN

#                (key->keyLen != 128 && key->keyLen != 192 && key->keyLen != 256)) {
#                return BAD_KEY_MAT;
#        }

	if (not defined $key or $key->{direction} != DIR_DECRYPT or
		($key->{keyLen} != 128 and $key->{keyLen} != 192 and $key->{keyLen} != 256)) {
			die "BAD_KEY_MAT";
	}

#        if (cipher == NULL ||
#                (cipher->mode != MODE_ECB && cipher->mode != MODE_CBC && cipher->mode != MODE_CFB1) ||
#                (cipher->blockLen != 128 && cipher->blockLen != 192 && cipher->blockLen != 256)) {
#                return BAD_CIPHER_STATE;
#        }

	if (not defined $cipher or ($cipher->{mode} != MODE_ECB and $cipher->{mode} != MODE_CBC and $cipher->{mode} != MODE_CFB1) or
	    ($cipher->{blockLen} != 128 and $cipher->{blockLen} != 192 and $cipher->{blockLen} != 256)) {
		die "BAD_CIPHER_STATE";
	}

#	
#
#	numBlocks = inputLen/cipher->blockLen;

	$numBlocks = $inputLen / $cipher->{blockLen};

Rijndael_PP.pm  view on Meta::CPAN

			for $j (0..$cipher->{blockLen}/32-1) {
				for $t (0..3) {
					$outBuffer->[4*$j+$t] = $block[$t][$j];
				}
			}
		}
	}


#		
#	case MODE_CBC:
#		/* first block */
#		for (j = 0; j < cipher->blockLen/32; j++) {
#			for(t = 0; t < 4; t++)
#			/* parse input stream into rectangular array */
#				block[t][j] = input[4*j+t] & 0xFF;
#		}

	elsif ($cipher->{mode} == MODE_CBC) {
		for $j (0..$cipher->{blockLen}/32-1) {
			for $t (0..3) {
				$block[$t][$j] = $input->[$t+4*$j] & 0xFF
			}
		}


#		rijndaelDecrypt (block, key->keyLen, cipher->blockLen, key->keySched);

		rijndaelDecrypt(@block, $key->{keyLen}, $cipher->{blockLen}, $key->{keySched});

Rijndael_PP.pm  view on Meta::CPAN

		die $@ if $@;
		$out .= pack 'C'x($blocksize/8), @$tmp;
	}
	
	return unless defined $out;
	$out;
}

####################################################
# 
# Interface for Crypt::CBC
#
####################################################

# return keysize in bytes
sub keysize { 
	my $self = shift;
	if (defined $self and ref $self and defined $self->{keysize}) {
		return $self->{keysize}/8
	}
	return $DEFAULT_KEYSIZE/8

Rijndael_PP.pm  view on Meta::CPAN

is really slow, but I am working on it.

=head1 SYNOPSIS

 # Functional style
 use Crypt::Rijndael_PP ':all';

 $key = '1234567890ABCDEF' x 4; # 256bit hex number

 # keysize = 256bit, blocksize = 128bit
 $c_txt = rijndael_encrypt($key, MODE_CBC, $data,  256, 128);
 $p_txt = rijndael_decrypt($key, MODE_CBC, $c_txt, 256, 128);


 # OO style
 # same interface as Crypt::Rijndael
 use Crypt::Rijndael_PP;

 $cipher = Crypt::Rijndael_PP->new( pack('H*', $key), MODE_CBC );

 $c_txt = $cipher->encrypt($data);
 $p_txt = $cipher->decrypt($c_txt);

=head1 DESCRIPTION

This modules shares the OO style interface with C<Crypt::Rijndael>
from Rafael R. Sevilla.

=over 4

=item

Supported modes: Electronic CodeBook (MODE_ECB) and Cipher Block Chaining
(MODE_CBC). Please use C<Crypt::CBC> for CBC-Mode, as my CBC is not compatible
with neither C<Crypt::CBC> nor C<Crypt::Rijndael> and it is subject to change
in the near future. When using C<Crypt::CBC> this module is 100% compatible to
C<Crypt::Rijndael> and you can decrypt and encrypt your data with both modules!

=item

Supported keysizes: 128, 192 and 256 (default)

=item

Supported blocksizes: 128 (default), 192 and 256

Rijndael_PP.pm  view on Meta::CPAN

keysize then the key is padded with "0" (hex) or
truncated to the right size.

The last data block is padded with "\0" if it does not match
a multiple of the blocksize.

Warnings a raised in both cases.

=head1 EXAMPLES

Using C<Crypt::CBC>

 use Crypt::CBC;

 my $key = 'my secret key';
 my $input = 'The answer is 42.';
 my $cipher = new Crypt::CBC($key,'Rijndael_PP');

 my $ciphertext = $cipher->encrypt($input);
 my $plaintext  = $cipher->decrypt($ciphertext);


 # - or -

 #!/usr/local/bin/perl -w
 #
 # Usage: r.pl e "my secret key" < in > out
 #
 use strict;
 use Crypt::CBC;
 die "Usage: $0 mode([ed]) key\n" unless @ARGV == 2;
 my $cipher = new Crypt::CBC($ARGV[1],'Rijndael_PP');
 $cipher->start($ARGV[0]);
 my $buffer;
 while( read(STDIN, $buffer, 1024) ) {
	 print $cipher->crypt($buffer);
 }
 print $cipher->finish;


=head1 LIMITATIONS

This implementation is really slow. I'm trying to tweak the
performance in coming releases.

CBC-Mode is not yet compatible to C<Crypt::Rijndael>. But you are
advised to use C<Crypt::CBC> for this mode anyway.

=head1 SEE ALSO

L<Crypt::Rijndael>

L<Crypt::CBC>

L<http://csrc.nist.gov/encryption/aes/>

=head1 COPYRIGHT

This library is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.

 Copyright 2001 Christian Lackas
 Copyright 2000 Vincent Rijmen and Joan Daemen

TODO  view on Meta::CPAN

- bug in CBC mode with multitple blocks
  maybe its just incompatible to Crypt::Rijndael
- implementation of a faster version (fast-alg)
- known answer test (reference test suite)

comp.pl  view on Meta::CPAN

use Crypt::Rijndael;

my ($count,$bytes) = 0;

my $mult = 10;

sub result { print "\n$count rounds\n$bytes Bytes\n"; exit; };

$SIG{INT} = \&result;

my $mode = shift || 'CBC';
my $key_size = 256;
my $plain_size = 128;

my %MODE = (
	ECB => {
		c_xs => Crypt::Rijndael::MODE_ECB,
		c_pl => Crypt::Rijndael_PP::MODE_ECB
	},
	CBC => {
		c_xs => Crypt::Rijndael::MODE_CBC,
		c_pl => Crypt::Rijndael_PP::MODE_CBC
	}
);

$|++;
while(1) {
	my $key = gen($key_size);
	my $c_xs = Crypt::Rijndael->new($key, $MODE{$mode}{c_xs});
	my $c_pl = Crypt::Rijndael_PP->new($key, $MODE{$mode}{c_pl});
			
	for (1..10) {

t/02rnd_hin_u_her.t  view on Meta::CPAN

	for (1..10) {
		my $block = gen(128 * $_);
		my $x = $i*20 + 2*$_ -1;
		{
			my $cipher = rijndael_encrypt($key, Crypt::Rijndael_PP::MODE_ECB, $block, 256, 128);
			my $plain  = rijndael_decrypt($key, Crypt::Rijndael_PP::MODE_ECB, $cipher, 256, 128);
			print $block eq $plain ? "ok $x\n" : "not ok $x # random data\n";
		}
		{
			++$x;
			my $cipher = rijndael_encrypt($key, Crypt::Rijndael_PP::MODE_CBC, $block, 256, 128);
			my $plain  = rijndael_decrypt($key, Crypt::Rijndael_PP::MODE_CBC, $cipher, 256, 128);
			print $block eq $plain ? "ok $x\n" : "not ok $x # random data\n";
		}
	}
}

sub gen {
	my $size = shift;
	my $res;
	while ($size > 0) {
		$size -= 8;

t/03compxs.t  view on Meta::CPAN

	exit 0;
} else {
	print "ok 1\n";
}

my %MODE = (
	ECB => {
		c_xs => &Crypt::Rijndael::MODE_ECB,
		c_pl => Crypt::Rijndael_PP::MODE_ECB
	},
	CBC => {
		c_xs => &Crypt::Rijndael::MODE_CBC,
		c_pl => Crypt::Rijndael_PP::MODE_CBC
	}
);

my $mode = 'ECB';
my $keysize = 256;
my $plainsize = 128;

for my $a (0..9) {
	my $key = gen($keysize);
	my $c_xs = Crypt::Rijndael->new($key, $MODE{$mode}{c_xs});

t/04cbc.t  view on Meta::CPAN

use strict;
use Crypt::Rijndael_PP;


print "1..100\n";

$|++;

for my $a (0..9) {
	my $key = gen(256);
	my $c = new Crypt::Rijndael_PP($key, Crypt::Rijndael_PP::MODE_CBC);
	for (0..9) {
		my $x = $a*10 + $_ + 1;
		my $data = gen($Crypt::Rijndael_PP::DEFAULT_BLOCKSIZE * int(rand(16)+1));
		my $cipher = $c->encrypt($data);
		my $plain = $c->decrypt($cipher);
		print $plain eq $data ? "ok $x\n" : "not ok $x\n";
	}
}

sub gen {



( run in 1.010 second using v1.01-cache-2.11-cpan-e1769b4cff6 )