Я пытаюсь реализовать дифференциальный криптоанализ на 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;
}