Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Crypt::CipherSaber

by chromatic (Archbishop)
on Nov 28, 2000 at 05:12 UTC ( [id://43583]=perlcraft: print w/replies, xml ) Need Help??

   1: ############################################################
   2: # Here's a module I'm packaging up for the CPAN.  
   3: # It implements the simple-yet-effective CipherSaber 
   4: # encryption scheme, levels one and two.  Instructions are 
   5: # in the POD.
   6: #
   7: # If you have time, I'd appreciate a review and any 
   8: # recommendations.  Thanks in advance.
   9: ############################################################
  10: package Crypt::CipherSaber;
  11: 
  12: use strict;
  13: use vars qw($VERSION);
  14: 
  15: $VERSION = '0.02';
  16: 
  17: sub new {
  18: 	my $class = shift;
  19: 	my $key = shift;
  20: 
  21: 	# CS-2 shuffles the state array N times, CS-1 once
  22: 	my $N = shift;
  23: 	if (!(defined $N) or ($N < 1)) {
  24: 		$N = 1;
  25: 	}
  26: 	my $self = [ $key, [ 0 .. 255 ], $N ];
  27: 	bless($self, $class);
  28: }
  29: 
  30: sub crypt {
  31: 	my $self = shift;
  32: 	my $iv = shift;
  33: 	$self->_setup_key($iv);
  34: 	my $message = shift;
  35: 	my $state = $self->[1];
  36: 	my ($i, $j, $n) = (0, 0, 0);
  37: 	my $output;
  38: 	for (0 .. (length($message) -1 )) {
  39: 		$i++;
  40: 		$i %= 256;
  41: 		$j += $state->[$i];
  42: 		$j %= 256;
  43: 		@$state[$i, $j] = @$state[$j, $i];
  44: 		$n = $state->[$i] + $state->[$j];
  45: 		$n %= 256;
  46: 		$output .= chr( $state->[$n] ^ ord(substr($message, $_, 1)) );
  47: 	}
  48: 	$self->[1] = [ 0 .. 255 ];
  49: 	return $output;
  50: }
  51: 
  52: sub encrypt {
  53: 	my $self = shift;
  54: 	my $iv = $self->_gen_iv();
  55: 	return $iv . $self->crypt($iv, @_);
  56: }
  57: 
  58: sub decrypt {
  59: 	my $self = shift;
  60: 	my $message = shift;
  61: 	my $iv = substr($message, 0, 10, '');
  62: 	return $self->crypt($iv, $message);
  63: }
  64: 
  65: ###################
  66: #
  67: # PRIVATE METHODS
  68: #
  69: ###################
  70: sub _gen_iv {
  71: 	my $iv;
  72: 	$iv .= chr(int(rand(255))) for (1 .. 10);
  73: 	return $iv;
  74: }
  75: 
  76: sub _setup_key {
  77: 	my $self = shift;
  78: 	my $key = $self->[0] . shift;
  79: 	my @key = map { ord } split(//, $key);
  80: 	my $state = $self->[1];
  81: 	my $j = 0;
  82: 	my $length = @key;
  83: 
  84: 	# repeat N times, for CS-2
  85: 	for (1 .. $self->[2]) {
  86: 		for my $i (0 .. 255) {
  87: 			$j += ($state->[$i] + ($key[$i % $length]));
  88: 			$j %= 256;
  89: 			(@$state[$i, $j]) = (@$state[$j, $i]);
  90: 		}
  91: 	}
  92: }
  93: 
  94: 1;
  95: 
  96: __END__
  97: 
  98: =head1 NAME
  99: 
 100: Crypt::CipherSaber - Perl module implementing CipherSaber encryption.
 101: 
 102: =head1 SYNOPSIS
 103: 
 104:   use Crypt::CipherSaber;
 105:   my $cs = Crypt::CipherSaber->new('my pathetic secret key');
 106: 
 107:   my $coded = $cs->encrypt('Here is a secret message for you');
 108:   my $decoded = $cs->decrypt($coded);
 109: 
 110: =head1 DESCRIPTION
 111: 
 112: The Crypt::CipherSaber module implements CipherSaber encryption, described at
 113: http://ciphersaber.gurus.com.  It is simple, fairly speedy, and relatively
 114: secure algorithm based on RC4.
 115: 
 116: Encryption and decryption are done based on a secret key, which must be shared
 117: with all intended recipients of a message.
 118: 
 119: =head1 METHODS
 120: 
 121: =item new($key, $N)
 122: 
 123: Initialize a new Crypt::CipherSaber object.  $key, the key used to encrypt or to
 124: decrypt messages is required.  $N is optional.  If provided and greater than
 125: one, it will implement CipherSaber-2 encryption (slightly slower but more
 126: secure).  If not specified, or equal to 1, the module defaults to CipherSaber-1
 127: encryption.  $N must be a positive integer greater than one.
 128: 
 129: =item encrypt($message)
 130: 
 131: Encrypt a message.  This uses the key stored in the current Crypt::CipherSaber 
 132: object.  It will generate a 10-byte random IV (Initialization Vector) 
 133: automatically, as defined in the RC4 specification.  This returns a string 
 134: containing the encrypted message.
 135: 
 136: Note that the encrypted message may contain unprintable characters, as it uses
 137: the extended ASCII character set (valid numbers 0 through 255).
 138: 
 139: =item decrypt($message)
 140: 
 141: Decrypt a message.  For the curious, the first ten bytes of an encrypted
 142: message are the IV, so this must strip it off first.  This returns a string
 143: containing the decrypted message.
 144: 
 145: The decrypted message may also contain unprintable characters, as the
 146: CipherSaber encryption scheme can handle binary files with fair ease.  If this
 147: is important to you, be sure to treat the results correctly.
 148: 
 149: =item crypt($iv, $message)
 150: 
 151: If you wish to generate the IV with a more cryptographically secure random
 152: string (at least compared to Perl's builtin rand() function), you may do so
 153: separately, passing it to this method directly.  The IV must be a ten-byte
 154: string consisting of characters from the extended ASCII set.
 155: 
 156: This is generally only useful for encryption, although you may extract the
 157: first ten characters of an encrypted message and pass them in yourself.  You
 158: might as well call B<decrypt()>, though.
 159: 
 160: =head1 AUTHOR
 161: 
 162: chromatic <chromatic@wgz.org>
 163: 
 164: thanks to jlp for testing and moral support, and to the fine 
 165: folks at http://perlmonks.org
 166: 
 167: =head1 SEE ALSO
 168: 
 169: the CipherSaber home page at http://ciphersaber.gurus.com
 170: 
 171: perl(1), rand().
 172: 
 173: =cut

Replies are listed 'Best First'.
Re (tilly): Crypt::CipherSaber
by tilly (Archbishop) on Nov 28, 2000 at 09:15 UTC
    Nice.

    I would suggest that your documentation should mention some modules like Math::TrulyRandom (and on some operating systems you can look for /dev/random) that can be used for producing the seeds. Also you may want to mention the fact that if you take virtually and supply of large somewhat random data (say from /dev/mem), compress it, encrypt that (even with a bad algorithm), then you will get a very large amount of very good random data for the seed. On systems which generate a lot of random numbers, you may run out of entropy for approaches based on things like timing data...

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (8)
As of 2024-04-16 18:25 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found