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);
}
}