Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import java.io.IOException;
- public class RC5_32bit {
- private int W;
- private int R;
- private int Pw;
- private int Qw;
- public RC5_32bit(int rounds){
- R = rounds;
- W = 32;
- Pw = 0xb7e15163;
- Qw = 0x9e3779b9;
- }
- private int bytesInWord(byte[] byteArray) {
- int word = 0;
- int buff;
- for(int j = W/8 - 1, pos = 0; j >= 0; j --, pos+= 8){
- buff = 0;
- buff |= byteArray[j];
- buff <<= W - 8;
- buff >>>= W - 8;
- word |= (buff) << pos;
- }
- return word;
- }
- private void wordInBytes(int word , byte [] byteArray) {
- for (int i = W/8 - 1, pos = 8; i >= 0; i-- ){
- byteArray[i] = (byte) (word % 256);
- word >>>= pos;
- }
- }
- private int rotL(int val, int pas) {
- return (val << pas) | (val >>> (W - pas));
- }
- private int rotR(int val, int pas) {
- return (val >>> pas) | (val << (W - pas));
- }
- private int[] init_L(byte[] key) {
- int[] L = new int[key.length/ (W/8)];
- int buff;
- for (int i = 0; i < L.length; i++)
- for(int j = W/8 - 1, pos = 0; j >= 0; j --, pos+= 8){
- buff = 0;
- buff |= key[j];
- buff <<= W - 8;
- buff >>>= W - 8;
- L[i] |= (buff) << pos;
- }
- return L;
- }
- private byte[] keyConverter(byte[] key){
- int byteW = W / 8;
- byte[] result;
- if(key.length % byteW != 0){
- int append = byteW - (key.length % byteW);
- result = new byte[key.length + append];
- for(int i = 0; i < result.length; i++)
- if(i < key.length)
- result[i] = key[i];
- else
- result[i] = 0;
- }
- else
- result = key;
- return result;
- }
- private int[] paddling(int [] L , int length){
- int[] S = new int[2 * R + 1];
- S[0] = Pw;
- for(int q = 1; q < S.length; q++)
- S[q] = S[q - 1] + Qw;
- int A = 0;
- int B = 0;
- int i = 0, j = 0;
- int N = 3 * Math.max(W / 8, 2 * R + 1);
- for(int count = 0; count < N; count++){
- A = S[i] = rotL((S[i] + A + B), 3);
- B = L[j] = rotR((L[j] + A + B), (A + B));
- i = (i + 1) % (2 * R + 1);
- j = (j + 1) % (length/(W / 8));
- }
- return S;
- }
- private int[] keyExpansion(byte[] key){
- int [] L;
- key = keyConverter(key);
- L = init_L(key);
- return paddling(L, key.length);
- }
- private void encRounds(byte[] A, byte[] B, int[] S){
- if(R == 0)
- return;
- int Aw = bytesInWord(A);
- int Bw = bytesInWord(B);
- Aw += S[0];
- Bw += S[1];
- for(int r = 1; r < R; r++){
- Aw ^= Bw;
- Aw = rotL(Aw, Bw);
- Aw += S[2*r];
- Bw ^= Aw;
- Bw = rotL(Bw, Aw);
- Bw += S[2*r + 1];
- }
- wordInBytes(Aw , A);
- wordInBytes(Bw , B);
- }
- private void decRounds(byte[] A, byte[] B, int[] S){
- if(R == 0)
- return;
- int Aw = bytesInWord(A);
- int Bw = bytesInWord(B);
- for(int r = R - 1; r > 0; r--){
- Bw -= S[2*r + 1];
- Bw = rotR(Bw, Aw);
- Bw ^= Aw;
- Aw -= S[2*r];
- Aw = rotR(Aw, Bw);
- Aw ^= Bw;
- }
- Aw -= S[0];
- Bw -= S[1];
- wordInBytes(Aw, A);
- wordInBytes(Bw, B);
- }
- private void divideByTwo(byte[] data, byte[] p1, byte[] p2){
- for(int k = 0; k < data.length / 2; k++)
- p1[k] = data[k];
- for(int k = data.length / 2, j = 0; k < data.length; k++ , j++)
- p2[j] = data[k];
- }
- private void addParts(byte[] p1, byte[] p2, byte[] data){
- for(int k = 0; k < data.length / 2; k++)
- data[k] = p1[k];
- for(int k = data.length / 2, j = 0; k < data.length; k++ , j++)
- data[k] = p2[j];
- }
- public void encrypt(File in, File out, byte[] key) throws IOException{
- FileInputStream inputStream;
- FileOutputStream outputStream;
- inputStream = new FileInputStream(in);
- outputStream = new FileOutputStream(out);
- int blockLength = (2*W) / 8;
- int numbOfBlocks = (int) (in.length() / blockLength);
- byte[] data = new byte[blockLength];
- byte[] output = new byte[blockLength];
- int [] S = keyExpansion(key);
- byte[] part_1 = new byte[data.length / 2];
- byte[] part_2 = new byte[data.length / 2];
- int lengthFile = inputStream.available();
- for(int i = 0; i < numbOfBlocks; i++){
- for(int j = 0; j < blockLength; j++)
- data[j] = (byte) inputStream.read();
- divideByTwo(data, part_1, part_2);
- encRounds(part_1, part_2, S);
- addParts(part_1, part_2, output);
- outputStream.write(output, 0 , blockLength );
- }
- if(lengthFile % blockLength != 0){
- int remain = lengthFile % blockLength;
- for(int i = 0; i < remain; i++)
- data[i] = (byte) inputStream.read();
- data[remain] = 1;
- for(int i = remain + 1; i < blockLength; i++)
- data[i] = 0;
- divideByTwo(data, part_1, part_2);
- encRounds(part_1, part_2, S);
- addParts(part_1, part_2, output);
- outputStream.write(output, 0 , blockLength);
- }
- else {
- data[0] = 1;
- for(int i = 1; i < blockLength; i++)
- data[i] = 0;
- divideByTwo(data, part_1, part_2);
- encRounds(part_1, part_2, S);
- addParts(part_1, part_2, output);
- outputStream.write(output, 0 , blockLength);
- }
- inputStream.close();
- outputStream.close();
- }
- public void decrypt(File in, File out, byte[] key) throws IOException{
- FileInputStream inputStream;
- FileOutputStream outputStream;
- inputStream = new FileInputStream(in);
- outputStream = new FileOutputStream(out);
- int blockLength = (2*W) / 8;
- int numbOfBlocks = (int) (in.length() / blockLength);
- byte[] data = new byte[blockLength];
- byte[] output = new byte[blockLength];
- int [] S = keyExpansion(key);
- byte[] part_1 = new byte[data.length / 2];
- byte[] part_2 = new byte[data.length / 2];
- for(int i = 0; i < numbOfBlocks; i++){
- for(int j = 0; j < blockLength; j++)
- data[j] = (byte) inputStream.read();
- divideByTwo(data, part_1, part_2);
- decRounds(part_1, part_2, S);
- addParts(part_1, part_2, output);
- if (i == numbOfBlocks - 1) {
- boolean endFile = false;
- for (int j = 0; j < output.length; j++)
- if (output[j] == 1) {
- for (int k = j + 1; k < output.length; k++)
- if (output[k] == 0)
- endFile = true;
- else {
- endFile = false;
- break;
- }
- if (endFile)
- outputStream.write(output, 0, j);
- }
- }
- else
- outputStream.write(output, 0 , blockLength );
- }
- inputStream.close();
- outputStream.close();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement