Tuesday 9 July 2013

S Hill Block cipher in Java

S Hill Cipher is one of the basic substitution Hill Cipher scheme. According to Wikipedia:


In classical cryptography, the Hill cipher is a polygraphic substitution cipher based on linear algebra. Invented by Lester S. Hill in 1929, it was the first polygraphic cipher in which it was practical (though barely) to operate on more than three symbols at once.

 Basic Algorithm:


Basic algorithm of Hill Cipher works with some matrix operation in modulo arithmetic  Plain text is first broken into chunks of length n. Each chunk is then modulo multiplicated with a nxn matrix acting as key. The resulting chunks of text are then concatenated to from Cipher text. For decryption the nxn key is taken modulo inverse to from decryption key. Cipher text is then modulo multiplicated in the same manner as the plain text was, to get the Plain text back.

Here is a Java program written to perform Encryption and Decryption using Hill Cipher. This program uses modulo 95 to cover the whole printable ASCII range.
The HillCipher class uses a HillMatrix class and a Converter class to perform arithmetic and conversion operations respectively.

HillMatrix Class:


package encryption.hillcipher;

import java.math.BigInteger;

public class HillMatrix {

    private int row;
    private int column;
    private int matrix[][];   
    private final int RANGE = 95;

    public HillMatrix(int row, int col){
        this.row = row;
        this.column = col;
        matrix = new int[row][col];
        for( int i=0;i<row;i++){
            for(int j=0;j<col;j++){
                matrix[i][j]=0;
            }
        }
    }

    public void set(int i, int j, int val){
        matrix[i][j]=val;
    }

    public int get(int i, int j){
        return matrix[i][j];
    }

    public int getrowindex(){
        return row;
    }

    public int getcolumnindex(){
        return column;
    }

    public HillMatrix cross(HillMatrix B){
        if(this.column != B.getrowindex()){
            return null;
        }
        HillMatrix C = new HillMatrix(this.row,B.getcolumnindex());
        for(int i=0;i<this.row;i++){
            for(int j=0;j<B.getcolumnindex();j++){
                for(int k=0;k<this.column;k++){
                    C.set(i, j, C.get(i, j) + this.get(i, k) * B.get(k, j));
                }
            }
        }
        return C;
    }

    private int det(HillMatrix m){
        int res=0;
        if(m.getcolumnindex() == 2){
            res = m.get(0, 0)*m.get(1, 1) - m.get(1, 0)*m.get(0, 1);
            return (res);
        }
        for(int i=0;i<m.getcolumnindex();i++){
            res = (int) (res + Math.pow(-1, i) * cofac(i,0,m) * m.get(0,i));
        }
        return (res);
    }

    private int cofac( int i, int j,HillMatrix m){
        int res;
        int index = m.getcolumnindex()-1;
        int deci = 0;
        int decj ;
        HillMatrix submat = new HillMatrix(index,index);
        for(int k=0;k<index+1;k++){
            decj=0;
            if( k == j) {
                deci=1;
                continue;
            }
            for(int l=0;l<index+1;l++){
                if( l == i){
                    decj=1;
                    continue;
                }
                submat.set(k-deci, l-decj, m.get(k, l));
            }
        }
        res = det(submat);       
        return res;
    }

    public int det(){
        return det(this);
    }

    public int cofac(int i, int j){
        return cofac(i,j,this);
    }

    public HillMatrix inv(){
        HillMatrix in = new HillMatrix(row , column);
        int invdet = moduloinv(det(this));
        int temp;
        for(int i=0; i<row ; i++){
            for(int j=0;j<column;j++){
                temp = cofac(i,j,this)* (int) Math.pow(-1,i+j);
                in.set(i, j, modulus(temp*invdet));
            }
        }
        return in;
    } 

    public HillMatrix transpose(){
        HillMatrix m = new HillMatrix(row,column);
        for(int i=0;i<row;i++){
            for(int j=0;j<column;j++){
                m.set(i, j, get(j,i));
            }
        }
        return m;
    } 

    private int modulus(int in){
        int res;
        if(in < 0){
            return RANGE - (Math.abs(in)%RANGE);
        }
        res = Math.abs(in) % RANGE;
        return res;
    }

    private int moduloinv(int in){
        BigInteger bi = new BigInteger(String.valueOf(in));
        try{
            bi = bi.modInverse(new BigInteger(String.valueOf(RANGE)));
        }
        catch(Exception e){
            System.out.println("Key is not inversable..!");
            System.exit(-1);
        }
        return bi.intValue();
    }    

    public HillMatrix mod(){
        HillMatrix m = new HillMatrix(row,column);
        for(int i=0;i<row;i++){
            for(int j=0;j<column;j++){
                m.matrix[i][j] = matrix[i][j]%RANGE;
            }
        }
        return m;
    }

    public boolean IsInvertable(){
        int det = det(this);
        if( det != 0 && moduloinv(det) != 0) {
            return true;
        }
        return false;
    }
}

Converter Class:
package encryption.hillcipher;

public class Converter{
    private static final int OFFSET = 32;
    public  static int ToInt(char ch){
        return ((int)ch-OFFSET);
    }
    public static char ToChar(int in){
        return (char)(in + OFFSET);
    }
}

Now here is the HillCipher class:
public class HillCipher {
    HillMatrix key;
    int keyLenght;
    
    public HillCipher(String keyText){
        int l = keyText.length();
        l=(int)Math.sqrt(l);
        keyLenght = l;
        key = new HillMatrix(keyLenght,keyLenght);
        l = 0;
        for(int i=0;i<keyLenght;i++){
            for(int j=0;j<keyLenght;j++){
                key.set(i, j, Converter.ToInt(keyText.charAt(l++)));
            }
        }
    }

    public StringBuffer Encrypt(StringBuffer pText){
        StringBuffer cText = new StringBuffer();
        HillMatrix enc = new HillMatrix(keyLenght,1);
        int n = keyLenght -(pText.length() % keyLenght);
        for(int i=0;i<n;i++){
            pText.append('x');
        }
        n = 0;
        while(n <pText.length()){
            for(int i=0;i<keyLenght;i++){
                enc.set(i, 0, Converter.ToInt(pText.charAt(n++)));
            }
            enc = key.cross(enc);
            enc = enc.mod();
            for(int i=0;i<keyLenght;i++){
                cText.append(Converter.ToChar(enc.get(i, 0)));
            }
        }
        return cText;
    }

    public StringBuffer Decrypt(StringBuffer cText){
        StringBuffer pText = new StringBuffer();
        HillMatrix dec = new HillMatrix(keyLenght,1);
        HillMatrix invKey = key.inv();
        int n = cText.length() % keyLenght;
        for(int i = 0 ; i< n ;i++){
            cText.append('x');
        }
        n = 0;
        while(n <cText.length()){
            for(int i =0;i<keyLenght;i++){
                dec.set(i, 0, Converter.ToInt(cText.charAt(n++)));
            }
            dec = invKey.cross(dec);
            dec = dec.mod();
            for(int i=0;i<keyLenght;i++){
                pText.append(Converter.ToChar(dec.get(i, 0)));
            }
        }
        return pText;
    }

    public static boolean IsDecryptable(String keyText){
        int l = keyText.length();
        l=(int)Math.sqrt(l);
        HillMatrix newkey = new HillMatrix(l,l);
        int n = 0;
        for(int i=0;i<l;i++){
            for(int j=0;j<l;j++){package encryption.hillcipher;

public class Converter{
    private static final int OFFSET = 32;
    public  static int ToInt(char ch){
        return ((int)ch-OFFSET);
    }
    public static char ToChar(int in){
        return (char)(in + OFFSET);
    }
}
                newkey.set(i, j, Converter.ToInt(keyText.charAt(n++)));
            }
        }
    
        return newkey.IsInvertable();
    }
}

Thursday 9 May 2013

Open Terminal any where

If you are a Linux user than you (must have to) use your terminal at least once each hour. Some times opening the terminal and navigating to the working directory using cd a number of time while keeping a strict sight on the spellings and case of directory path some times become very teasing. And you might wish to have an option on your right click menu with "Open with terminal"...!
So here is how you can do this (I have done this on Ubuntu and I don't know about other distributions. If you are looking for some thing similar on windows, then try this) :


  1. Install Nautilus Action Configuration Tool. Nautilus is the default file manager in Ubuntu and many other Linux distros. According to Wikipedia:
    Nautilus is the official file manager for the GNOME desktop. The name is a play on words, evoking the shell of a nautilus to represent an operating system shell. Nautilus replaced Midnight Commander in GNOME 1.4 and was the default from version 2.0 onwards.

  2. After installation open it.

  3. Go to File > New.
  4. Un Check Display item in selection context menu.
  5. Check Display item in location context menu.
  6. Set the context label as you want. For example I set it to Open in terminal..
  7. Set the tooltip text.

  8. Now in command tab set Path to xterm. Ubuntu users can also use gnome-terminal.
  9. Set Working Directory to %d/%b or %d if you want to open terminal in base directory only.
  10. Save and exit.
  11. Now go to your required directory and enjoy....

Sunday 28 April 2013

Open Command Prompt Any Where

If you are a programmer or you like to work with command line or you use some utilities that only runs on command line then you might really hate opening the command line then separately moving to the current directory by typing cd [my directory]  hundred times trying to keeping the spellings of your directory path exactly same....
I my self really dont like it. So there is the mercy of Windows Registry....
According to Wikipedia
The Windows Registry is a hierarchical database that stores configuration settings and options on Microsoft Windows operating systems. It contains settings for low-level operating system components and for applications running on the platform that have opted to use the registry.

 Opting the other details I am going to show you a way with which you can open the command prompt directly to your current working directory.



Here are a few easy steps to get this functionality.



  1. Open Run from start menu or press win+R.
  2. Type regedit and press ok.
  3. In the Registry Editor press Cltr+F to open find dialog and uncheck all options except "key". Press Find.
  4. The key tree view will high light some key like "CDO.DropDirectory". But this is not what we are looking for.
  5. Just keep pressing F3 until the tree high lights the key with name "Direcotry".
  6. Drop this key. You will find 3 further keys here. Drop the one with name Background.
  7. Here you will find 2 keys again. Right click the "shell" key and create a new key.
  8. Name this key "Open Command Prompt Here" or any other name that you want....!
  9. Now right click this key and create another with name "command".
  10. High light the command key and you will see that the table on the right column is showing (Default), REG_SZ, Not Set. Right click it and press Modify...
  11. In the key value input box right "cmd.exe".


Now go to any of your directory right click and Enjoy!

Friday 26 April 2013

RSA Public Key Encryption Algorithm in Java

Definition: 

RSA is an algorithm for public-key cryptography that is based on the presumed difficulty of factoring large integers, the factoring problem.

Algorithm:

  • p and q: the primes from the key generation,
  • d_P = d\text{ (mod }p-1\text{)},
  • d_Q = d\text{ (mod }q-1\text{)} and
  • q_\text{inv} = q^{-1}\text{ (mod }p\text{)}.
  • m_1 = c^{d_P}\text{ (mod }p\text{)}
  • m_2 = c^{d_Q}\text{ (mod }q\text{)}
  • h = q_\text{inv}*(m_1-m_2)\text{ (mod }p\text{)} (if m_1 < m_2 then some libraries compute h as q_\text{inv} \times (m_1+p-m_2)\text{ (mod }p\text{)})
  • m = m_2 + (h*q)\, 
Definition and Algorithm taken from Wikipedia.

I have write a Java program implementing the RSA Public key cipher algorithm. You can use the code in case 'k' , case 'c' , case 'p' for key generation, encryption and decryption  respectively.

package encryption.rsa;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigInteger;

public class RSA {

    public static void main(String[] args) throws IOException {
        char selection = '3';
        BufferedReader console = new BufferedReader(new InputStreamReader(System.in));
        BigInteger p;
        BigInteger q;
        BigInteger n;
        BigInteger phiN;
        BigInteger e = new BigInteger("0");
        BigInteger d = new BigInteger("0");
        BigInteger plain;
        BigInteger cipher;
        while (selection != 'e') {
            switch (selection) {

                case 'k':
                    System.out.print("Enter the Value of p: ");
                    p = new BigInteger(console.readLine());
                    System.out.print("Enter the Value of q: ");
                    q = new BigInteger(console.readLine());
                    if (!p.isProbablePrime(4) || !q.isProbablePrime(4)) {
                        System.out.print("p or q is a composite number!\n\n");
                        break;
                    }
                    n = p.multiply(q);
                    phiN = p.subtract(new BigInteger("1")).multiply(q.subtract(new BigInteger("1")));
                    for (int i = 2; i < (phiN.intValue() / 2); i++) {
                        if (phiN.remainder(new BigInteger(String.valueOf(i))).intValue() != 0) {
                            e = new BigInteger(String.valueOf(i));
                            d = e.modInverse(phiN);
                            break;
                        }
                    }
                    System.out.print("\n\nPublic Key: {" + e.toString() + ", " + n.toString() + "}\n");
                    System.out.print("Private Key: {" + d.toString() + ", " + n.toString() + "}\n");
                    break;
                case 'c':
                    System.out.print("\n\nEnter the value to Encrypt: ");
                    plain = new BigInteger(console.readLine());
                    System.out.print("Enter the value of e: ");
                    e = new BigInteger(console.readLine());
                    System.out.print("Enter the value of n: ");
                    n = new BigInteger(console.readLine());
                    cipher = plain.modPow(e, n);
                    System.out.print("\nThe Ciphered Value of " + plain.toString()
                            + " is " + cipher.toString() + '.');
                    break;
                case 'p':
                    System.out.print("\n\nEnter the value to Decrypt: ");
                    cipher = new BigInteger(console.readLine());
                    System.out.print("Enter the value of d: ");
                    d = new BigInteger(console.readLine());
                    System.out.print("Enter the value of n: ");
                    n = new BigInteger(console.readLine());
                    plain = cipher.modPow(d, n);
                    System.out.print("\nThe Deciphered Value of " + cipher.toString()
                            + " is " + plain.toString() + '.');
                    break;
            }
            System.out.println("\n\n\nPlease Select From the Following:");
            System.out.println("Generate [k]ey pair.");
            System.out.println("En[c]rypt.");
            System.out.println("Decry[p]t");
            System.out.println("[E]xit");
            selection = console.readLine().charAt(0);
        }
    }
}