| 
#!/usr/local/bin/perl 
my $i; 
 
local @PC_1_TBL = ( 
        57,49,41,33,25,17, 9, 1,58,50,41,34,26,18, 
        10, 2,59,51,43,35,27,19,11, 3,60,52,44,36, 
        63,55,47,39,31,23,15, 7,62,54,46,38,30,22, 
        14, 6,61,53,45,37,29,21,13, 5,28,20,12, 4); 
#for($i=0;$i<=$#PC_1_TBL;$i++) { 
#        print "passIn[$PC_1_TBL[$i]],\n"; 
#} 
 
local @PC_2_TBL = ( 
        14,14,11,24, 1, 5, 3,28,15, 6,21,10,23,19,12, 4, 
        26, 8,16, 7,27,20,13, 2,41,52,31,37,47, 5,30,40, 
        51,45,33,48,44,49,39,56,34,53,46,42,50,36,29,32); 
#for($i=0;$i<=$#PC_2_TBL;$i++) { 
#        print "passOut[$PC_2_TBL[$i]],\n"; 
#} 
 
local @KS_Count = ( 
         1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1); 
local @KS_Count_1 = ( 
         0,1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, 1); 
 
local @IP_TBL = ( 
        58,50,42,34,26,18,10, 2,60,52,44,36,28,20,12, 4, 
        62,54,46,38,30,22,14, 6,64,56,48,40,32,24,16, 8, 
        57,49,41,33,25,17, 9, 1,59,51,43,35,27,19,11, 3, 
        61,53,45,37,29,21,13, 5,63,55,47,39,31,23,15, 7); 
#for($i=0;$i<=$#IP_TBL;$i++) { 
#        print "strIn[$IP_TBL[$i]],\n"; 
#} 
#local @IP1_TBL = (); 
#for($i=0;$i<=$#IP_TBL;$i++) { 
#        $IP1_TBL[$IP_TBL[$i]-1]= $i +1; 
#} 
#for($i=0;$i<=$#IP1_TBL;$i++) { 
#        print "strtmp[$IP1_TBL[$i]],\n"; 
#} 
 
local @E_Table_TBL = ( 
        32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9,10,11, 
        12,13,12,13,14,15,16,17,16,17,18,19,20,21,22,23, 
        22,23,24,25,24,25,26,27,28,29,28,29,30,31,32, 1); 
#for($i=0;$i<=$#E_Table_TBL;$i++) { 
#        print "In[$E_Table_TBL[$i]],\n"; 
#} 
 
local @S_Box_TBL1 = ( 
        14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7, 
         0,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8, 
         4, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0, 
        15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13); 
local @S_Box_TBL2 = ( 
        15, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10, 
         3,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5, 
         0,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15, 
        13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9); 
local @S_Box_TBL3 = ( 
        10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8, 
        13, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1, 
        13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7, 
         1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12); 
local @S_Box_TBL4 = ( 
         7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15, 
        13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9, 
        10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4, 
         3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14); 
local @S_Box_TBL5 = ( 
         3,12, 4, 1, 7,10, 1, 6, 8, 5, 3,15,13, 0,14, 9, 
        14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6, 
         4, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14, 
        11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3); 
local @S_Box_TBL6 = ( 
         4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1, 
        13, 0,11, 7, 4, 9, 1,10,14, 3, 5,12, 2,15, 8, 6, 
         1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2, 
         6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12); 
local @S_Box_TBL7 = ( 
        12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11, 
        10,15, 4, 2, 7,12, 9, 5, 6, 1,13,14, 0,11, 3, 8, 
         9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6, 
         4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13); 
local @S_Box_TBL8 = ( 
        13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7, 
         1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2, 
         7, 1, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8, 
         2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11); 
 
local @P_Table_TBL = ( 
        16, 7,20,21,29,12,28,17, 1,15,23,26, 5,18,31,10, 
         2, 8,24,14,32,27, 3, 9,19,13,30, 6,22,11, 4,25); 
#for($i=0;$i<=$#P_Table_TBL;$i++) { 
#        print "In[$P_Table_TBL[$i]],\n"; 
#} 
 
my $passwd_1_line = "0123456789abcdef"; 
my $passwd_2_line = "ffeeddccbbaa9988"; 
my $string_1_line = "0011223344556677"; 
my @passwd_1 = &hexLine2binArray($passwd_1_line); 
my @passwd_2 = &hexLine2binArray($passwd_2_line); 
my @string_1 = &hexLine2binArray($string_1_line); 
my @string_2=(); 
my @string_3=(); 
my @string_4=(); 
my @string_5=(); 
my @string_6=(); 
my @string_7=(); 
my $aline=(); 
 
@string_2 = &DES(1,@passwd_1,@string_1); 
@string_3 = &DES(0,@passwd_2,@string_2); 
@string_4 = &DES(1,@passwd_1,@string_3); 
@string_5 = &DES(0,@passwd_1,@string_4); 
@string_6 = &DES(1,@passwd_2,@string_5); 
@string_7 = &DES(0,@passwd_1,@string_6); 
print "K1:$passwd_1_line\n\n"; 
print "K2:$passwd_2_line\n\n"; 
print "S1:$string_1_line\n\n"; 
print "S1:$#string_1 bit : ".join("",@string_1)."\n"; 
print "    change: "; 
for($i=0;$i<=63;$i++) { 
        if( $string_1[$i] == $string_7[$i] ) { 
                print " "; 
        } 
        else {        print "v"; } 
} 
print "\n"; 
print "S7:$#string_7 bit : ".join("",@string_7)."\n"; 
print "    change: "; 
for($i=0;$i<=63;$i++) { 
        if( $string_1[$i] == $string_4[$i] ) { 
                print " "; 
        } 
        else {        print "v"; } 
} 
print "\n"; 
print "S4:$#string_4 bit : ".join("",@string_4)."\n"; 
$aline = &binArray2hexLine(@string_4); 
print "S4:$aline\n"; 
for($i=0;$i<=63;$i++) { 
        if( $string_1[$i] != $string_7[$i] ) { 
                print "Compare Error Between S1 and S7 in ${i}th bit => $string_1[$i] : $string_7[$i]\n"; 
        } 
} 
 
sub DES { 
        my @IN = @_; 
        my $flag; 
        my @passwd=(); 
        my @string=(); 
        my @passwd_K1=(); 
        my @passwd_C0=(); 
        my @passwd_D0=(); 
        my @string_L0=(); 
        my @string_R0=(); 
        my @passwd_C1=(); 
        my @passwd_D1=(); 
        my @string_L1=(); 
        my @string_R1=(); 
        my $i; 
        my $aline; 
 
        ($flag, @passwd[0..63],   @string[0..63]   ) = @IN; 
        (@passwd_C0[0..27],@passwd_D0[0..27]) = &PC_1(@passwd); 
        (@string_L0[0..31],@string_R0[0..31]) = &IP(@string); 
 
         
        $aline = &binArray2hexLine(@passwd_C0); 
        print "ASC11:C0:$#passwd_C0 $i : $aline\n"; 
        $aline = &binArray2hexLine(@passwd_D0); 
        print "ASC11:D0:$#passwd_D0 $i : $aline\n"; 
        $aline = &binArray2hexLine(@string_R0); 
        print "ASC11:R0:$#string_R0 $i : $aline\n"; 
        $aline = &binArray2hexLine(@string_L0); 
        print "ASC11:L0:$#string_L0 $i : $aline\n"; 
 
        #print ". ".join("",@passwd_C0)." ".join("",@passwd_D0)."\n"; 
        for($i=0;$i<16;$i++) { 
                (@passwd_K1[0..47],@passwd_C1[0..27],@passwd_D1[0..27]) = 
                        &passwd_bl($flag,$i,@passwd_C0,@passwd_D0); 
 
                (@string_L1[0..31],@string_R1[0..31]) = 
                        &string_bl(@passwd_K1,@string_L0,@string_R0); 
 
                @passwd_C0 = @passwd_C1; 
                @passwd_D0 = @passwd_D1; 
 
                @string_L0 = @string_L1; 
                @string_R0 = @string_R1; 
 
         
        #print ":K1:$i $#passwd_K1 $i : ".join("",@passwd_K1)."\n"; 
        #print ":R0:$i $#string_R0 $i : ".join("",@string_R0)."\n"; 
        #print ":L0:$i $#string_L0 $i : ".join("",@string_L0)."\n"; 
                @string = (@string_L0,@string_R0); 
        } 
        #print ":Ro:$#string_R0 $i : ".join("",@string_R0)."\n"; 
        #print ":Lo:$#string_L0 $i : ".join("",@string_L0)."\n"; 
 
        @string = &IP_1(@string_R0[0..31],@string_L0[0..31]); 
        #print "$#string IP1 : ".join("",@string)."\n"; 
        return @string; 
         
} 
sub PC_1 { 
        my @IN = @_; 
        my @OUT = (); 
        my $i; 
        #print "$#IN PC1_In : ".join("",@IN)."\n"; 
        for($i=0;$i<=$#PC_1_TBL;$i++) { 
                $OUT[$i]=$IN[$PC_1_TBL[$i] - 1]; 
        } 
        #print "$#OUT PC1 : ".join("",@OUT)."\n"; 
        return @OUT; 
} 
sub passwd_bl { 
        my @IN = @_; 
        my $flag; 
        my $round; 
        my @passwd_C0=(); 
        my @passwd_D0=(); 
        my @passwd_C1=(); 
        my @passwd_D1=(); 
        my @passwd_K1=(); 
        my $i; 
 
        ($flag,$round,@passwd_C0[0..27],@passwd_D0[0..27]) = @IN; 
        #print "$flag $round "; 
        if( $flag ) { 
                @passwd_C1[0..27]= &Left_Shift($KS_Count[$round],@passwd_C0); 
                @passwd_D1[0..27]= &Left_Shift($KS_Count[$round],@passwd_D0); 
        } 
        else { 
                @passwd_C1[0..27]= &Right_Shift($KS_Count_1[$round],@passwd_C0); 
                @passwd_D1[0..27]= &Right_Shift($KS_Count_1[$round],@passwd_D0); 
        } 
        @passwd_K1[0..47] = &PC_2(@passwd_C1,@passwd_D1); 
 
        return (@passwd_K1,@passwd_C1,@passwd_D1);         
} 
sub Left_Shift { 
        my ($count,@IN) = @_; 
        my $i; 
        #print "$#IN LS1 : ".join("",@IN)."\n"; 
        for($i=0;$i<$count;$i++) { 
                $IN[$#IN + 1] = $IN[0]; 
                shift(@IN); 
        } 
        #print "$#IN LS2 : ".join("",@IN)."\n"; 
        return @IN; 
} 
sub Right_Shift { 
        my ($count,@IN) = @_; 
        my $i; 
        #print "$#IN RS1 : ".join("",@IN)."\n"; 
        for($i=0;$i<$count;$i++) { 
                (@IN) = ($IN[27],@IN); 
        } 
        #print "$#IN RS2 : ".join("",@IN)."\n"; 
        return @IN; 
} 
sub PC_2 { 
        my @IN = @_; 
        my @OUT = (); 
        my $i; 
        for($i=0;$i<=$#PC_2_TBL;$i++) { 
                $OUT[$i]=$IN[$PC_2_TBL[$i]-1]; 
        } 
        return @OUT; 
} 
sub IP { 
        my @IN = @_; 
        my @OUT = (); 
        my $i; 
        for($i=0;$i<=$#IP_TBL;$i++) { 
                $OUT[$i] = $IN[$IP_TBL[$i]-1]; 
        } 
        return @OUT; 
} 
sub IP_1 { 
        my @IN = @_; 
        my @OUT = (); 
        my $i; 
        for($i=0;$i<=$#IP_TBL;$i++) { 
                @OUT[$IP_TBL[$i]-1] = $IN[$i]; 
        } 
        return (@OUT); 
} 
sub string_bl { 
        my @IN = @_; 
        my @passwd_K1; 
        my @string_L0=(); 
        my @string_R0=(); 
        my @string_L1=(); 
        my @string_R1=(); 
        my @string_R48=(); 
 
        (@passwd_K1[0..47],@string_L0[0..31],@string_R0[0..31])=@IN; 
 
        @string_R48 = &E_Table(@string_R0); 
        @string_R48 = &XOR(@passwd_K1,@string_R48); 
        @string_R1 = &S_Box(@string_R48); 
        @string_R1 = &P_Table(@string_R1); 
        @string_R1 = &XOR(@string_L0,@string_R1); 
        @string_L1 = @string_R0; 
 
        return(@string_L1,@string_R1); 
} 
 
sub XOR { 
        my @IN = @_; 
        my @OUT = (); 
        my $length = ($#IN + 1) / 2; 
        my $i; 
        for($i=0; $i<$length; $i++) { 
                if($IN[$i] == $IN[$i + $length]) { $OUT[$i] = 0; } 
                else {                             $OUT[$i] = 1; } 
        } 
        return @OUT; 
} 
sub E_Table { 
        my @IN = @_; 
        my @OUT = (); 
        my $i; 
        for($i=0;$i<=$#E_Table_TBL;$i++) { 
                $OUT[$i]=$IN[$E_Table_TBL[$i]-1]; 
        } 
        return @OUT; 
} 
sub S_Box { 
        my @IN = @_; 
 
        my @s1=(); 
        my @s2=(); 
        my @s3=(); 
        my @s4=(); 
        my @s5=(); 
        my @s6=(); 
        my @s7=(); 
        my @s8=(); 
 
        my @o1=(); 
        my @o2=(); 
        my @o3=(); 
        my @o4=(); 
        my @o5=(); 
        my @o6=(); 
        my @o7=(); 
        my @o8=(); 
        my @OUT = (); 
        my $i; 
 
        (@s1[0..5],@s2[0..5],@s3[0..5],@s4[0..5], 
                @s5[0..5],@s6[0..5],@s7[0..5],@s8[0..5]) = @IN; 
 
        $num = &bit_2_dec($s1[0],$s1[5]) * 16 + &bit_2_dec(@s1[1..4]); 
        $num = $S_Box_TBL1[$num]; 
        @s1 = &dec_2_bit($num); 
 
        $num = &bit_2_dec($s2[0],$s2[5]) * 16 + &bit_2_dec(@s2[1..4]); 
        $num = $S_Box_TBL2[$num]; 
        @s2 = &dec_2_bit($num); 
 
        $num = &bit_2_dec($s3[0],$s3[5]) * 16 + &bit_2_dec(@s3[1..4]); 
        $num = $S_Box_TBL3[$num]; 
        @s3 = &dec_2_bit($num); 
 
        $num = &bit_2_dec($s4[0],$s4[5]) * 16 + &bit_2_dec(@s4[1..4]); 
        $num = $S_Box_TBL4[$num]; 
        @s4 = &dec_2_bit($num); 
 
        $num = &bit_2_dec($s5[0],$s5[5]) * 16 + &bit_2_dec(@s5[1..4]); 
        $num = $S_Box_TBL5[$num]; 
        @s5 = &dec_2_bit($num); 
 
        $num = &bit_2_dec($s6[0],$s6[5]) * 16 + &bit_2_dec(@s6[1..4]); 
        $num = $S_Box_TBL6[$num]; 
        @s6 = &dec_2_bit($num); 
 
        $num = &bit_2_dec($s7[0],$s7[5]) * 16 + &bit_2_dec(@s7[1..4]); 
        $num = $S_Box_TBL7[$num]; 
        @s7 = &dec_2_bit($num); 
 
        $num = &bit_2_dec($s8[0],$s8[5]) * 16 + &bit_2_dec(@s8[1..4]); 
        $num = $S_Box_TBL8[$num]; 
        @s8 = &dec_2_bit($num); 
 
        @OUT = (@s1,@s2,@s3,@s4,@s5,@s6,@s7,@s8); 
 
        return @OUT; 
} 
sub bit_2_dec { 
        my @IN = @_; 
        my $OUT=0; 
        my $i; 
        for($i=0;$i<=$#IN;$i++) { 
                $OUT = ($OUT * 2) + $IN[$i]; 
        } 
        return $OUT; 
} 
sub dec_2_bit { 
        my ($IN) = @_; 
        my @OUT = (); 
        my @OUT2 = (); 
        my $div = $IN; 
        my $i; 
        while( $div != 0) { 
                $res = $div % 2; 
                push(@OUT,$res); 
                $div = ($div - $res) / 2; 
        } 
        my $l=  $#OUT; 
        for($i=0;$i<= $l;$i++) { 
                $OUT2[$i] = $OUT[$l - $i];         
        } 
        while($#OUT2 < 3) { 
                @OUT2 = (0,@OUT2); 
        } 
 
        return @OUT2; 
} 
sub P_Table { 
        my @IN = @_; 
        my @OUT = (); 
        my $i; 
        for($i=0;$i<=$#P_Table_TBL;$i++) { 
                $OUT[$i]=$IN[$P_Table_TBL[$i]-1]; 
        } 
        return @OUT; 
} 
sub hex2bin { 
        my ($aline) = @_; 
        my @hex=(); 
        my @bin=(); 
        my $bline = (); 
        @hex = split("",$aline); 
        for($i=0;$i<=$#hex;$i++) { 
                if   ($hex[$i] eq '1') { $bline = "0001"; } 
                elsif($hex[$i] eq '2') { $bline = "0010"; } 
                elsif($hex[$i] eq '3') { $bline = "0011"; } 
                elsif($hex[$i] eq '4') { $bline = "0100"; } 
                elsif($hex[$i] eq '5') { $bline = "0101"; } 
                elsif($hex[$i] eq '6') { $bline = "0110"; } 
                elsif($hex[$i] eq '7') { $bline = "0111"; } 
                elsif($hex[$i] eq '8') { $bline = "1000"; } 
                elsif($hex[$i] eq '9') { $bline = "1001"; } 
                elsif($hex[$i] eq 'a') { $bline = "1010"; } 
                elsif($hex[$i] eq 'b') { $bline = "1011"; } 
                elsif($hex[$i] eq 'c') { $bline = "1100"; } 
                elsif($hex[$i] eq 'd') { $bline = "1101"; } 
                elsif($hex[$i] eq 'e') { $bline = "1110"; } 
                elsif($hex[$i] eq 'f') { $bline = "1111"; } 
                else                   { $bline = "0000"; } 
                push(@bin,$bline); 
        } 
        $bline = join('',@bin); 
        return $bline; 
} 
sub bin2hex { 
        my ($aline) = @_; 
        my @bin=(); 
        my @hex=(); 
        my $bline = (); 
        @bin = split("",$aline); 
        for($i=0;$i<=$#bin;$i+=4) { 
                $aline = join('',$bin[$i],$bin[$i+1], 
                                $bin[$i+2],$bin[$i+3]); 
                if   ($aline eq "0001") { $bline = "1"; } 
                elsif($aline eq "0010") { $bline = "2"; } 
                elsif($aline eq "0011") { $bline = "3"; } 
                elsif($aline eq "0100") { $bline = "4"; } 
                elsif($aline eq "0101") { $bline = "5"; } 
                elsif($aline eq "0110") { $bline = "6"; } 
                elsif($aline eq "0111") { $bline = "7"; } 
                elsif($aline eq "1000") { $bline = "8"; } 
                elsif($aline eq "1001") { $bline = "9"; } 
                elsif($aline eq "1010") { $bline = "a"; } 
                elsif($aline eq "1011") { $bline = "b"; } 
                elsif($aline eq "1100") { $bline = "c"; } 
                elsif($aline eq "1101") { $bline = "d"; } 
                elsif($aline eq "1110") { $bline = "e"; } 
                elsif($aline eq "1111") { $bline = "f"; } 
                else                    { $bline = "0"; } 
                push(@hex,$bline); 
        } 
        $bline = join('',@hex); 
        return $bline; 
} 
sub binArray2hexLine { 
        my @IN = @_; 
        my $aline=(); 
        my $bline=(); 
        $aline = join('',@IN); 
        $bline = bin2hex($aline); 
        return $bline; 
} 
sub binArray2hexPrint { 
        my @IN = @_; 
        $aline = &binArray2hexLine(@IN); 
        print "$aline\n"; 
} 
sub hexLine2binArray { 
        my ($aline) = @_; 
        my @bin=(); 
        my $bline =(); 
        $bline = &hex2bin($aline); 
        @bin = split('',$bline); 
        return @bin; 
} 
sub B_AND { 
        my @IN = @_; 
        my @OUT = (); 
        my $length = ($#IN + 1) / 2; 
        my $i; 
        for($i=0; $i<$length; $i++) { 
                if(($IN[$i] == 1)&&($IN[$i + $length] == 1)) { 
                                                $OUT[$i] = 1; } 
                else {                          $OUT[$i] = 0; } 
        } 
        return @OUT; 
} 
sub B_XOR { 
        my @IN = @_; 
        my @OUT = (); 
        my $length = ($#IN + 1) / 2; 
        my $i; 
        for($i=0; $i<$length; $i++) { 
                if($IN[$i] == $IN[$i + $length]) { $OUT[$i] = 0; } 
                else {                             $OUT[$i] = 1; } 
        } 
        return @OUT; 
} 
 
  | 
 |