Crypt-Rainbow
view release on metacpan or search on metacpan
XSLoader::load('Crypt::Rainbow', $VERSION);
# Preloaded methods go here.
1;
__END__
=head1 NAME
Crypt::Rainbow - Crypt::CBC-compliant block cipher
=head1 ABSTRACT
Rainbow is 128-bit block cipher that accepts a 128-bit key. Designed by
Chang-Hyi Lee and Jeong-Soo Kim of Samsung Advanced Institute of
Technology, Rainbow is similar to the block ciphers Square and Shark.
=head1 SYNOPSIS
use Crypt::Rainbow;
=head1 DESCRIPTION
Rainbow is 128-bit block cipher that accepts a 128-bit key. Designed by
Chang-Hyi Lee and Jeong-Soo Kim of Samsung Advanced Institute of
Technology, Rainbow is similar to the block ciphers Square and Shark.
Rainbow was submitted as an B<AES> candidate but was rejected because
it was deemed not ``complete and proper'', based on the requirements
specified by NIST in the Federal Register on September 12, 1997.
This module supports the Crypt::CBC interface, with the following
functions.
=head2 Functions
=over
=item B<blocksize>
Returns the size (in bytes) of the block (16, in this case).
print "Decryption OK\n" if ($plaintext1 eq $plaintext2);
=head1 EXAMPLE 2
#!/usr/local/bin/perl
use diagnostics;
use strict;
use warnings;
use Crypt::CBC; # CBC automatically loads Rainbow for us
# when using Crypt::CBC, key may be of ANY length
my $key = "0123456789abcdef";
# IV must be exactly 16 bytes long
my $IV = pack "H32", 0;
my $cipher = Crypt::CBC->new({'key' => $key,
'cipher' => 'Rainbow',
'iv' => $IV,
'regenerate_key' => 1,
'padding' => 'standard',
'prepend_iv' => 0
});
# when using Crypt::CBC, plaintext may be of ANY length
my $plaintext1 = "This is a test";
my $ciphertext = $cipher->encrypt($plaintext1);
my $plaintext2 = $cipher->decrypt($ciphertext);
print "Decryption OK\n" if ($plaintext1 eq $plaintext2);
=head1 MORE EXAMPLES
See B<Crypt::CBC> for more examples using CBC mode. See also the
"examples" and "t" directories for some more examples.
=head1 SEE ALSO
B<Crypt::Khazad>, B<Crypt::Misty1>, B<Crypt::Anubis>,
B<Crypt::Noekeon>, B<Crypt::Skipjack>, B<Crypt::Camellia>, and
B<Crypt::Square>.
=head1 COPYRIGHT AND LICENSE
/* #include <assert.h> */
#include <string.h>
/* Defines: */
#define BITSPERBLOCK 128 /* Number of bits in a cipher block */
#define BLOCKSIZE (BITSPERBLOCK/8) /* # bytes in a cipher block */
#define BLOCK_WSIZE (BITSPERBLOCK/32) /* # WORD32's in a cipher block */
#define DIR_ENCRYPT 0 /* Are we encrpyting? */
#define DIR_DECRYPT 1 /* Are we decrpyting? */
#define MODE_ECB 1 /* Are we ciphering in ECB mode? */
#define MODE_CBC 2 /* Are we ciphering in CBC mode? */
#define MODE_CFB1 3 /* Are we ciphering in 1-bit CFB mode? */
#define R_TRUE 1
#define R_FALSE 0
/* Error Codes : */
#define BAD_KEY_DIR -1 /* Key direction is invalid, e.g.,
unknown value */
#define BAD_KEY_MAT -2 /* Key material not of correct
length */
BYTE direction; /* In our case this is negligible, since this
structure involve both enc/dec Keys */
int keyLen; /* Length of the key */
char keyMaterial[MAX_KEY_SIZE+1]; /* Raw key data in ASCII */
BYTE KS_Enc[SCHEDULE_KEY_SIZE]; /* encryption key */
BYTE KS_Dec[SCHEDULE_KEY_SIZE]; /* decryption key */
} keyInstance;
/* The structure for cipher information */
typedef struct cipherInstance {
BYTE mode; /* MODE_ECB, MODE_CBC, or MODE_CFB1 */
BYTE IV[MAX_IV_SIZE]; /* A possible Initialization Vector for
ciphering */
BYTE RED[512]; /* The S-box table RED=[f]|[f^(-1)] */
int blockSize; /* Here It is fixed : 128 */
} cipherInstance;
/* Function protoypes */
int makeKey(keyInstance *key, BYTE direction, int keyLen,
char *keyMaterial);
int inputLen, BYTE *outBuffer)
{
if (cipher == NULL) return BAD_CIPHER_STATE;
if (keys == NULL) return BAD_KEY_INSTANCE;
if (inputLen%128) return BAD_CIPHER_INPUT;
if (cipher->mode == MODE_ECB) {
RB_Enc_ecb (cipher->RED, keys->KS_Enc, input, inputLen, outBuffer);
return R_TRUE;
}
if (cipher->mode == MODE_CBC) {
RB_Enc_cbc (cipher->RED, keys->KS_Enc,cipher->IV, input, inputLen, outBuffer);
return R_TRUE;
}
if (cipher->mode == MODE_CFB1) {
RB_Enc_cfb1 (cipher->RED, keys->KS_Enc,cipher->IV, input, inputLen, outBuffer);
return R_TRUE;
}
return BAD_CIPHER_MODE;
}
}
}
#define BLOCK_XOR(B, A) \
{ \
B[0] ^= A[0];\
B[1] ^= A[1];\
B[2] ^= A[2];\
B[3] ^= A[3];\
}
/* CBC-mode encryption */
static void RB_Enc_cbc (BYTE *table, BYTE *cipherKey, BYTE *iv, BYTE *input, int inputLen,
BYTE *outBuffer)
{
WORD32 tmp[4], data[4], key[2*(R+1)][4];
WORD32 *scan, *tar;
BYTE *SBox;
int i, ib;
SBox = table;
scan = WD(cipherKey);
int inputLen, BYTE *outBuffer)
{
if (cipher == NULL) return BAD_CIPHER_STATE;
if (keys == NULL) return BAD_KEY_INSTANCE;
if (inputLen%128) return BAD_CIPHER_INPUT;
if (cipher->mode == MODE_ECB) {
RB_Dec_ecb (cipher->RED, keys->KS_Dec, input, inputLen, outBuffer);
return R_TRUE;
}
if (cipher->mode == MODE_CBC) {
RB_Dec_cbc (cipher->RED, keys->KS_Dec, cipher->IV, input, inputLen, outBuffer);
return R_TRUE;
}
if (cipher->mode == MODE_CFB1) {
RB_Dec_cfb1 (cipher->RED, keys->KS_Enc,cipher->IV, input, inputLen, outBuffer);
return R_TRUE;
}
return BAD_CIPHER_MODE;
}
/*
#define BLOCK_XOR(B, A) \
{ \
B[0] ^= A[0]; \
B[1] ^= A[1]; \
B[2] ^= A[2]; \
B[3] ^= A[3]; \
}
*/
/* CBC-mode encryption */
static void RB_Dec_cbc (BYTE *table, BYTE *cipherKey, BYTE *iv, BYTE *input, int inputLen,
BYTE *outBuffer)
{
WORD32 tmp[4], data[4], key[2*(R+1)][4], pred[4];
WORD32 *scan, *tar;
BYTE *SBox;
int i, ib;
SBox = table;
scan = WD(cipherKey);
status = cipherInit(&ciph, MODE_ECB, (char *)inV);
if (status != R_TRUE) {
printf("Error Occured!__er_code=%d\n",status);
exit(1);
}
status =blockEncrypt(&ciph, &keys, (BYTE *)ptext, textLen,(BYTE *)ctext);
status =blockDecrypt(&ciph, &keys, (BYTE *)ctext, textLen,(BYTE *)ptext);
if (strncmp(plainSrc,ptext,1024)==0) printf("----ECB : OK!----\n");
else printf("----ECB : FAIL!-----\n");
/* CBC TEST start--- */
status = cipherInit(&ciph, MODE_CBC, (char *)inV);
if (status != R_TRUE) {
printf("Error Occured!__er_code=%d\n",status);
exit(1);
}
status =blockEncrypt(&ciph, &keys, (BYTE *)ptext, textLen,(BYTE *)ctext);
status =blockDecrypt(&ciph, &keys, (BYTE *)ctext, textLen,(BYTE *)ptext);
if (strncmp(plainSrc,ptext,1024)==0) printf("----CBC : OK!----\n");
else printf("----CBC : FAIL!-----\n");
/* CFB1 TEST start--- */
status = cipherInit(&ciph, MODE_CFB1, (char *)inV);
if (status != R_TRUE) {
printf("Error Occured!__er_code=%d\n",status);
exit(1);
}
status =blockEncrypt(&ciph, &keys, (BYTE *)ptext, textLen,(BYTE *)ctext);
status =blockDecrypt(&ciph, &keys, (BYTE *)ctext, textLen,(BYTE *)ptext);
if (strncmp(plainSrc,ptext,1024)==0) printf("----CFB1 : OK!----\n");
for (i=0; i<ITERATIONS; i++) {
status =blockEncrypt(&ciph, &keys, (BYTE *)ptext, textLen,(BYTE *)ctext);
strncpy (ctext, ptext, 1024);
}
elapsed += clock ();
sec = elapsed ? (double) elapsed / CLOCKS_PER_SEC : 1.0;
printf("****ECB_speed.... ");
printf (" %.4f sec(1Mbytes), %.4f Mbytes/sec.\n",
sec, 1./sec);
status = cipherInit(&ciph, MODE_CBC, (char *)inV);
if (status != R_TRUE) {
printf("Error Occured!__er_code=%d\n",status);
exit(1);
}
elapsed = -clock();
for (i=0; i<ITERATIONS; i++) {
status =blockEncrypt(&ciph, &keys, (BYTE *)ptext, textLen,(BYTE *)ctext);
strncpy (ctext, ptext, 1024);
}
elapsed += clock ();
sec = elapsed ? (double) elapsed / CLOCKS_PER_SEC : 1.0;
printf("****CBC_speed.... ");
printf (" %.4f sec(1Mbytes), %.4f Mbytes/sec.\n",
sec, 1./sec);
}
examples/cbc-mode view on Meta::CPAN
#!/usr/local/bin/perl
use diagnostics;
use strict;
use warnings;
use Crypt::CBC; # CBC automatically loads Rainbow for us
my $key = pack "H32", "00112233445566778899aabbccddeeff";
my $IV = pack "H32", "00112233445566778899aabbccddeeff";
my $cipher = Crypt::CBC->new({'key' => $key,
'cipher' => 'Rainbow',
'iv' => $IV,
'regenerate_key' => 1,
'padding' => 'standard',
'prepend_iv' => 0
});
my $plaintext1 = pack "H32", "0123456789abcdeffedcba9876543210";
print "plaintext1 : ", unpack("H*", $plaintext1), "\n";
examples/fileenc view on Meta::CPAN
#!/usr/local/bin/perl
use diagnostics;
use strict;
use warnings;
use Getopt::Long;
use Crypt::CBC; # CBC automatically loads Rainbow for us
my ($encrypt, $decrypt, $help);
GetOptions("encrypt" => \$encrypt, "decrypt" => \$decrypt,
"help" => \$help);
sub usage
{
print "USAGE:\n";
print " $0 --encrypt file1 > outputfile\n";
print " $0 --decrypt file1 > outputfile\n\n";
examples/fileenc view on Meta::CPAN
&usage() if (!$encrypt and !$decrypt);
&usage() if ($help);
my $key = &get_input("password");
# For better security, IV must be randomly
# generated AND must be used ONLY ONCE!
# So, this example is *very* weak!
my $IV = pack "H32", "000102030405060708090a0b0c0d0e0f";
my $cipher = Crypt::CBC->new({'key' => $key,
'cipher' => 'Rainbow',
'iv' => $IV,
'regenerate_key' => 1,
'padding' => 'standard',
'prepend_iv' => 0
});
local $/ = undef; # slurp whole file
chomp $ARGV[0];
open INFILE, $ARGV[0];
examples/pin-generator view on Meta::CPAN
#!/usr/local/bin/perl
use diagnostics;
use strict;
use warnings;
use Crypt::CBC;
use MIME::Base64;
sub get_input
{
my ($message) = @_;
local $| = 1;
local *TTY;
open TTY,"/dev/tty";
my ($tkey1, $tkey2);
system "stty -echo </dev/tty";
examples/pin-generator view on Meta::CPAN
} until $tkey1 eq $tkey2;
system "stty echo </dev/tty";
close TTY;
return $tkey1;
}
my $key = &get_input("username");
my $IV = pack "H32", "000102030405060708090a0b0c0d0e0f";
my $cipher = Crypt::CBC->new({'key' => $key,
'cipher' => 'Rainbow',
'iv' => $IV,
'regenerate_key' => 1,
'padding' => 'standard',
'prepend_iv' => 0
});
my $ciphertext = $cipher->encrypt($key);
print "Your password is\n", encode_base64($ciphertext, ""), "\n";
( run in 1.465 second using v1.01-cache-2.11-cpan-e1769b4cff6 )