Advertisement
nserd

RC5 cipher [32bit]

Jan 22nd, 2017
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 6.85 KB | None | 0 0
  1. import java.io.File;
  2. import java.io.FileInputStream;
  3. import java.io.FileOutputStream;
  4. import java.io.IOException;
  5.  
  6. public class RC5_32bit {
  7.     private int W;
  8.     private int R;
  9.    
  10.     private int Pw;
  11.     private int Qw;
  12.    
  13.     public RC5_32bit(int rounds){
  14.         R = rounds;
  15.         W = 32;
  16.         Pw = 0xb7e15163;
  17.         Qw = 0x9e3779b9;
  18.     }
  19.    
  20.     private int bytesInWord(byte[] byteArray) {
  21.         int word = 0;
  22.         int buff;
  23.        
  24.         for(int j = W/8 - 1, pos = 0; j >= 0; j --, pos+= 8){
  25.             buff = 0;
  26.             buff |= byteArray[j];
  27.             buff <<= W - 8;
  28.             buff >>>= W - 8;
  29.                
  30.             word |= (buff) << pos;
  31.         }
  32.        
  33.         return word;
  34.     }
  35.    
  36.     private void wordInBytes(int word , byte [] byteArray) {
  37.         for (int i = W/8 - 1, pos = 8; i >= 0; i-- ){
  38.             byteArray[i] = (byte) (word % 256);
  39.             word >>>= pos;
  40.         }
  41.     }
  42.    
  43.     private int rotL(int val, int pas) {
  44.         return (val << pas) | (val >>> (W - pas));
  45.     }
  46.  
  47.     private int rotR(int val, int pas) {
  48.         return (val >>> pas) | (val << (W - pas));
  49.     }
  50.    
  51.     private int[] init_L(byte[] key) { 
  52.         int[] L = new int[key.length/ (W/8)];
  53.         int buff;
  54.        
  55.         for (int i = 0; i < L.length; i++)
  56.             for(int j = W/8 - 1, pos = 0; j >= 0; j --, pos+= 8){
  57.                 buff = 0;
  58.                 buff |= key[j];
  59.                 buff <<= W - 8;
  60.                 buff >>>= W - 8;
  61.                
  62.                 L[i] |= (buff) << pos;
  63.             }
  64.        
  65.         return L;
  66.     }
  67.    
  68.     private byte[] keyConverter(byte[] key){
  69.         int byteW = W / 8;
  70.         byte[] result;
  71.        
  72.         if(key.length % byteW != 0){
  73.             int append = byteW - (key.length % byteW);
  74.             result = new byte[key.length + append];
  75.            
  76.             for(int i = 0; i < result.length; i++)
  77.                 if(i < key.length)
  78.                     result[i] = key[i];
  79.                 else
  80.                     result[i] = 0;
  81.         }
  82.         else
  83.             result = key;
  84.        
  85.         return result;
  86.     }
  87.    
  88.     private int[] paddling(int [] L , int length){
  89.         int[] S = new int[2 * R + 1];
  90.        
  91.         S[0] = Pw;
  92.         for(int q = 1; q < S.length; q++)
  93.             S[q] = S[q - 1] + Qw;
  94.        
  95.         int A = 0;
  96.         int B = 0;
  97.  
  98.         int i = 0, j = 0;
  99.         int N = 3 * Math.max(W / 8, 2 * R + 1);
  100.        
  101.         for(int count = 0; count < N; count++){
  102.             A = S[i] = rotL((S[i] + A + B), 3);
  103.             B = L[j] = rotR((L[j] + A + B), (A + B));
  104.             i = (i + 1) % (2 * R + 1);
  105.             j = (j + 1) % (length/(W / 8));
  106.         }  
  107.        
  108.         return S;
  109.     }
  110.    
  111.     private int[] keyExpansion(byte[] key){
  112.         int [] L;
  113.        
  114.         key = keyConverter(key);
  115.         L = init_L(key);
  116.        
  117.         return paddling(L, key.length);
  118.     }
  119.    
  120.     private  void encRounds(byte[] A, byte[] B, int[] S){
  121.         if(R == 0)
  122.             return;
  123.        
  124.         int Aw = bytesInWord(A);
  125.         int Bw = bytesInWord(B);
  126.  
  127.         Aw += S[0];
  128.         Bw += S[1];
  129.        
  130.         for(int r = 1; r < R; r++){
  131.             Aw ^= Bw;
  132.             Aw = rotL(Aw, Bw);
  133.             Aw += S[2*r];
  134.                
  135.             Bw ^= Aw;
  136.             Bw = rotL(Bw, Aw);
  137.             Bw += S[2*r + 1];
  138.         }
  139.        
  140.         wordInBytes(Aw , A);
  141.         wordInBytes(Bw , B);
  142.     }
  143.    
  144.     private  void decRounds(byte[] A, byte[] B, int[] S){
  145.         if(R == 0)
  146.             return;
  147.        
  148.         int Aw = bytesInWord(A);
  149.         int Bw = bytesInWord(B);
  150.  
  151.         for(int r = R - 1; r > 0; r--){
  152.             Bw -= S[2*r + 1];
  153.             Bw = rotR(Bw, Aw);
  154.             Bw ^= Aw;
  155.            
  156.            
  157.             Aw -= S[2*r];
  158.             Aw = rotR(Aw, Bw);
  159.             Aw ^= Bw;      
  160.         }
  161.        
  162.         Aw -= S[0];
  163.         Bw -= S[1];
  164.        
  165.         wordInBytes(Aw, A);
  166.         wordInBytes(Bw, B);
  167.     }
  168.    
  169.     private void divideByTwo(byte[] data, byte[] p1, byte[] p2){
  170.         for(int k = 0; k < data.length / 2; k++)
  171.             p1[k] = data[k];
  172.         for(int k = data.length / 2, j = 0; k < data.length; k++ , j++)
  173.             p2[j] = data[k];
  174.     }
  175.    
  176.     private void addParts(byte[] p1, byte[] p2, byte[] data){
  177.         for(int k = 0; k < data.length / 2; k++)
  178.             data[k] = p1[k];
  179.         for(int k = data.length / 2, j = 0; k < data.length; k++ , j++)
  180.             data[k] = p2[j];
  181.     }
  182.    
  183.     public  void encrypt(File in, File out, byte[] key) throws IOException{
  184.         FileInputStream inputStream;
  185.         FileOutputStream outputStream;
  186.        
  187.         inputStream = new FileInputStream(in);
  188.         outputStream = new FileOutputStream(out);
  189.        
  190.         int blockLength = (2*W) / 8;
  191.         int numbOfBlocks = (int) (in.length() / blockLength);
  192.        
  193.         byte[] data = new byte[blockLength];
  194.         byte[] output = new byte[blockLength];
  195.        
  196.         int [] S = keyExpansion(key);
  197.  
  198.         byte[] part_1 = new byte[data.length / 2];
  199.         byte[] part_2 = new byte[data.length / 2];
  200.  
  201.         int lengthFile = inputStream.available();
  202.  
  203.         for(int i = 0; i < numbOfBlocks; i++){
  204.             for(int j = 0; j < blockLength; j++)
  205.                 data[j] = (byte) inputStream.read();
  206.            
  207.             divideByTwo(data, part_1, part_2);
  208.             encRounds(part_1, part_2, S);
  209.             addParts(part_1, part_2, output);
  210.            
  211.             outputStream.write(output, 0 , blockLength );
  212.         }
  213.        
  214.         if(lengthFile % blockLength != 0){
  215.             int remain = lengthFile % blockLength;
  216.      
  217.             for(int i = 0; i < remain; i++)
  218.                 data[i] = (byte) inputStream.read();
  219.  
  220.             data[remain] = 1;
  221.  
  222.             for(int i = remain + 1; i < blockLength; i++)
  223.                 data[i] = 0;
  224.  
  225.             divideByTwo(data, part_1, part_2);
  226.             encRounds(part_1, part_2, S);
  227.             addParts(part_1, part_2, output);
  228.            
  229.             outputStream.write(output, 0 , blockLength);
  230.         }
  231.        
  232.         else {
  233.             data[0] = 1;
  234.            
  235.             for(int i = 1; i < blockLength; i++)
  236.                 data[i] = 0;
  237.            
  238.             divideByTwo(data, part_1, part_2);
  239.             encRounds(part_1, part_2, S);
  240.             addParts(part_1, part_2, output);
  241.  
  242.             outputStream.write(output, 0 , blockLength);
  243.         }
  244.      
  245.         inputStream.close();
  246.         outputStream.close();
  247.     }
  248.    
  249.     public void decrypt(File in, File out, byte[] key) throws IOException{
  250.         FileInputStream inputStream;
  251.         FileOutputStream outputStream;
  252.        
  253.         inputStream = new FileInputStream(in);
  254.         outputStream = new FileOutputStream(out);
  255.        
  256.         int blockLength = (2*W) / 8;
  257.         int numbOfBlocks = (int) (in.length() / blockLength);
  258.        
  259.         byte[] data = new byte[blockLength];
  260.         byte[] output = new byte[blockLength];
  261.        
  262.         int [] S = keyExpansion(key);
  263.        
  264.         byte[] part_1 = new byte[data.length / 2];
  265.         byte[] part_2 = new byte[data.length / 2];
  266.        
  267.         for(int i = 0; i < numbOfBlocks; i++){
  268.             for(int j = 0; j < blockLength; j++)
  269.                 data[j] = (byte) inputStream.read();
  270.  
  271.             divideByTwo(data, part_1, part_2);
  272.             decRounds(part_1, part_2, S);
  273.             addParts(part_1, part_2, output);
  274.            
  275.             if (i == numbOfBlocks - 1) {
  276.                 boolean endFile = false;
  277.  
  278.                 for (int j = 0; j < output.length; j++)
  279.                     if (output[j] == 1) {
  280.                         for (int k = j + 1; k < output.length; k++)
  281.                             if (output[k] == 0)
  282.                                 endFile = true;
  283.                             else {
  284.                                 endFile = false;
  285.                                 break;
  286.                             }
  287.  
  288.                         if (endFile)
  289.                             outputStream.write(output, 0, j);
  290.                     }
  291.             }
  292.  
  293.             else
  294.                 outputStream.write(output, 0 , blockLength );
  295.         }
  296.        
  297.         inputStream.close();
  298.         outputStream.close();
  299.     }
  300. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement