Какой самый быстрый способ поиска пар с определенной входной разницей для использования в криптоанализе на DES? - PullRequest
0 голосов
/ 19 мая 2019

Я пытаюсь реализовать дифференциальный криптоанализ на 6-варианте DES, и мне нужно несколько пар с определенной входной разницей (deltaX).Какой самый быстрый способ сделать это?

Шифр ​​DES имеет 64-битный блок, что означает 8 букв. Я пробовал искать пары блок за блоком и букву за буквой, но количество возвращаемых пар было такиммало, даже когда я использовал длинные тексты, поэтому я пытался поиск по частям, но поиск занимает слишком много времени.

Вот функции, которые я использовал для поиска:

static double stringBlockLengthDouble=8.0;
static int stringBlockLength=8;
static int blockLengthInBits=64;

public static Pair[] searchForPairsBlockByBlock(byte[] OmegaP,byte[] initialKey,int rounds,String plaintext1,String plaintext2){
   ArrayList<ArrayList<String>> pairsString=new ArrayList<>();
   ArrayList<String> texts=new ArrayList<>();

   int plaintext1BlocksNum=(int)Math.ceil(plaintext1.length()/stringBlockLengthDouble);
   int plaintext2BlocksNum=(int)Math.ceil(plaintext2.length()/stringBlockLengthDouble);

   for(int i=0;i<plaintext1BlocksNum;i++){
        String plaintext1Block="";
        if(i<plaintext1BlocksNum-1){
            plaintext1Block=plaintext1.substring(i*stringBlockLength,(i+1)*stringBlockLength);
        }
        else{
            plaintext1Block=plaintext1.substring(i*stringBlockLength);

        }
        if(texts.contains(plaintext1Block)){
            continue;
        }
        byte[] plaintext1BinaryBlock=convertTextToBinaryArrayASCII(plaintext1Block);

        for(int j=0;j<plaintext2BlocksNum;j++){
            String plaintext2Block="";
            if(j<plaintext2BlocksNum-1){
                    plaintext2Block=plaintext2.substring(j*stringBlockLength,(j+1)*stringBlockLength);

             }
             else{
                    plaintext2Block=plaintext2.substring(j*stringBlockLength);

             }
             if(texts.contains(plaintext2Block)){
                continue;
             }

             byte[] plaintext2BinaryBlock=convertTextToBinaryArrayASCII(plaintext2Block);

             byte[] xor=DESCipher.xor(plaintext1BinaryBlock,plaintext2BinaryBlock);

            if(isEqualBinaryArray(xor, OmegaP)){
                 System.out.println("inside b");
                 texts.add(plaintext1Block);
                 texts.add(plaintext2Block);
                 ArrayList<String> onePairString=new ArrayList<>();
                 onePairString.add(plaintext1Block);
                 onePairString.add(plaintext2Block);
                 pairsString.add(onePairString);

            }
        }
   }

   Pair[] returned=new Pair[pairsString.size()];
   for(int i=0;i<pairsString.size();i++){
        byte[] plaintext1Binary=convertTextToBinaryArrayASCII(pairsString.get(i).get(0));
        returned[i]=new Pair(plaintext1Binary,OmegaP,initialKey,rounds);
   }
   return returned;
}



public static Pair[] searchForPairsBitByBit(byte[] OmegaP,byte[] initialKey,int rounds,String plaintext1,String plaintext2){
    ArrayList<ArrayList<String>> pairsString=new ArrayList<>();
    ArrayList<String> texts=new ArrayList<>();

    byte[] plaintext1Binary=convertTextToBinaryArrayASCII(plaintext1);
    byte[] plaintext2Binary=convertTextToBinaryArrayASCII(plaintext2);

    byte[] binaryBlock1=new byte[blockLengthInBits];
    byte[] binaryBlock2=new byte[blockLengthInBits]; 

    for(int i=0;i<plaintext1Binary.length-blockLengthInBits-1;i++){
        for(int blockIndex=0;blockIndex<blockLengthInBits;blockIndex++){
             binaryBlock1[blockIndex]=plaintext1Binary[i+blockIndex];
        }
        String block1Hex=DES_Analysis.convertBinaryArrayToHex(binaryBlock1);
        if(texts.contains(block1Hex)){
            continue;
        }
        for(int j=0;j<plaintext2Binary.length-blockLengthInBits-1;j++){
            for(int blockIndex=0;blockIndex<blockLengthInBits;blockIndex++){
                    binaryBlock2[blockIndex]=plaintext2Binary[j+blockIndex];
        }
        String block2Hex=DES_Analysis.convertBinaryArrayToHex(binaryBlock2);
        if(texts.contains(block2Hex)){
                continue;
        }
        byte[] xor=DESCipher.xor(binaryBlock1,binaryBlock2);

        if(isEqualBinaryArray(xor,OmegaP)){
                System.out.println("inside b");
                texts.add(block1Hex);
                texts.add(block2Hex);
                ArrayList<String> list=new ArrayList<>();
                list.add(block1Hex);
                list.add(block2Hex);
                pairsString.add(list);
        }
     }
  }

  Pair[] returned=new Pair[pairsString.size()];
  for(int i=0;i<pairsString.size();i++){
        byte[] binary1=DES_Analysis.convertHexToBinaryArray(pairsString.get(i).get(0));
        returned[i]=new Pair(plaintext1Binary,OmegaP,initialKey,rounds);
  }
  return returned;

}


public static Pair[] searchForPairsLetterByLetter(byte[] OmegaP,byte[] initialKey,int rounds,String plaintext1,String plaintext2){
    ArrayList<ArrayList<String>> pairsString=new ArrayList<>();
    ArrayList<String> texts=new ArrayList<>();

    int plaintext1BlocksNum=(int)Math.ceil(plaintext1.length()/stringBlockLengthDouble);
    int plaintext2BlocksNum=(int)Math.ceil(plaintext2.length()/stringBlockLengthDouble);

    for(int i=0;i<plaintext1.length();i++){
        String plaintext1Block="";
        if(i<plaintext1.length()-stringBlockLength){
                plaintext1Block=plaintext1.substring(i,i+stringBlockLength);
        }
        else{
            plaintext1Block=plaintext1.substring(i);
        }
        if(texts.contains(plaintext1Block)){
            continue;
        }

        byte[] plaintext1BinaryBlock=convertTextToBinaryArrayASCII(plaintext1Block);

        for(int j=0;j<plaintext2.length();j++){
            String plaintext2Block="";
            if(j<plaintext2.length()-stringBlockLength){
                    plaintext2Block=plaintext2.substring(j,j+stringBlockLength);

            }
            else{
                plaintext2Block=plaintext2.substring(j);
            }
            if(texts.contains(plaintext2Block)){
                continue;
            }

            byte[] plaintext2BinaryBlock=convertTextToBinaryArrayASCII(plaintext2Block);
            byte[] xor=DESCipher.xor(plaintext1BinaryBlock,plaintext2BinaryBlock);

            if(isEqualBinaryArray(xor,OmegaP)){
                System.out.println("inside b");
                texts.add(plaintext1Block);
                texts.add(plaintext2Block);
                ArrayList<String> onePairString=new ArrayList<>();
                onePairString.add(plaintext1Block);
                onePairString.add(plaintext2Block);
                pairsString.add(onePairString);

            }
        }
    }

    Pair[] returned=new Pair[pairsString.size()];
    for(int i=0;i<pairsString.size();i++){
        byte[] plaintext1Binary=convertTextToBinaryArrayASCII(pairsString.get(i).get(0));
        returned[i]=new Pair(plaintext1Binary,OmegaP,initialKey,rounds);
    }
    return returned;
}


...