Skip to content

Commit

Permalink
give RC4 method Blob and Array candidates
Browse files Browse the repository at this point in the history
  • Loading branch information
dwarring committed Nov 8, 2015
1 parent 4927208 commit 5e37114
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 15 deletions.
29 changes: 18 additions & 11 deletions lib/Crypt/RC4.pm
Expand Up @@ -5,6 +5,8 @@
# Author: Kurt Kincaid (sifukurt@yahoo.com)
# Copyright (c) 2001, Kurt Kincaid
# All Rights Reserved.
# Perl 6 Port: 08-Nov-2015 05:24:25 PM by
# david.warring@gmail.com
#
# This is free software and may be modified and/or
# redistributed under the same terms as Perl itself.
Expand All @@ -16,26 +18,31 @@ class Crypt::RC4 {
has Int $!x;
has Int $!y;

submethod BUILD(Blob :$key!) is default {
multi submethod BUILD(array[uint8] :$key!) is default {
self.BUILD( :key(Blob.new: $key) )
}
multi submethod BUILD(Blob :$key!) is default {
@!state = setup( $key );
$!x = 0;
$!y = 0;
}

method RC4(Blob $message --> Blob) is default {
my uint8 @buf = $message.list;

multi method RC4(@buf is copy --> Array) {
for @buf {
$!x = 0 if ++$!x > 255;
$!y -= 256 if ($!y += @!state[$!x]) > 255;
@!state[$!x, $!y] = @!state[$!y, $!x];
$_ +^= @!state[( @!state[$!x] + @!state[$!y] ) % 256];
}
@buf;
}

Blob.new: @buf;
multi method RC4(Blob $message --> Blob) is default {
my uint8 @buf = $message.list;
Blob.new: self.RC4( @buf );
}

sub setup( Blob $key --> Array ) {
sub setup( $key --> Array ) {
my Int @state = 0..255;
my Int $y = 0;
for 0..255 -> $x {
Expand All @@ -45,8 +52,8 @@ class Crypt::RC4 {
@state;
}

sub RC4(Blob $key, Blob $message --> Blob) is export(:DEFAULT) {
$?CLASS.new( :$key ).RC4( $message );
our sub RC4($key, |c) is export(:DEFAULT) {
$?CLASS.new( :$key ).RC4( |c );
}
}

Expand All @@ -65,16 +72,16 @@ Crypt::RC4 - Perl implementation of the RC4 encryption algorithm
# OO Style
use Crypt::RC4;
my $ref = Crypt::RC4.new( $passphrase );
my $ref = Crypt::RC4.new( :key($passphrase) );
my $encrypted = $ref.RC4( $plaintext );
my $ref2 = Crypt::RC4.new( $passphrase );
my $decrypted = $ref2.RC4( $encrypted );
# process an entire file, one line at a time
# (Warning: Encrypted file leaks line lengths.)
my $ref3 = Crypt::RC4.new( $passphrase );
while for $fh.lines {
my $ref3 = Crypt::RC4.new( :key($passphrase) );
for $fh.lines {
chomp;
say $ref3.RC4($_);
}
Expand Down
18 changes: 14 additions & 4 deletions t/00basic.t
@@ -1,13 +1,23 @@
use Test;
use Crypt::RC4;
# port of test.pl from the original Crypt-RC4 Perl 5 distribution
my Blob $passphrase = Blob.new(0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef);
my Blob $plaintext = Blob.new(0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef);
my uint8 @passphrase = 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef;
my uint8 @plaintext = 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef;
my uint8 @encrypted = RC4( @passphrase, @plaintext );
my uint8 @decrypted = RC4( @passphrase, @encrypted );
my uint8 @expected-enc = 0x75,0xb7,0x87,0x80,0x99,0xe0,0xc5,0x96;

is-deeply @encrypted, @expected-enc, 'array encryption';
is-deeply @decrypted, @plaintext, 'array decryption';

my Blob $passphrase = Blob.new: @passphrase;
my Blob $plaintext = Blob.new: @plaintext;
my Blob $encrypted = RC4( $passphrase, $plaintext );
my Blob $decrypted = RC4( $passphrase, $encrypted );
my Blob $expected-enc = Blob.new: @expected-enc;

is-deeply $encrypted, Blob.new(0x75,0xb7,0x87,0x80,0x99,0xe0,0xc5,0x96), 'encryption';
is-deeply $decrypted, $plaintext, 'decryption';
is-deeply $encrypted, $expected-enc, 'blob encryption';
is-deeply $decrypted, $plaintext, 'blob decryption';

$passphrase = Blob.new(0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef);
$plaintext = Blob.new(0x68,0x65,0x20,0x74,0x69,0x6d,0x65,0x20);
Expand Down

0 comments on commit 5e37114

Please sign in to comment.