#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
#include "const-c.inc"
#define ENCIPHER 0
#define DECIPHER 1
#define L_BLOCK 128
#define BPB 8
#ifndef EOS
#define EOS '\0'
#endif
#ifndef EOL
#define EOL '\n'
#endif
int
m[L_BLOCK];
int
k[L_BLOCK];
int
o[8] = { 7, 6, 2, 1, 5, 0, 3, 4 };
int
pr[8] = { 2, 5, 4, 0, 3, 1, 7, 6 };
int
s0[16] = { 12, 15, 7, 10, 14, 13, 11, 0, 2, 6, 3, 1, 9, 4, 5, 8 };
int
s1[16] = { 7, 2, 14, 9, 3, 11, 0, 4, 12, 13, 1, 10, 6, 15, 8, 5 };
_lucifer(
int
direction){
int
tcbindex, tcbcontrol;
int
round, hi, lo, h_0, h_1;
register
int
bit, temp1;
int
byte, index, v, tr[BPB];
h_0 = 0;
h_1 = 1;
if
( direction == DECIPHER )
tcbcontrol = 8;
else
tcbcontrol = 0;
for
( round=0; round<16; round += 1 )
{
if
( direction == DECIPHER )
tcbcontrol = (tcbcontrol+1) & 0xF;
tcbindex = tcbcontrol;
for
( byte = 0; byte < 8; byte +=1 )
{
lo = (m[(h_1*64)+(BPB*byte)+7])*8
+(m[(h_1*64)+(BPB*byte)+6])*4
+(m[(h_1*64)+(BPB*byte)+5])*2
+(m[(h_1*64)+(BPB*byte)+4]);
hi = (m[(h_1*64)+(BPB*byte)+3])*8
+(m[(h_1*64)+(BPB*byte)+2])*4
+(m[(h_1*64)+(BPB*byte)+1])*2
+(m[(h_1*64)+(BPB*byte)+0]);
v = (s0[lo]+16*s1[hi])*(1-k[(BPB*tcbindex)+byte])
+(s0[hi]+16*s1[lo])*k[(BPB*tcbindex)+byte];
for
( temp1 = 0; temp1 < BPB; temp1 += 1 )
{
tr[temp1] = v & 0x1;
v = v>>1;
}
for
( bit = 0; bit < BPB; bit += 1 )
{
index = (o[bit]+byte) & 0x7;
temp1 = m[(h_0*64)+(BPB*index)+bit]
+k[(BPB*tcbcontrol)+pr[bit]]
+tr[pr[bit]];
m[(h_0*64)+(BPB*index)+bit] = temp1 & 0x1;
}
if
( byte<7 || direction == DECIPHER )
tcbcontrol = (tcbcontrol+1) & 0xF;
}
temp1 = h_0;
h_0 = h_1;
h_1 = temp1;
}
for
( byte = 0; byte < 8; byte += 1 )
{
for
( bit = 0; bit < BPB; bit += 1 )
{
temp1 = m[(BPB*byte)+bit];
m[(BPB*byte)+bit] = m[64+(BPB*byte)+bit];
m[64+(BPB*byte)+bit] = temp1;
}
}
return
;
}
_setkey(
char
*key){
int
i,c,counter;
if
((i =
strlen
(key)) < 16){
for
( ; i < 16; i += 1 )
key[i] = EOS;
}
for
(counter = 0; counter < 16; counter += 1 )
{
c = key[counter] & 0xFF;
for
( i = 0; i < BPB; i += 1 )
{
k[(BPB*counter)+i] = c & 0x1;
c = c>>1;
}
}
}
_preluc(
const
char
* input,SV* buff,
int
direction){
int
counter = 0,output,i,j;
char
c;
for
(j = 0;j <
strlen
(input);j++)
{
c = input[j];
if
( counter == 16 )
{
_lucifer( direction );
for
( counter = 0; counter < 16; counter += 1 )
{
output = 0;
for
( i = BPB-1; i >= 0; i -= 1 )
{
output = (output<<1) + m[(BPB*counter)+i];
}
sv_catpvn(buff,(
const
char
*) &output,1);
}
counter = 0;
}
for
( i = 0; i < BPB; i += 1 )
{
m[(BPB*counter)+i] = c & 0x1;
c = c>>1;
}
counter += 1;
}
for
( ;counter < 16; counter += 1 )
for
( i = 0; i < BPB; i += 1 )
m[(BPB*counter)+i] = 0;
_lucifer( direction );
for
( counter = 0; counter < 16; counter += 1 )
{
output = 0;
for
( i = BPB-1; i >= 0; i -= 1 )
{
output = (output<<1) + m[(BPB*counter)+i];
}
sv_catpvn(buff,(
const
char
*)&output,1);
}
}
MODULE = Crypt::Lucifer PACKAGE = Crypt::Lucifer
INCLUDE:
const
-xs.inc
void
setkey(key)
SV* key;
CODE:
STRLEN key_length;
_setkey((
char
*) SvPV(key,key_length));
OUTPUT:
SV*
luc_encrypt(input)
SV* input
CODE:
RETVAL = newSVpv(
""
,0);
_preluc(sv_pv(input),RETVAL,ENCIPHER);
OUTPUT:
RETVAL
SV*
luc_decrypt(input)
SV* input
CODE:
RETVAL = newSVpv(
""
,0);
_preluc(sv_pv(input),RETVAL,DECIPHER);
OUTPUT:
RETVAL