Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- BigInteger [] K ; //128 bits key
- private String plainText;
- public static final BigInteger delta = new BigInteger("9e3779b9",16);
- //constructor receives a string of plaintext and 128 bit key in hexadecimal
- public TEA(String plainText, String key)
- {
- parseKey(key);
- }
- //constructor receives a hexadecimal
- public TEA(String key)
- {
- parseKey(key);
- }
- //parses a 128 bit key, given in hexadecimal form, and store its value in 4 integers (total of 128 bits),
- private void parseKey(String key)
- {
- if(key.substring(0,2).equals("0x"))
- key= key.substring(2);
- //validating input
- if(key.length() != 32)
- {
- System.out.println("Invalid key size!");
- return;
- }
- //dividing the key into 4 strings
- String[] kStr = new String[4];
- int index=-1;
- for(int i=0; i<key.length(); i++)
- {
- if(i%8 == 0)
- {
- index++;
- kStr[index]="";
- }
- kStr[index] = kStr[index] + key.charAt(i);
- }
- //converting the 4 hex strings into 4 integers
- K= new BigInteger[4];
- for(int i=0; i<4; i++)
- K[i] = new BigInteger(kStr[i], 16);
- }
- //receives a plaintext block of 64 bits in hexadecimal to be encrypted
- //returns the cipher block
- String encryptBlock(String plainTextBlock)
- {
- if(plainTextBlock.substring(0,2).equals("0x"))
- plainTextBlock= plainTextBlock.substring(2);
- //validating input
- if(plainTextBlock.length()!=16)
- {
- System.out.println("Invalid block size!");
- return null;
- }
- //separating the string block into left and right blocks
- String LStr = plainTextBlock.substring(0, 8); //left block (32 bit)
- String RStr = plainTextBlock.substring(8); //right block (32 bit)
- //converting left and right blocks to integers
- BigInteger L = new BigInteger(LStr, 16);
- BigInteger R = new BigInteger(RStr, 16);
- BigInteger sum= new BigInteger("0");
- //32 rounds
- for(int i=0; i<32; i++)
- {
- sum = sum.add(delta);
- L= sum(L, (sum(shiftLeft(R,4),K[0])) .xor(sum(R,sum)) .xor(sum(shiftRight(R,5),K[1]))) ;
- R= sum(R, (sum(shiftLeft(L,4),K[2])) .xor(sum(L,sum)) .xor(sum(shiftRight(L,5),K[3]))) ;
- //R= R.add( (shiftLeft(R,4).add(K[2])).xor(L.add(sum)).xor(shiftRight(L,5).add(K[3])) );
- }
- //joining back the blocks as hex
- String cipherBlock = "0x"+L.toString(16)+R.toString(16)+"";
- return cipherBlock;
- }
- //receives a ciphertext block of 64 bits in hexadecimal to be decrypted
- //returns the plaintext block
- String decryptBlock(String cipherBlock)
- {
- if(cipherBlock.substring(0,2).equals("0x"))
- cipherBlock= cipherBlock.substring(2);
- //validating input
- if(cipherBlock.length()!=16)
- {
- System.out.println("Invalid block size!");
- return null;
- }
- //separating the string block into left and right blocks
- String LStr = cipherBlock.substring(0, 8); //left block (32 bit)
- String RStr = cipherBlock.substring(8); //right block (32 bit)
- //converting left and right blocks to integers
- BigInteger L = new BigInteger(LStr, 16);
- BigInteger R = new BigInteger(RStr, 16);
- BigInteger sum= shiftLeft(delta,5);
- //32 rounds
- for(int i=0; i<32; i++)
- {
- R= subtract(R, (sum(shiftLeft(L,4),K[2])) .xor(sum(L,sum)) .xor(sum(shiftRight(L,5),K[3]))) ;
- L= subtract(L, (sum(shiftLeft(R,4),K[0])) .xor(sum(R,sum)) .xor(sum(shiftRight(R,5),K[1]))) ;
- //R= R.subtract( (L.shiftLeft(4).add(K[2])).xor(L.add(sum)).xor(L.shiftRight(5).add(K[3])) );
- //L= L.subtract( (R.shiftLeft(4).add(K[0])).xor(R.add(sum)).xor(R.shiftRight(5).add(K[1])) );
- sum = sum.subtract(delta);
- }
- //joining back the blocks as hex
- String plainTextBlock = "0x"+L.toString(16)+R.toString(16)+"";
- return plainTextBlock;
- }
- private BigInteger shiftLeft(BigInteger x, int steps)
- {
- BigInteger shifted=null;
- boolean negative =false;
- String xStr = x.toString(2);
- //removing negative sign while shifting (currently)
- if(xStr.charAt(0)=='-')
- {
- negative= true;
- xStr = xStr.substring(1);
- }
- int additionalSize = 32- xStr.length();
- for(int i=0; i<additionalSize; i++)
- xStr= "0"+xStr;
- for(int i=0; i<steps; i++)
- {
- xStr = xStr.substring(1);
- xStr = xStr+"0";
- }
- //one last addition of negative sign if the number is negative
- if(negative==true)
- xStr= "-"+xStr;
- //System.out.println(xStr);
- shifted = new BigInteger(xStr,2);
- return shifted;
- }
- private BigInteger shiftRight(BigInteger x, int steps)
- {
- BigInteger shifted=null;
- boolean negative = false;
- String xStr = x.toString(2);
- //removing negative sign while shifting (currently)
- if(xStr.charAt(0)=='-')
- {
- negative= true;
- xStr = xStr.substring(1);
- }
- int additionalSize = 32- xStr.length();
- for(int i=0; i<additionalSize; i++)
- xStr= "0"+xStr;
- for(int i=0; i<steps; i++)
- {
- xStr = xStr.substring(0,xStr.length()-1);
- xStr = "0"+xStr;
- }
- //one last addition of negative sign if the number is negative
- if(negative==true)
- xStr= "-"+xStr;
- shifted = new BigInteger(xStr,2);
- return shifted;
- }
- private BigInteger sum(BigInteger a, BigInteger b)
- {
- BigInteger sum = a.add(b);
- String sumStr = sum.toString(2);
- if(sumStr.length()>32)
- {
- int diff = sumStr.length()- 32;
- sumStr = sumStr.substring(diff);
- }
- BigInteger newSum = new BigInteger(sumStr,2);
- return newSum;
- }
- private BigInteger subtract(BigInteger a, BigInteger b)
- {
- BigInteger sub = a.subtract(b);
- String subStr = sub.toString(2);
- if(subStr.length()>32)
- {
- int diff = subStr.length()- 32;
- subStr = subStr.substring(diff);
- }
- BigInteger newSub = new BigInteger(subStr,2);
- return newSub;
- }
- public static void main(String[] args)
- {
- String plainText="0x0123456789ABCDEF";
- String key= "0xA56BABCD00000000FFFFFFFFABCDEF01";
- TEA tea = new TEA(key);
- String cipherText = tea.encryptBlock(plainText);
- System.out.println("Original Plain Text:"+plainText);
- System.out.println("CipherText:"+cipherText);
- System.out.println("Decrypted CipherText is:"+tea.decryptBlock(cipherText));
- }
Add Comment
Please, Sign In to add comment