limoilux.org

Articles des members du comité des logiciels libres du Cégep Limoilou.

Browsing Posts published by dbernard

Ca fait quelque temps que je travail sur mon encrypteur, et j’ai enfin réussi a fait de quoi qui marche.
Le code n’est pas complet, mais je croit que ca marche assez bien pour que j appelle ca un “proof of concept”.
Freya utilise un générateur de hasard pour creer les 16 sous-clés qui serve a son “réseau de Feistel”, ce qui le rend
en théorie invincible a une analyse des fréquences. Pour des raison pratique j’utilise une clé de 4 caractères de long,
mais ca serai facile de la rallonger.

Text.Java

package freyaCipher;

/* Preuve du Concept
 * Freya
 *
 * Encrypteur/décrypteur
 * La clef doit avoir 4 caracteres de long( pourrai eventuellement amilioré )
 * Par David Bernard (dbernard456@gmail.com)
 * Le 14 aout 2010
 *
 */

public class Text {
	private Key myKey;
	private Block[] myBlock;
	private char[] textBody;

	private int originalLength;
	private int adaptedLength;
	private int blockCount;

	public Text(String inputText) {
		textBody = inputText.toCharArray();
		originalLength = inputText.length();
		setParam();
		Encrypt("ABC5");
		Decrypt("ABC5");

	}

	public void Encrypt(String key) {
		prepare();
		myKey = new Key(key);
		for(int round = 0; round < 16; round++) {
			for(int i = 0; i < blockCount; i++) {
				myBlock[i].encode(myKey.getSubKey(round));
			}
		}
		readEachBlock();
		printText();
		printBlocks();

	}

	public void Decrypt(String key) {
		myKey = new Key(key);
		for(int round = 15; round >= 0; round--) {
			for(int i = 0; i < blockCount; i++) {
				myBlock[i].decode(myKey.getSubKey(round));
			}
		}
		revert();
		printText();
		printBlocks();
	}

	private void setParam() {
		setBlockCount();
		setAdaptedLength();
	}

	private void prepare() {
		adaptTextBody();
		setBlocks();
		permuteEachBlocks();
		readEachBlock();
	}

	private void readEachBlock() {
		for (int i = 0; i < blockCount; i++) {
			readBlock(i);
		}
	}

	private void readBlock(int blockIndex) {
		char[] buffer = myBlock[blockIndex].getBlock().toCharArray();
		int position;
		for(int i = 0; i < 8; i++) {
			position = i + (blockIndex * 8);
			textBody[position] = buffer[i];
		}
	}

	private void permuteEachBlocks() {
		for (int i = 0; i < blockCount; i++) {
			myBlock[i].permute();
		}
	}

	private void revert() {
		permuteEachBlocks();
		readEachBlock();
		unadaptTextBody();
	}

	private void unadaptTextBody() {
		char[] buffer;
		buffer = textBody;
		textBody = new char[originalLength];
		for(int i = 0; i < originalLength; i++) {
			textBody[i] = buffer[i];
		}
	}

	private void adaptTextBody() {
		char[] buffer;
		buffer = textBody;
		textBody = new char[adaptedLength];
		for(int i = 0; i < adaptedLength; i++) {
			textBody[i] = buffer[i % originalLength];
		}
	}

	private void setBlockCount() {
		blockCount = originalLength / 8;
		if((originalLength % 8 ) > 0) blockCount++;
	}

	private void setAdaptedLength() {
		adaptedLength = blockCount * 8;
	}

	private void setBlocks() {
		myBlock = new Block[blockCount];
		for(int i = 0; i < blockCount; i++) {
			createBlock(i);
		}
	}

	private void createBlock(int blockIndex) {
		char[] buffer = new char[8];
		String blockText;
		int position;
		for(int i = 0; i < 8; i++) {
			position = i + (blockIndex * 8);
			buffer[i] = textBody[position];
		}
		blockText = String.valueOf(buffer);
		myBlock[blockIndex] = new Block(blockText);
	}

	public String getText() {
		String output = String.valueOf(textBody);
		return output;
	}

	public void printText() {
		System.out.println(String.valueOf(textBody));
	}

	public void printBlocks() {

		for (int i = 0; i < blockCount; i++) {
			System.out.println("(" + i + ") " + myBlock[i].getBlock());
		}
		System.out.println();
	}
}

LCG.Java

package freyaCipher;

public class LCG {

	private int seed;
	private int modulus;
	private int multiplier;
	private int length;
	private int[] value;

	public LCG(int seed, int modulus, int multiplier, int length) {
		this.seed = seed;
		this.modulus = modulus;
		this.multiplier = multiplier;
		this.length = length;
		generate();
	}

	public int getValue(int position) {
		return value[position];
	}

	public void printSequency() {
		for(int i = 0; i < length ;i++) {
		System.out.print(value[i] + ", ");
		}
	}

	private void generate() {
		value = new int[length];
		value[0] = generateValue(seed);
		generateAllValue();
	}

	private void generateAllValue() {
		for(int i = 1; i < length; i++) {
			value[i] = generateValue(value[i - 1]);
		}
	}

	private int generateValue(int arg) {
		return (arg * multiplier) % modulus;
	}
}

Block.Java

package freyaCipher;

public class Block {

	private char[] collection = new char[8];

	public Block(String collection) {
		this.collection = collection.toCharArray();
	}

	public String getBlock() {
		return String.valueOf(collection);
	}

	public void permute() {
		char[] buffer;
		buffer = collection;
		collection = new char[8];
		collection[0] = buffer[0];
		collection[1] = buffer[3];
		collection[2] = buffer[5];
		collection[3] = buffer[1];
		collection[4] = buffer[6];
		collection[5] = buffer[2];
		collection[6] = buffer[4];
		collection[7] = buffer[7];
	}

	public void encode(String subKey) {
		char[] key = subKey.toCharArray();
		char[] buffer = collection;
		collection = new char[8];
		collection[0] = (char)((buffer[4] ^ key[0])^buffer[0]);
		collection[1] = (char)((buffer[5] ^ key[1])^buffer[1]);
		collection[2] = (char)((buffer[6] ^ key[2])^buffer[2]);
		collection[3] = (char)((buffer[7] ^ key[3])^buffer[3]);
		collection[4] = buffer[0];
		collection[5] = buffer[1];
		collection[6] = buffer[2];
		collection[7] = buffer[3];
	}

	public void decode(String subKey) {
		char[] key = subKey.toCharArray();
		char[] buffer = collection;
		collection = new char[8];
		collection[0] = buffer[4];
		collection[1] = buffer[5];
		collection[2] = buffer[6];
		collection[3] = buffer[7];
		collection[4] = (char)((buffer[4]^buffer[0])^key[0]);
		collection[5] = (char)((buffer[5]^buffer[1])^key[1]);
		collection[6] = (char)((buffer[6]^buffer[2])^key[2]);
		collection[7] = (char)((buffer[7]^buffer[3])^key[3]);
	}
}

Key.Java

package freyaCipher;

public class Key {
	int[] seed = new int[4];
	char[][] subKey = new char[4][16];
	char[] key;
	int modulus = 251;
	int multiplier = 13;

	public Key(String key) {
		this.key = key.toCharArray();
		generateSubKey();
	}

	private void generateSubKey() {
		generateAllSeed();
		LCG[] myLCG = new LCG[4];
		for(int i = 0; i < 4; i++)  {
			myLCG[i] = new LCG(seed[i], modulus, multiplier, 16);
			for(int j = 0; j < 16; j++) {
				subKey[i][j] = (char)myLCG[i].getValue(j);
			}
		}
	}

	private void generateAllSeed() {
		for(int i = 0; i < 4; i++) {
			generateSeed(i);
		}
	}

	private void generateSeed(int seedIndex) {
		seed[seedIndex]	= (int)key[seedIndex];
	}

	public String getSubKey(int roundIndex) {
		char[] buffer = new char[4];
		buffer[0] = subKey[0][roundIndex];
		buffer[1] = subKey[1][roundIndex];
		buffer[2] = subKey[2][roundIndex];
		buffer[3] = subKey[3][roundIndex];
		return String.valueOf(buffer);
	}
}

C’est un petit défi que je m’était donné, comprendre conment un peut faire une addition avec seulement des OR et des AND. J ai dessiner des transistor et j’ai voulu les tester avec des transistors virtuels. Bien que j’aille trouver dans les livre une version pas mal plus simple du circuit, je suis quand même fier de moi d’avoir trouver quelque chose qui marchait tout seul, même si c’est loin d’être efficace.
————————–

package logicAdder;

public class AdderUnit {

	// Additioneur logique revision 1 20100521, par David Bernard, dbernard456@gmail.com

	public static boolean[] calculateSum (boolean inputA[], boolean inputB[], int outputLength) {

		boolean output[] = new boolean[outputLength];
		boolean buffer[] = new boolean[2];
		boolean remain   = false;    

		for(int i = 0; i < outputLength; i++) {
			buffer    = AdderUnit.compute(inputA[i], inputB[i], remain);
			output[i] = buffer[0];
			remain    = buffer[1];
		}

		return output;
	}

	private static boolean[] compute(boolean a, boolean b, boolean c) {
		boolean output[] = new boolean[2]; 

		boolean midVal = AdderUnit.allTrueUnit(a, b, c);
		boolean[] leftVal = AdderUnit.sumBody(a, b, c);
		boolean[] rightVal = AdderUnit.residBody(a, b, c);
		output[0] = AdderUnit.orUnit(leftVal, midVal);
		output[1] = AdderUnit.orUnit(rightVal, midVal);
		return output;
	}
	private static boolean[] sumBody(boolean a, boolean b, boolean c) {
		boolean output[] = new boolean[3];

		output[0] = AdderUnit.sumUnit(a, b, c);
		output[1] = AdderUnit.sumUnit(b, c, a);
		output[2] = AdderUnit.sumUnit(c, a, b);
		return output;
		}

	private static boolean[] residBody(boolean a, boolean b, boolean c) {
		boolean output[] = new boolean[3];

		output[0] = AdderUnit.residUnit(b, c, a);
		output[1] = AdderUnit.residUnit(c, a, b);
		output[2] = AdderUnit.residUnit(a, b, c);
		return output;
		}

	private static boolean residUnit(boolean input1,boolean input2, boolean input3){
		boolean buffer = false;
		if(input1 && input2) buffer = true;
		if(buffer && !input3)
			return true; else return false;
	}

	private static boolean sumUnit(boolean input1, boolean input2,boolean input3){
		boolean buffer = false;
		if(input1 || input2) buffer = true;
		if(!buffer && input3)
			return true; else return false;
	}

	private static boolean allTrueUnit(boolean input1,boolean input2,boolean input3){
		boolean buffer = false;
		if(input1 && input2) buffer = true;
		if(buffer && input3)
			return true; else return false;
	}

	private static boolean orUnit(boolean[] args, boolean input) {

		boolean buffer[] = new boolean[2];

		if(args[0] || args[1])
			buffer[0] = true; else buffer[0] = false;

		if(args[2] || input)
			buffer[1] = true; else buffer[1] = false;

		if(buffer[0] || buffer[1])
			return true; else return false;
	}

}