使用java线程并行化AES

时间:2014-02-25 20:28:45

标签: java

以下是使用AES格式的方法的aes加密类:

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;


public class AESencrypt extends Thread{

private  int Nb = 4; // fjalet ne blloqe nga 4 per nje rresht
private  int Nk; // gjatesia e qelesit ne fjale
private int Nr; // numri i rundeve, = Nk + 6
private int wCount; // pozicioni ne w, per RoundKey 
private  AEStables tab; // te gjita tabelat qe nevojiten per AES-in
private  byte[] w; // qelesi i zgjeruar (expansion)
// AESencrypt: konstruktori. zgjeron qelesin


public AESencrypt(byte[] key, int NkIn)  {
    Thread t=new Thread();
    t.start();
    Nk = NkIn; // nr i fjaleve tek qelesi, duhet jete 4, 6 ose 8
    Nr = Nk + 6; // nr korrespondues i roundeve
    tab = new AEStables(); // klases qe i jepen vlerat per funksione te ndryshme
    w = new byte[4*Nb*(Nr+1)]; // zona per zgjerim te qelsit
    KeyExpansion(key, w); // gjatesia e w varet nga Nr
    t.interrupt();
}

public void Cipher(final byte[] in, final byte[] out) {
   Thread t1=new Thread();
   t1.start();
    wCount = 0; // numero bajtet ne KeyExpansion permes enkriptimit
    byte[][] state = new byte[4][Nb]; // vargu i gjendjes(state)
    Copy.copy(state, in); // kopjimi aktual i komponenteve(menyre e menqur) 
    AddRoundKey(state); // xor me qelesin e zgjeruar
    for (int round = 1; round < Nr; round++) {
          //Print.printArray("Start round " + round + ":", state);
        SubBytes(state); // zevendesimi S-box(substitution)

        ShiftRows(state); // perzierja e reshtave
        MixColumns(state); // perzierja e komplikuar e kolonave
        AddRoundKey(state); // xor me qelesin e zgjeruar

    }
    //Print.printArray("Start round " + Nr + ":", state);
    SubBytes(state); // zevendesimi S-box (substitution)
    ShiftRows(state); // perzierja e rreshtave
    AddRoundKey(state); // xor me qelesin e zgjeruar
    Copy.copy(out, state);


}

private void KeyExpansion(byte[] key, byte[] w)  {
    Thread t2=new Thread();`
    t2.start();`

    byte[] temp = new byte[4];
    // vetem kopjohet qelesi ne w
    int j = 0;
    while (j < 4*Nk) {
    w[j] = key[j++];
    }
    // ketu eshte j == 4*Nk;
    int i;
    while(j < 4*Nb*(Nr+1))  {
        i = j/4; // j gjithnje eshte shumefish i nr 4
        // trajton qdo gje dmth qdo fjale te njesi kohe, 4 bajta per nje njesi kohe
        for (int iTemp = 0; iTemp < 4; iTemp++)
            temp[iTemp] = w[j-4+iTemp];
        if (i % Nk == 0) {
                byte ttemp, tRcon;
                byte oldtemp0 = temp[0];
                for (int iTemp = 0; iTemp < 4; iTemp++) {
                        if (iTemp == 3) ttemp = oldtemp0;
                        else ttemp = temp[iTemp+1];
                        if (iTemp == 0) tRcon = tab.Rcon(i/Nk);
                        else tRcon = 0;
                        temp[iTemp] = (byte)(tab.SBox(ttemp) ^ tRcon);
                }
        }
        else if (Nk > 6 && (i%Nk) == 4) {
                for (int iTemp = 0; iTemp < 4; iTemp++)
                temp[iTemp] = tab.SBox(temp[iTemp]);
            }
        for (int iTemp = 0; iTemp < 4; iTemp++)
        w[j+iTemp] = (byte)(w[j - 4*Nk + iTemp] ^ temp[iTemp]);
            j = j + 4;
       t2.interrupt();
     }

}
private void SubBytes(byte[][] state) {   
    for (int row = 0; row < 4; row++){
        for (int col = 0; col < Nb; col++)
            {state[row][col] = tab.SBox(state[row][col]);
            }
      }
}

private void ShiftRows(byte[][] state) 
{   byte[] t = new byte[4];
    for (int r = 1; r < 4; r++) {
        for (int c = 0; c < Nb; c++)
            t[c] = state[r][(c + r)%Nb];
        for (int c = 0; c < Nb; c++)
        state[r][c] = t[c];
        }
}

private void MixColumns(byte[][] s) {

    int[] sp = new int[4];
    byte b02 = (byte)0x02, b03 = (byte)0x03;
    for (int c = 0; c < 4; c++) {
        sp[0] = tab.FFMul(b02, s[0][c]) ^ tab.FFMul(b03, s[1][c]) ^s[2][c] ^ s[3][c];
        sp[1] = s[0][c] ^ tab.FFMul(b02, s[1][c]) ^tab.FFMul(b03, s[2][c]) ^ s[3][c];
        sp[2] = s[0][c] ^ s[1][c] ^tab.FFMul(b02, s[2][c]) ^ tab.FFMul(b03, s[3][c]);
        sp[3] = tab.FFMul(b03, s[0][c]) ^ s[1][c] ^s[2][c] ^ tab.FFMul(b02, s[3][c]);
        for (int i = 0; i < 4; i++) 
            s[i][c] = (byte)(sp[i]);
    }
}

private void AddRoundKey(byte[][] state) {
    for (int c = 0; c < Nb; c++){
        for (int r = 0; r < 4; r++){
             state[r][c] = (byte)(state[r][c] ^ w[wCount++]);
           }
    }  
}

主要方法:

public class AEStest{
private static String koha;
public static void main(String[] args) throws IOException, InterruptedException {
 // per qelesin 128-bit, perdorim me poshte 16, 16, dhe 4
    // per qelesin 192-bit, perdorim me poshte 16, 24 dhe 6
    // per qelesin 256-bit, perdorim me poshte 16, 32 dhe 8 

    long startTime = System.currentTimeMillis();
    long fillimiTestit = new java.util.Date().getTime();

    //kodi me ane te paralelizimit
    int ch=1024;//nr i karaktereve hyres(percakton madhesine e fajllit)
    GetBytes getInput = new GetBytes("C:\\Users\\...\\Desktop\\plaintext.txt", ch);//teksti per enkriptim
    GetBytes getKey = new GetBytes("C:\\Users\\...\\Desktop\\key1.txt", 16);//qelesi
    //AESencrypt aes = new AESencrypt(key, 4);
    byte[] key = getKey.getBytes();
    byte[] out = new byte[16]; 
    byte[] input = getInput.getBytes();
    Print.printArray("PlainText  ",input);
    Print.printArray("Qelesi:    ", key);
    int i=0;
    byte[] in = new byte[ch];
    System.out.print("Ciphertext: ");


    //long fillimiTestit = new java.util.Date().getTime();

    List< Future> futuresList = new ArrayList< Future>();
    int nrProcesoreve = Runtime.getRuntime().availableProcessors();
    AESencrypt aes = new AESencrypt(key, 4);
    ExecutorService eservice = Executors.newFixedThreadPool(nrProcesoreve);
    //AESencrypt aes = new AESencrypt(key, 4);
    for (int index = 0; index < ch/16; index++) {


        futuresList.add(eservice.submit(aes));

            in = getInput.getBytes();
            aes.Cipher(in,out);
            Print.printo(out);

            i++; 
    }

    Object objRezultati;
    for (Future future : futuresList) {
        try {
             // lexohet rezultati nese eshte i gatshem nga te gjitha threadat ne ekzekut
            objRezultati = future.get();
            System.out.println("Rezultati " + objRezultati);
        } catch (    InterruptedException | ExecutionException e) {
        }
    }
   // Double sekonda = new Double((new java.util.Date().getTime() - fillimiTestit) * 0.001);
    //koha = "Kohezgjatja " + sekonda + " sekonda";
    //System.out.println(koha);
    long endTime = System.currentTimeMillis();
    System.out.println("\n U ekzekutua per " + (endTime - startTime) + " milliseconds");
}

}

我使用ExecutorService进行线程并行化,但没有减少处理时间。我可以得到任何建议。

1 个答案:

答案 0 :(得分:1)

您创建和启动线程的方式不提供任何有意义的多线程。

Thread t=new Thread();
t.start();

以上所有代码都是创建一个线程并生成一个空的run()方法。你在多个地方这样做,它没有任何好处。请参阅Thread文档,因为它提供了有关创建和启动线程的两种方法的示例。

从设计角度来看,更喜欢涉及实施Runnable的方法。这样做会强制执行开发合同,使您的代码块不仅可以在线程中使用,而且可以在所有Java的并发功能中使用。

要开始使用,请使用AEStest班级实施Runnable,而不是延长Thread

public class AEStest implements Runnable {
    public AEStest(byte[] key, int NkIn) {
        super();
        // your constructor code
        // do not do any thread processing here
    }

    public void run() {
        // your thread processing code here
    }
}

通过定义该类,您可以通过使用AEStest实例作为线程的可运行目标简单地构造线程来生成一个或多个线程:

for (int i = 0; i < numberOfThreads; ++i) {
    Thread t = new Thread(new AEStest(...));
    t.start();
}