http://qs321.pair.com?node_id=97238
Category: Cryptography
Author/Contact Info C. Prichard
Description: Improved string cipher. Useful in protecting content of HTML textareas where a Javascript implementation is used by the client. The algorithm has also been implemented in Visual Basic.

This improved version uses a randomly sorted key domain table to build a modified key used in a second cipher pass. The key domain now includes ASCII values from 32 to 96 decimal. Output domain is 32 to 159 but the values 128 to 159 are shifted so as to be compatible with all ISO-8859-1 implementations in transmission equipment as well as all Windows implementations.

A patent is being sought to protect the author's right to his own innovation which uses a key attribute to articulate shifts applied to the modified key string. Its thought that the implementation demonstrates that there is some cryptographic value of a somewhat unique key attribute. The attribute is used to mask the values in the modified key as they are taken from the randomly sorted domain table. The attribute is also used to articulate shifts applied to the modified key. Applying these shifts is what creates a difference between the resulting cipher bits applied by very similar keys.

Solving a CipherText message is not trivial. To date it has not been done. An attack will require some known plaintext and sufficient data for frequency analysis. Applying a truncated modified keystring of cipher bits in the second pass diffuses the recurring pattern to N*(N-1) message elements. It also serves to mask the actual key in the event that a message is broken and the same key is used to protect other items. The algorithm uses a data-dependent shift based on message length. This results in two different results when ciphering the word "Hello" and the word "Hello ". The feature is desireable for applications that would apply the same key to a series of short strings.

If required, an ASCII compliant version can be obtained.
# CipherTextI.pm
#
# Charles Prichard 6-16-01
#

#
#################################################
package CipherTextI;

use strict;
use integer;
use bytes;
#################################################
#   PUBLIC Subroutine                           #
#################################################
sub new($) {
    
my $class = shift;

    my $self = {};
    
    bless $self, ref $class || $class;


    $self->{xString} = undef;
    $self->{xStr} = undef;

    $self->{R_KEY} = undef;
    $self->{ATT} = undef;
    $self->{S_KEY} = undef;
    $self->{cipher_key} = undef;
    
    $self->{RSORT} = [];
    
    $self->init(@_);
    
    return $self;

}
sub init($){
    
    my $self = shift;
    
    my ($params) = shift;
    
    my @temp1 = split /\;/, $params;
    
        my %params = ();
    
        my @temp2=();
    
        foreach my $x (@temp1){
    
            @temp2 = split /\=/, $x;
    
            $self->{$temp2[0]} = $temp2[1];
       }
    
    $self->{RSORT} = [3,28,7,5,39,62,34,32,56,18,17,6,29,49,63,45,13,1
+3,29,40,2,17,17,9,12,61,56,23,55,37,31,13,27,52,8,23,38,53,9,60,31,30
+,39,27,37,14,14,34,8,29,58,10,25,3,19,37,11,35,52,39,48,24,22,19];
    
    $self->{S_KEY} = $self->Make_shiftedKeys();
    
    return;
}
#################################################
#   PUBLIC Subroutine                           #
#################################################
sub encipher($) {
    
    my $self = shift;
        
    my $MSG = shift;;
        
    $MSG = $self->Encode($self->Encode($MSG,$self->{R_KEY}),$self->{S_
+KEY});    

    return $MSG;     
}
#################################################
#   PUBLIC Subroutine                           #
#################################################
sub decipher {
    
    my $self = shift;
        
    my $MSG = shift;;
       
    $MSG = $self->Decode($self->Decode($MSG,$self->{S_KEY}),$self->{R_
+KEY});
      
    return $MSG;     
}
#################################################
#       PRIVATE Subroutine                      #
#################################################
sub Make_shiftedKeys(){
    
    my $self = shift;
    
    my $shift = $self->setAttribute();
    
    $self->{S_KEY} = $self->modifyKeys();

    if (($shift % 2) == 1){$self->{S_KEY} = (substr($self->{S_KEY},1,(
+length $self->{S_KEY})));}
    
    else {$self->{S_KEY} = (substr($self->{S_KEY},0,(length $self->{S_
+KEY}) - 1));}

    my $key;
    my $v;
    
    for (my $i=0; $i <= ($shift - 1) % length $self->{S_KEY}; $i++){  
+           
            
            my $key = substr($self->{S_KEY},0,1);
            
            $v = ord($key) - 32;
            
            $self->{S_KEY} = (substr($self->{S_KEY},1,(length $self->{
+S_KEY}) - 1));

            $self->{S_KEY} .= chr($v ^ $self->{RSORT}[$v] + 32);
    
        }
        
        return $self->{S_KEY};
}
#################################################
#       PRIVATE Subroutine                      #
#################################################  
sub setAttribute(){
    
    my $self = shift;
    
        $self->{ATT} = 0x00;
        
        for (my $i=0; $i < (length $self->{R_KEY}); $i++){
    
        $self->{ATT} = $self->{ATT} ^ (ord(substr($self->{R_KEY},$i,1)
+) - 0x20);  
      } 
        
        return $self->{ATT};
}
#################################################
#       PRIVATE Subroutine                      #
#################################################
sub modifyKeys(){
    
    my $self = shift;
    my S_KEY = "";
    my $i, $x;
    
    For $x = 1 To length($self->{R_KEY})
    
        $i = ord(substr($self->{R_KEY}, $x, 1)) - 32
        
        S_KEY = S_KEY + Chr(($i ^ $self->{RSORT}[$i] ^ $self->{ATT}) +
+ 32)
    
    Next x
    
    return S_KEY;

}
#################################################
#       PRIVATE Subroutine                      #
#################################################
sub Encode($$){
    
    my $self = shift;
    
        $self->{xString} = shift;
    
        $self->{cipher_key} = shift;
    
        $self->cipher();
    
        return $self->{xStr};

}
#################################################
#       PRIVATE Subroutine                      #
#################################################
sub Decode($$){
    
    my $self = shift;
    
    $self->{xString} = shift;
    
        $self->{cipher_key} = shift;
    
        $self->cipher();
    
        return $self->{xStr};

}
#################################################
#       PRIVATE Subroutine                      #
#################################################
sub cipher(){
    
    my $self = shift;

        $self->{xStr} = "";
     
        my $keyval;
     
        my $xch;
     
        my @akeys = split "",$self->{cipher_key};
     
        my $keylen = length $self->{cipher_key};
     
        my $i = (length $self->{xString} % $keylen); # DATA DEPENDENT 
+SHIFT 
    
        for(my $x=0; $x < length ($self->{xString}); $x++){
            
              $keyval = ord($akeys[$i]) - 0x20;
              
              $xch = ord(substr($self->{xString},$x,1));
              
              if ($xch > 0x7f){ $xch = $xch - 0x21;}
              
            if ($xch > 0x1f){
                

                 $xch = ($keyval ^ ($xch - 0x20)) + 0x20; # Apply ciph
+er
               
                 
              }
             
             if ($xch > 0x7f){ $xch = $xch + 0x21;}
        
        $self->{xStr} .= chr($xch);                           
     
            $i++;
     
            if ($i == $keylen){$i = 0;}
     
        }         

        return;
}

1;