Click here to Skip to main content
15,892,298 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I discovered that in java does not support 32 but integers. I had errors that i was getting when I had it in that form. So I switched over to BigInteger think it would fix this problem. So I kept on using BigInteger through the left and right shifting. Now i'm facing the problem of not getting the right output.
I'm using BigInteger to store a 128 byte key. But when running my code it's giving me the wrong output. And what i read was that it is possible to use masking which would solve this issue.

What I have tried:

when inputting the plaintText as: "0x0123456789ABCDEF"

Output is:

    Original Plain Text:0x0123456789ABCDEF
    CipherText:0xa0761126d09724fd
    Decrypted CipherText is:0x8d5a4a234b3c6720

But when i input: 0x123456789ABCDEF

The output is:

    Invalid block size!
    Original Plain Text:0x123456789ABCDEF
    CipherText:null


What am I doing wrong?

Here's my code: 

   
import java.math.BigInteger;
    
    public class TEA {
    
        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));
    
    
    
    
        }
    
    
    }
Posted
Updated 18-Feb-19 0:34am
v2
Comments
Richard Deeming 18-Feb-19 10:04am    
What makes you think Java doesn't support 32-bit integers?

Primitive Data Types (The Java™ Tutorials > Learning the Java Language > Language Basics)[^]
"int: By default, the int data type is a 32-bit signed two's complement integer, which has a minimum value of -231 and a maximum value of 231-1. In Java SE 8 and later, you can use the int data type to represent an unsigned 32-bit integer, which has a minimum value of 0 and a maximum value of 232-1. Use the Integer class to use int data type as an unsigned integer."
Chad3F 25-Mar-19 16:39pm    
Side note: Use key.startsWith("0x") instead of creating a sub-string and comparing that to "0x".

1 solution

I don't know what's wrong with your code, but it looks like you want to force doors wide open...

Java supoorts encryption/decryption via JCA[^]. So, i'd suggest to use JCA classes...
For example: Java Secure Hashing - MD5, SHA256, SHA512, PBKDF2, BCrypt, SCrypt[^]
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900