Для реализации генетического алгоритма в OPS добавлены следующие функции:
Функция порождения ключа-«ребенка» по заданным параметрам
void ops_data_breed (struct ops_data ops,
void *parent_key1, void *parent_key2, void
*child_key)
Выбор родителей для скрещивания реализован в gen.c. В качестве варианта селекции
реализована турнирная селекция.
128
В функции static struct genotype* gen_select_tournament(struct gen *p) происходит
проведение турниров, в которых выбирают одного победителя из текущей популяции с
учетом наилучшего значения фитнесс-функции и функции
static void gen_select(struct gen *p,struct genotype **parent1,struct genotype **parent2),
которая выбирает двух различных победителей турниров, которые будут являться
родителями.
Функция формирования начальных параметров алгоритма, инициализация алгоритма
int gen_init(struct gen *p, struct gen_cfg *cfg, struct ops_data *ops,
void *orig_text, void *orig_cipher,
int generations, int population_size,
double (*fitness)(struct gen *p, void *key),
void (*select)(struct gen *p, struct genotype **parent1, struct genotype
**parent2),
void *priv);
Выделение памяти, определение функций отбора родителей, определения значения фитнесс-
функции.
Основная функция работы генетического алгоритма
void gen_run(struct gen *p)
Эта функция работает следующим образом:
Вызов функций муравьиного алгоритма для DES и AES определен соответственно в
заголовочных файлах:
gen_aes.h
gen_des.h
Значение основных параметров для работы алгоритма задается для AES и DES
соответственно в функциях: int test_gen_aes() и int test_gen_des()
char
password[33]
= "CotaFota"
ключ для тестового примера
parents_to_keep
количество родителей, которое будет сохранятся в
следующем поколении, с учетом значения фитнесс-
функции
mutation_rate
скорость мутации, значение должно быть меньше
1.
delta
величина, используемая для определения того,
будет ли
бит ключа сохраняться как определенный,
то есть
найденный.
В случае генетического алгоритма для AES и DES параметры функции инициализации
совпадают:
gen_init(&gen, &cfg, &ops, text, cipher, generations, population_size, NULL, NULL,
NULL, f_out);
&gen
указатель на управляющую структуру генетического
алгоритма
&cfg
дополнительные параметры алгоритма
&ops
указатель на объект, содержащий параметры заданного
шифрования,
операции с ключами
text
оригинальный нешифрованный текст
cipher
шифрованный текст
generations
количество поколений
population
размер популяции
NULL
финтесс-функция по умолчанию
NULL
функция селекции по умолчанию
NULL
дополнительные данные не нужны
f_out
поток ввода-вывода
68
ILOVA
ops.h
#ifndef __OPS_DATA_H__
#define __OPS_DATA_H__
#include
enum ops_data_type
{
OPS_DATA_CIPHER,
OPS_DATA_TEXT,
OPS_DATA_KEY
};
struct ops_data
{
int key_length;
int text_length;
int cipher_length;
void* (*allocate)(struct ops_data *ops, enum ops_data_type type);
void (*destroy)(struct ops_data *ops, enum ops_data_type type, void *data);
void (*random)(struct ops_data *ops, enum ops_data_type type, void *data);
int (*get_bit)(struct ops_data *ops, enum ops_data_type type, void *data, int n);
void (*set_bit)(struct ops_data *ops, enum ops_data_type type, void *data, int n, int value);
void (*print)(struct ops_data *ops, enum ops_data_type type, void *data, FILE *f);
void (*print_pos)(struct ops_data *ops, enum ops_data_type type, void *data, FILE *f);
void (*copy)(struct ops_data *ops, enum ops_data_type type, void *src, void *dst);
void (*cipher)(struct ops_data *ops, void *text, void *key, void *cipher);
void (*breed)(struct ops_data *ops, void *parent_key1, void *parent_key2, void *child_key);
void (*mutate)(struct ops_data *ops, void *key, double mutation_rate);
};
void ops_data_init(struct ops_data *ops);
#endif // __OPS_DATA_H__
ops_aes.h
#ifndef __OPS_DATA_AES_H__
#define __OPS_DATA_AES_H__
#include "ops/ops.h"
void ops_data_init_aes(struct ops_data *ops, int key_length);
#endif // __OPS_DATA_AES_H__
ops_des.h
#ifndef __OPS_DATA_DES_H__
#define __OPS_DATA_DES_H__
69
#include "ops/ops.h"
void ops_data_init_des(struct ops_data *ops);
#endif // __OPS_DATA_DES_H__
ops.c
#include
#include
#include
#include
#include
#include
#include
#include "ops/ops.h"
static inline int ops_data_get_length(struct ops_data *ops, enum ops_data_type type)
{
switch(type)
{
case OPS_DATA_CIPHER:
return ops->cipher_length;
case OPS_DATA_TEXT:
return ops->text_length;
case OPS_DATA_KEY:
return ops->key_length;
}
return 0;
}
void* ops_data_allocate(struct ops_data *ops, enum ops_data_type type)
{
return malloc((ops_data_get_length(ops, type) + 7) / 8);
}
void ops_data_destroy(struct ops_data *ops, enum ops_data_type type, void *data)
{
(void)ops;
(void)type;
free(data);
}
void ops_data_random(struct ops_data *ops, enum ops_data_type type, void *data)
{
char *x = data;
int i, len = (ops_data_get_length(ops, type) + 7) / 8;
for(i = 0; i < len; i++) x[i] = rand() & 0xff;
}
70
int ops_data_get_bit(struct ops_data *ops, enum ops_data_type type, void *data, int n)
{
char *x = data;
(void)ops;
(void)type;
return (x[n / 8] >> (n % 8)) & 0x01;
}
void ops_data_set_bit(struct ops_data *ops, enum ops_data_type type, void *data, int n, int value)
{
char *x = data, mask = (1 << (n % 8));
(void)ops;
(void)type;
if (value) x[n / 8] |= mask;
else x[n / 8] &= ~mask;
}
void ops_data_print_pos(struct ops_data *ops, enum ops_data_type type, void *data, FILE *f)
{
int i, len = ops_data_get_length(ops, type);
for(i = 0; i < len; i++)
{//fprintf(f, "%d", i);
fprintf(f, " [%d]-%d", i, ops->get_bit(ops, type, data, i));
}
fflush(f);
}
void ops_data_print(struct ops_data *ops, enum ops_data_type type, void *data, FILE *f)
{
int i, len = ops_data_get_length(ops, type);
for(i = 0; i < len; i++)
{//fprintf(f, "%d", i);
fprintf(f, "%d", ops->get_bit(ops, type, data, i));
}
fflush(f);
}
void ops_data_copy(struct ops_data *ops, enum ops_data_type type, void *src, void *dst)
{
memcpy(dst, src, (ops_data_get_length(ops, type) + 7) / 8);
}
void ops_data_breed(struct ops_data *ops, void *parent_key1, void *parent_key2, void
*child_key)
71
{
int i, pos;
void *tmp;
pos = rand() % (2 * (ops->key_length - 1));
if (pos >= ops->key_length - 1)
{
// swap parents
tmp = parent_key1;
parent_key1 = parent_key2;
parent_key2 = tmp;
// fix position
pos -= ops->key_length - 1;
}
//fprintf(stdout, "pos\t\%d\n", pos);
for(i = 0; i <= pos; i++)
{
ops->set_bit(ops, OPS_DATA_KEY, child_key, i, ops->get_bit(ops, OPS_DATA_KEY,
parent_key1, i));
}
for(i = pos + 1; i < ops->key_length; i++)
{
ops->set_bit(ops, OPS_DATA_KEY, child_key, i, ops->get_bit(ops, OPS_DATA_KEY,
parent_key2, i));
}
}
void ops_data_mutate(struct ops_data *ops, void *key, double mutation_rate)
{
int i;
for(i = 0; i < ops->key_length; i++)
{
if (rand() < (int)(mutation_rate * RAND_MAX)){
ops->set_bit(ops, OPS_DATA_KEY, key, i, !ops->get_bit(ops, OPS_DATA_KEY, key,
i));
}
}
}
void ops_data_init(struct ops_data *ops)
{
memset(ops, 0, sizeof(struct ops_data));
ops->allocate = ops_data_allocate;
ops->destroy = ops_data_destroy;
ops->random = ops_data_random;
ops->get_bit = ops_data_get_bit;
ops->set_bit = ops_data_set_bit;
ops->print = ops_data_print;
72
ops->copy = ops_data_copy;
ops->breed = ops_data_breed;
ops->mutate = ops_data_mutate;
}
ops_aes.c
#include
#include
#include
#include
#include
#include "cipher/aes.h"
#include "ops/ops_aes.h"
static void ops_data_cipher_aes(struct ops_data *ops, void *text, void *key, void *cipher)
{
struct aes_parameter param;
aes_init(¶m, key, ops->key_length, 0);
aes_encode(¶m, text, cipher);
}
void ops_data_init_aes(struct ops_data *ops, int key_length)
{
ops_data_init(ops);
ops->key_length = key_length;
ops->text_length = 128;
ops->cipher_length = 128;
ops->cipher = ops_data_cipher_aes;
}
ops_des.c
#include
#include
#include
#include
#include
#include "cipher/des.h"
#include "ops/ops_des.h"
static void* ops_data_allocate_des(struct ops_data *ops, enum ops_data_type type)
{
(void)ops;
(void)type;
return malloc(sizeof(uint64_t));
}
73
static void ops_data_random_des(struct ops_data *ops, enum ops_data_type type, void *data)
{
uint64_t *p = data;
int i;
(void)ops;
*p = 0;
for(i = 0; i < (int)sizeof(uint64_t); i++)
{
*p |= ((uint64_t)(rand() & 0xff)) << (i * 8);
}
if (type == OPS_DATA_KEY) *p &= 0x7f7f7f7f7f7f7f7fULL;
}
static int ops_data_get_bit_des(struct ops_data *ops, enum ops_data_type type, void *data, int n)
{
(void)ops;
switch (type)
{
case OPS_DATA_KEY:
return ((*((uint64_t*)data)) >> (8 * (n / 7) + (n % 7))) & 0x01;
default:
return ((*((uint64_t*)data)) >> n) & 0x01;
}
}
static void ops_data_set_bit_des(struct ops_data *ops, enum ops_data_type type, void *data, int n,
int value)
{
uint64_t mask;
(void)ops;
switch (type)
{
case OPS_DATA_KEY:
mask = (1UL << (8 * (n / 7) + (n % 7)));
break;
default:
mask = (1 << n);
break;
}
if (value) *((uint64_t*)data) |= mask;
else *((uint64_t*)data) &= ~mask;
}
static void ops_data_print_des(struct ops_data *ops, enum ops_data_type type, void *data, FILE
*f)
{
uint64_t x = *((uint64_t*)data);
int i;
74
(void)ops;
for(i = 0; i < 64; i++)
{
if (((i & 0x07) == 0x07) && (type == OPS_DATA_KEY)) fprintf(f, "x");
else fprintf(f, "%ld", (x >> i) & 0x01);
}
fflush(f);
}
static void ops_data_copy_des(struct ops_data *ops, enum ops_data_type type, void *src, void
*dst)
{
(void)ops;
(void)type;
*((uint64_t*)dst) = *((uint64_t*)src);
}
static void ops_data_cipher_des(struct ops_data *ops, void *text, void *key, void *cipher)
{
(void)ops;
*((uint64_t*)cipher) = des_encode(*((uint64_t*)text), *((uint64_t*)key));
}
void ops_data_init_des(struct ops_data *ops)
{
ops_data_init(ops);
ops->key_length = 56;
ops->text_length = 64;
ops->cipher_length = 64;
ops->allocate = ops_data_allocate_des;
ops->random = ops_data_random_des;
ops->get_bit = ops_data_get_bit_des;
ops->set_bit = ops_data_set_bit_des;
ops->print = ops_data_print_des;
ops->copy = ops_data_copy_des;
ops->cipher = ops_data_cipher_des;
}
ant.h
#ifndef __ANT_H__
#define __ANT_H__
#include
#include "ops/ops.h"
struct ant_cfg
{
double
alpha; // influencing factors of pheromone value
75
double
beta; // heuristic value of path quality
double
rho; // pheromone evaporation factor
double
gamma; // threshold value of optium key
double
delta; // threshold value to set bit as known
int
kappa; // number of known keys required to start key bit deriving
};
struct ant
{
struct ops_data *ops;
struct ant_cfg *cfg;
int
rounds;
int
iterations;
int
ant_count;
void
*orig_text;
void
*orig_cipher;
int
optimum_keys;
int
*optimum_keys_stat;
void
*best_iteration_key;
void
*test_key;
void
*test_cipher;
double
*tau;
int
*known_bit;
double
best_round_fitness;
void
*best_round_key;
void
(*tau_init)(struct ant *p);
double
(*fitness)(struct ant *p, void *key);
void
*priv; // private data
FILE
*f_out;
};
int ant_init(struct ant *p, struct ant_cfg *cfg, struct ops_data *ops,
void *orig_text, void *orig_cipher,
int rounds, int iterations, int ant_count,
double (*fitness)(struct ant *p, void *key),
void (*tau_init)(struct ant *p), void *priv, FILE *f_out);
void ant_run(struct ant *p);
void ant_done(struct ant *p);
#endif // __ANT_H__
ant_aes.h
#ifndef __ANT_AES_H__
#define __ANT_AES_H__
76
int test_ant_aes();
#endif // __ANT_AES_H__
ant_des.h
#ifndef __ANT_DES_H__
#define __ANT_DES_H__
int test_ant_des();
#endif // __ANT_DES_H__
ant.c
#include
#include
#include
#include
#include
#include "ant.h"
static double ant_fitness(struct ant *p, void *key)
{
struct ops_data *ops = p->ops;
int i, result = 0;
ops->cipher(ops, p->orig_text, key, p->test_cipher);
for(i = 0; i < ops->cipher_length; i++)
{
if (ops->get_bit(ops, OPS_DATA_CIPHER, p->orig_cipher, i) ==
ops->get_bit(ops, OPS_DATA_CIPHER, p->test_cipher, i)) result++;
}
if(p->rounds == 2)
{
fprintf(p->f_out, "\n");
fprintf(p->f_out, "Ant_fitness\n");
fprintf(p->f_out, "Orig_cipher : \n");
ops->print(ops, OPS_DATA_CIPHER, p->orig_cipher, p->f_out);
fprintf(p->f_out, "\n");
fprintf(p->f_out, "Test_cipher : \n");
ops->print(ops, OPS_DATA_CIPHER, p->test_cipher, p->f_out);
fprintf(p->f_out, "\n");
fprintf(p->f_out, "Test_key : \n");
ops->print(ops, OPS_DATA_KEY, key, p->f_out);
fprintf(p->f_out, "\n");
fprintf(p->f_out, "count equal = %u", result);
fprintf(p->f_out, "\n");
fprintf(p->f_out, "cipher_length = %u", ops->cipher_length);
fprintf(p->f_out, "\n");
77
fprintf(p->f_out, "return ant_fitness = %f", ((double)result) / ops->cipher_length);
fprintf(p->f_out, "\n");
}
return ((double)result) / ops->cipher_length;
}
static void ant_tau_init(struct ant *p)
{
struct ops_data *ops = p->ops;
int k;
memset(p->tau, 0, ops->key_length * (4 * sizeof(double)));
p->tau[0] = (0.5 / RAND_MAX) * rand();
p->tau[1] = (0.5 / RAND_MAX) * rand();
for(k = 1; k < ops->key_length; k++)
{
p->tau[4 * k + 0] = (0.25 / RAND_MAX) * rand();
p->tau[4 * k + 1] = (0.25 / RAND_MAX) * rand();
p->tau[4 * k + 2] = (0.25 / RAND_MAX) * rand();
p->tau[4 * k + 3] = (0.25 / RAND_MAX) * rand();
}
}
int ant_init(struct ant *p, struct ant_cfg *cfg, struct ops_data *ops,
void *orig_text, void *orig_cipher,
int rounds, int iterations, int ant_count,
double (*fitness)(struct ant *p, void *key),
void (*tau_init)(struct ant *p), void *priv, FILE *f_out)
{
int i;
memset(p, 0, sizeof (*p));
p->ops = ops;
p->cfg = cfg;
p->priv = priv;
p->rounds = rounds;
p->iterations = iterations;
p->ant_count = ant_count;
p->orig_text = orig_text;
p->orig_cipher = orig_cipher;
p->optimum_keys = 0;
p->best_round_fitness = -1;
p->f_out = (f_out == NULL) ? stdout : f_out;
p->fitness = (fitness == NULL) ? ant_fitness : fitness;
p->tau_init = (tau_init == NULL) ? ant_tau_init : tau_init;
p->tau = malloc(ops->key_length * (4 * sizeof(double)));
if (p->tau == NULL) goto error_tau;
78
memset(p->tau, 0, ops->key_length * (4 * sizeof(double)));
p->optimum_keys_stat = malloc(ops->key_length * sizeof(int));
if (p->optimum_keys_stat == NULL) goto error_optimum_keys_stat;
memset(p->optimum_keys_stat, 0, ops->key_length * sizeof(int));
p->known_bit = malloc(ops->key_length * sizeof(int));
if (p->known_bit == NULL) goto error_known_bit;
for(i = 0; i < ops->key_length; i++) p->known_bit[i] = -1;
p->test_cipher = ops->allocate(ops, OPS_DATA_CIPHER);
if (p->test_cipher == NULL) goto error_test_cipher;
p->test_key = ops->allocate(ops, OPS_DATA_KEY);
if (p->test_key == NULL) goto error_test_key;
p->best_round_key = ops->allocate(ops, OPS_DATA_KEY);
if (p->best_round_key == NULL) goto error_best_round_key;
p->best_iteration_key = ops->allocate(ops, OPS_DATA_KEY);
if (p->best_iteration_key == NULL) goto error_best_iteration_key;
return 1;
error_best_iteration_key:
ops->destroy(ops, OPS_DATA_KEY, p->best_round_key);
error_best_round_key:
ops->destroy(ops, OPS_DATA_KEY, p->test_key);
error_test_key:
ops->destroy(ops, OPS_DATA_CIPHER, p->test_cipher);
error_test_cipher:
free(p->known_bit);
error_known_bit:
free(p->optimum_keys_stat);
error_optimum_keys_stat:
free(p->tau);
error_tau:
memset(p, 0, sizeof (*p));
return 0;
}
void ant_done(struct ant *p)
{
struct ops_data *ops = p->ops;
ops->destroy(ops, OPS_DATA_KEY, p->best_iteration_key);
ops->destroy(ops, OPS_DATA_KEY, p->best_round_key);
ops->destroy(ops, OPS_DATA_KEY, p->test_key);
ops->destroy(ops, OPS_DATA_CIPHER, p->test_cipher);
free(p->known_bit);
free(p->optimum_keys_stat);
free(p->tau);
79
memset(p, 0, sizeof (*p));
}
void ant_run(struct ant *p)
{
struct ops_data *ops = p->ops;
struct ant_cfg *cfg = p->cfg;
double best_iteration_fitness, fitness;
double eta0, eta1, chance,
pow_tau0_alfa,
pow_tau1_alfa,
pow_eta0_beta,
pow_eta1_beta;
int
round, iteration, ant, k, bit, prev_bit, detected_bit;
detected_bit = 0;
p->optimum_keys = 0;
memset(p->optimum_keys_stat, 0, ops->key_length * sizeof(int));
for(k = 0; k < ops->key_length; k++) p->known_bit[k] = -1;
for(round = 0; round < p->rounds; round++)
{
fprintf(stdout, "round = %d\n", round);
//prepare initial values for tau(i,j)
p->tau_init(p);
p->best_round_fitness = -1;
for(iteration = 0; iteration < p->iterations; iteration++)
{
best_iteration_fitness = -1;
for(ant = 0; ant < p->ant_count; ant++)
{
if (iteration != 0)
{
// inintial value for concatenate key
ops->copy(ops, OPS_DATA_KEY, p->best_round_key, p->test_key);
}
if(p->rounds == 2)
{
fprintf(p->f_out, "\n");
fprintf(p->f_out, "START [ROUND %u] [ITERATION %u] [ANT %u]", round,
iteration, ant);
fprintf(p->f_out, "\n");
fprintf(p->f_out, "test_key : \n");
ops->print(ops, OPS_DATA_KEY, p->test_key, p->f_out);
fprintf(p->f_out, "\n");
}
80
// start of ant trip
prev_bit = 0;
for(k = 0; k < ops->key_length; k++)
{
if (iteration == 0)
{
eta0 = eta1 = 1;
}
else
{
ops->set_bit(ops, OPS_DATA_KEY, p->test_key, k, 0);
eta0 = p->fitness(p, p->test_key);
ops->set_bit(ops, OPS_DATA_KEY, p->test_key, k, 1);
eta1 = p->fitness(p, p->test_key);
}
// chance to select the case where k-th bit set to zero
//
chance = pow(p->tau[4 * k + 2 * prev_bit + 0], cfg->alpha) * pow(eta0, cfg->beta) /
//
(pow(p->tau[4 * k + 2 * prev_bit + 0], cfg->alpha) * pow(eta0, cfg->beta) +
//
pow(p->tau[4 * k + 2 * prev_bit + 1], cfg->alpha) * pow(eta1, cfg->beta));
pow_tau0_alfa = pow(p->tau[4 * k + 2 * prev_bit + 0], cfg->alpha);
pow_tau1_alfa = pow(p->tau[4 * k + 2 * prev_bit + 1], cfg->alpha);
pow_eta0_beta = pow(eta0, cfg->beta);
pow_eta1_beta = pow(eta1, cfg->beta);
chance = pow_tau0_alfa * pow_eta0_beta /
(pow_tau0_alfa * pow_eta0_beta +
pow_tau1_alfa * pow_eta1_beta);
bit = (rand() < (int)(RAND_MAX * chance)) ? 0 : 1;
ops->set_bit(ops, OPS_DATA_KEY, p->test_key, k, bit);
if(p->rounds==2) // round == 0 && iteration == 0 && ant == 0
{
fprintf(p->f_out, "\n");
fprintf(p->f_out, "[round %u] [iteration %u] [ant %u]", round, iteration, ant);
fprintf(p->f_out, "\n");
fprintf(p->f_out, "p-tau-0 [0 - 0] = %f", p->tau[4 * k + 0]);
fprintf(p->f_out, "\n");
fprintf(p->f_out, "p-tau-1 [0 - 1] = %f", p->tau[4 * k + 1]);
fprintf(p->f_out, "\n");
fprintf(p->f_out, "p-tau-2 [1 - 0] = %f", p->tau[4 * k + 2]);
fprintf(p->f_out, "\n");
fprintf(p->f_out, "p-tau-3 [1 - 1] = %f", p->tau[4 * k + 3]);
fprintf(p->f_out, "\n");
fprintf(p->f_out, "\n");
fprintf(p->f_out, "eta0 [round %u] [iteration %u] = %f", round, iteration, eta0);
fprintf(p->f_out, "\n");
81
fprintf(p->f_out, "beta = %f", cfg->beta);
fprintf(p->f_out, "\n");
fprintf(p->f_out, "pow_eta0_beta = %f", pow(eta0, cfg->beta));
fprintf(p->f_out, "\n");
fprintf(p->f_out, "p-tau-0 [bit %u] [ %u -> 0 ] = %f", k, prev_bit, p->tau[4 * k
+ 2 * prev_bit + 0]);
fprintf(p->f_out, "\n");
fprintf(p->f_out, "alpha = %f", cfg->alpha);
fprintf(p->f_out, "\n");
fprintf(p->f_out, "pow_tau0_alfa = %f", pow(p->tau[4 * k + 2 *
prev_bit + 0], cfg->alpha));
fprintf(p->f_out, "\n");
fprintf(p->f_out, "\n");
fprintf(p->f_out, "eta1 [round %u] [iteration %u] = %f", round, iteration, eta1);
fprintf(p->f_out, "\n");
fprintf(p->f_out, "beta = %f", cfg->beta);
fprintf(p->f_out, "\n");
fprintf(p->f_out, "pow_eta1_beta = %f", pow(eta1, cfg->beta));
fprintf(p->f_out, "\n");
fprintf(p->f_out, "p-tau-1 [bit %u] [ %u -> 1 ] = %f", k, prev_bit, p->tau[4 * k
+ 2 * prev_bit + 1]);
fprintf(p->f_out, "\n");
fprintf(p->f_out, "alpha = %f", cfg->alpha);
fprintf(p->f_out, "\n");
fprintf(p->f_out, "pow_tau1_alfa = %f", pow(p->tau[4 * k + 2 *
prev_bit + 1], cfg->alpha));
fprintf(p->f_out, "\n");
fprintf(p->f_out, "\n");
fprintf(p->f_out, "chance = pow_tau0_alfa * pow_eta0_beta / (pow_tau0_alfa *
pow_eta0_beta + pow_tau1_alfa * pow_eta1_beta) \n");
fprintf(p->f_out, "\n");
fprintf(p->f_out, "chance [bit %u] [prev_bit %u -> 0] = %f", k, prev_bit, chance);
fprintf(p->f_out, "\n");
fprintf(p->f_out, "RM [%u]* chance [bit %u] = %u", RAND_MAX, k,
(int)(RAND_MAX * chance));
fprintf(p->f_out, "\n");
fprintf(p->f_out, "bit [bit %u] = %u", k, bit);
fprintf(p->f_out, "\n");
fprintf(p->f_out,
"p->test_key
bit
[bit
%u]
=
%u",
k,
ops-
>get_bit(ops,OPS_DATA_KEY,p->test_key, k));
fprintf(p->f_out, "\n");
fprintf(p->f_out, "\n");
}
prev_bit = bit;
}
fitness = p->fitness(p, p->test_key);
if (fitness > best_iteration_fitness)
{
82
best_iteration_fitness = fitness;
ops->copy(ops, OPS_DATA_KEY, p->test_key, p->best_iteration_key);
}
if(fitness > p->best_round_fitness)
{
p->best_round_fitness = fitness;
ops->copy(ops, OPS_DATA_KEY, p->test_key, p->best_round_key);
}
if(p->rounds == 2)
{
fprintf(p->f_out, "\n");
fprintf(p->f_out, "Test_key : \n");
ops->print(ops, OPS_DATA_KEY, p->test_key, p->f_out);
fprintf(p->f_out, "\n");
fprintf(p->f_out, "fitness [round %u] [iteration %u] [ant %u] = %f", round,
iteration, ant, fitness);
fprintf(p->f_out, "\n");
fprintf(p->f_out, "best_iteration_fitness [round %u] [iteration %u] [ant %u] = %f",
round, iteration, ant, best_iteration_fitness);
fprintf(p->f_out, "\n");
fprintf(p->f_out, "best_round_fitness [round %u] [iteration %u] [ant %u] = %f",
round, iteration, ant, p->best_round_fitness);
fprintf(p->f_out, "\n");
}
}
// increase pheromon along best iteration way
double increment = best_iteration_fitness / log2(ops->key_length);
if(p->rounds == 2)
{
fprintf(p->f_out, "\n");
fprintf(p->f_out, "best_iteration_fitness = %f \n", best_iteration_fitness);
fprintf(p->f_out, "log2(ops->key_length) = %f \n", log2(ops-
>key_length));
fprintf(p->f_out, "increment [round %u] [iteration %u] [ant %u] = %f \n", round,
iteration, ant, increment);
}
prev_bit = 0;
if(p->rounds == 2)
{
fprintf(p->f_out, "\n");
fprintf(p->f_out, "Pheromons array increse \n"
"-------------------------\n"
"[round ---] [iteration -----] [bit ---]:\t"
"o[0-0]\to[0-1]\to[1-0]\to[1-1]\t"
"n[0-0]\tn[0-1]\tn[1-0]\tn[1-1]\n");
}
83
for(k = 0; k < ops->key_length; k++)
{
bit = ops->get_bit(ops, OPS_DATA_KEY, p->best_iteration_key, k);
if(p->rounds == 2)
{
fprintf(p->f_out, "[round %03u] [iteration %05u] [bit %03u]:\t", round, iteration, k);
fprintf(p->f_out, "%.5lf\t%.5lf\t%.5lf\t%.5lf\t", p->tau[4 * k + 0], p->tau[4 * k + 1], p-
>tau[4 * k + 2], p->tau[4 * k + 3]);
}
p->tau[4 * k + 2 * prev_bit + bit] += increment;
if(p->rounds == 2)
{
fprintf(p->f_out, "%.5lf\t%.5lf\t%.5lf\t%.5lf\t", p->tau[4 * k + 0], p->tau[4 * k + 1], p-
>tau[4 * k + 2], p->tau[4 * k + 3]);
fprintf(p->f_out, "\n");
}
prev_bit = bit;
}
// decrease pheromon
if(p->rounds == 2)
{
fprintf(p->f_out, "\n");
fprintf(p->f_out, "Pheromons array decrease \n"
"-------------------------\n"
"[round ---] [iteration -----] [bit ---]:\t"
"o[0-0]\tn[0-0]\to[0-1]\tn[0-1]\t"
"o[1-0]\tn[1-0]\to[1-1]\tn[1-1]\n");
}
for(k = 0; k < 4 * ops->key_length; k++)
{
if(p->rounds == 2)
{
if (k % 4 == 0)
{
fprintf(p->f_out, "[round %03u] [iteration %05u] [bit %03u]:\t", round, iteration, k /
4);
}
fprintf(p->f_out, "%.5lf\t", p->tau[k]);
}
p->tau[k] *= cfg->rho;
if(p->rounds == 2)
{
fprintf(p->f_out, "%.5lf\t", p->tau[k]);
if (k % 4 == 3) fprintf(p->f_out, "\n");
84
}
}
}
fprintf(p->f_out, "best_round_fitness [round %u] = %f\n", round, p->best_round_fitness);
if (p->best_round_fitness >= cfg->gamma)
{
p->optimum_keys++;
//fprintf(p->f_out, " best_round_fitness >= gamma [%f] [round %u] = %f \n", cfg-
>gamma, round, p->best_round_fitness);
fprintf(p->f_out, " optimum key %d found\n"
" key: ", p->optimum_keys);
ops->print(ops, OPS_DATA_KEY, p->best_round_key, p->f_out);
fprintf(p->f_out, "\n");
ops->cipher(ops, p->orig_text, p->best_round_key, p->test_cipher);
fprintf(p->f_out, " o_c: ");
ops->print(ops, OPS_DATA_CIPHER, p->orig_cipher, p->f_out);
fprintf(p->f_out, "\n");
fprintf(p->f_out, " t_c: ");
ops->print(ops, OPS_DATA_CIPHER, p->test_cipher, p->f_out);
fprintf(p->f_out, "\n");
//stdout - to look after
fprintf(stdout, " best_round_fitness >= gamma [%f] [round %u] = %f \n", cfg->gamma,
round, p->best_round_fitness);
fprintf(stdout, " optimum key %d found\n"
" key: ", p->optimum_keys);
ops->print(ops, OPS_DATA_KEY, p->best_round_key, stdout);
fprintf(stdout, "\n");
fprintf(p->f_out, "\n");
fprintf(p->f_out, "\tOPTIMUM STAT \n"
"\tOPTIMUM_KEYS\t%d\n"
"\tBit"
"\tOPTIMUM_KEYS_STAT[bit]", p->optimum_keys);
fprintf(p->f_out,"\n");
for(k = 0; k < ops->key_length; k++)
{
p->optimum_keys_stat[k] += ops->get_bit(ops, OPS_DATA_KEY, p->best_round_key,
k);
if ((p->optimum_keys >= cfg->kappa) && (p->known_bit[k] == -1))
{
bit = -1;
85
fprintf(p->f_out,"\t%d\t%d \n", k, p->optimum_keys_stat[k]);
if(p->optimum_keys_stat[k] > 0 && p->optimum_keys_stat[k] < p->optimum_keys)
{
if (p->optimum_keys_stat[k] >= p->optimum_keys * cfg->delta) bit = 1;
if (p->optimum_keys_stat[k] <= p->optimum_keys * (1.0 - cfg->delta)) bit = 0;
if(p->rounds == 2)
fprintf(p->f_out, "cfg->delta = %f -> optimum_keys_stat [bit %u] = %u \n", cfg-
>delta, k, p->optimum_keys_stat[k]);
if (bit >= 0)
{
//if(p->rounds==1)
fprintf(p->f_out, "--- * bit %d SET as %d ---\n", k, bit);
p->known_bit[k] = bit;
detected_bit++;
}
fprintf(p->f_out,"\n");
}
}
}
fprintf(p->f_out, "--- Detected_bits %d ---\n", detected_bit);
}
}
}
ant_aes.c
#include
#include
#include
#include
#include
#include
#include
#include "cipher/aes.h"
#include "ops/ops_aes.h"
#include "ant/ant.h"
#include "ant/ant_aes.h"
static void ant_tau_init_aes(struct ant *p)
{
struct ops_data *ops = p->ops;
int
seed_count = *((int*)p->priv);
char key[32];
int
i, k, prev_bit, bit;
86
double increment;
increment = 1.0 / seed_count;
if(p->rounds == 2 || p->rounds == 5)
{
fprintf(p->f_out, "seed_count = %u", seed_count);
fprintf(p->f_out, "\n");
fprintf(p->f_out, "increment = %f", increment);
fprintf(p->f_out, "\n");
}
memset(p->tau, 0, ops->key_length * (4 * sizeof(double)));
for(i = 0; i < seed_count; i++)
{
ops->random(ops, OPS_DATA_KEY, key);
if(p->rounds == 2 || p->rounds == 5)
{
fprintf(p->f_out, "Random key: \n");
ops->print(ops, OPS_DATA_KEY, key, p->f_out);
fprintf(p->f_out, "\n");
}
if(p->rounds == 2 || p->rounds == 5)
{
fprintf(p->f_out, "\n");
fprintf(p->f_out, "Pheromons array init \n"
"-------------------------\n"
"bit\t\tvalue\to[0-0]\to[0-1]\to[1-0]\to[1-1]\t\n");
}
prev_bit = 0;
for(k = 0; k < ops->key_length; k++)
{
if (p->known_bit[k] != -1) bit = p->known_bit[k];
else bit = ops->get_bit(ops, OPS_DATA_KEY, key, k);
if(p->rounds == 2 || p->rounds == 5)
fprintf(p->f_out, "[ %03u ]\t=\t%u", k, bit);
p->tau[4 * k + 2 * prev_bit + bit] += increment;
if(p->rounds == 2 || p->rounds == 5)
{
fprintf(p->f_out, "\t%.5lf\t%.5lf\t%.5lf\t%.5lf\t",p->tau[4 * k + 0], p->tau[4 * k + 1], p-
>tau[4 * k + 2], p->tau[4 * k + 3]);
fprintf(p->f_out, "\n");
}
prev_bit = bit;
}
}
}
int test_ant_aes()
{
87
char password[33] = "CotaFota";
struct ant_cfg cfg =
{
.alpha = 1.50,
.beta = 1.00,
.rho = 0.90,
.gamma = 0.72,
.delta = 0.70,
.kappa = 10
};
struct ops_data ops;
struct ant
ant;
unsigned char text[16], cipher[16];
int
i;
int
seed_count;
int rounds, iterations, ant_count;
int key_len;
FILE
*f_out;
FILE
*in_fd;
const char *input_fname;
int out_option;
printf("Choose output_option: \n");
printf("0 - stdout for test case\n");
printf("1 - test file \n");
printf("2 - file \n");
scanf("%d", &out_option);
//out_option = 2;
switch(out_option)
{
case 0:
input_fname = "data_ant_aes_test.txt";
f_out=stdout;
break;
case 1:
{
input_fname = "data_ant_aes_test.txt";
f_out = fopen("out_ant_aes_test.txt", "a");
}
break;
case 2:
{
input_fname = "data_ant_aes.txt";
f_out = fopen("out_ant_aes.txt", "a");
}
break;
default:
input_fname = "data_ant_aes_test.txt";
f_out=stdout;
88
break;
}
for(int j = 0; j < 5; j++)
{
in_fd = fopen(input_fname, "r");
fscanf(in_fd, "%lf%lf%lf%lf%lf%u%u%u%u%u%u",
&cfg.alpha, &cfg.beta, &cfg.rho,
&cfg.gamma, &cfg.delta, &cfg.kappa,
&rounds, &iterations, &ant_count, &seed_count, &key_len );
fclose(in_fd);
srand(time(NULL));
// 1) 128(16byte) -> key(128) ->128(16 byte)
// 2) 128 -> key(194) ->128
// 3) 128 -> key(256=32byte) ->128
ops_data_init_aes(&ops, key_len);
//ops.random(&ops, OPS_DATA_TEXT, text);
memset(text, 0, sizeof(text));
FILE *in_txt = fopen("input.txt", "r");
fread(text, sizeof(text), 1, in_txt);
fclose(in_txt);
ops.cipher(&ops, text, password, cipher);
// ant_init(&ant, &cfg, &ops, text, cipher,
//
rounds, iterations, ant_count,
//
NULL, NULL, &seed_count, f_out);
ant_init(&ant, &cfg, &ops, text, cipher,
rounds, iterations, ant_count,
NULL, ant_tau_init_aes, &seed_count, f_out);
struct timeval tv1, tv2;
gettimeofday(&tv1, NULL);
ant_run(&ant);
gettimeofday(&tv2, NULL);
fprintf(f_out, "---------RESULT [ %d ]-------:\n", j);
fprintf(f_out, "Case ANT-AES:\n");
fprintf(f_out, "\n");
fprintf(f_out, "parameters:\n"
"key_len = %u\n"
"rounds = %u\n"
"iterations = %u\n"
"ant_count = %u\n"
89
"seed_count = %u\n"
"cfg.alpha = %f\n"
"cfg.beta = %f\n"
"cfg.rho = %f\n"
"cfg.gamma = %f\n"
"cfg.delta = %f\n"
"cfg.kappa = %u\n",
key_len,
rounds,
iterations,
ant_count,
seed_count,
cfg.alpha,
cfg.beta,
cfg.rho,
cfg.gamma,
cfg.delta,
cfg.kappa
);
fprintf(f_out, "orig text:\n");
ops.print(&ops, OPS_DATA_TEXT, text, f_out);
fprintf(f_out,"\n");
fprintf(f_out,"\n");
fprintf(f_out,"orig cipher:\n");
ops.print(&ops, OPS_DATA_CIPHER, cipher, f_out);
fprintf(f_out,"\n");
fprintf(f_out,"\n");
fprintf(f_out, "actual key:\n");
fprintf(f_out," / \n");
fprintf(f_out, "founded bits:\n");
ops.print(&ops, OPS_DATA_KEY, password, f_out);
fprintf(f_out,"\n");
int count_known_bits = 0;
int count_cotrrect_bits = 0;
for(i = 0; i < ops.key_length; i++)
{
if (ant.known_bit[i] != -1)
{
fprintf(f_out, "%d", ant.known_bit[i]);
count_known_bits++;
if(ant.known_bit[i] == ops.get_bit(&ops, OPS_DATA_KEY, password, i))
count_cotrrect_bits++;
}
else fprintf(f_out, "?");
}
fprintf(f_out, "\n");
90
fprintf(f_out, "total bits = %u\n", ops.key_length);
fprintf(f_out, "count_known_bits = %u\n", count_known_bits);
fprintf(f_out, "count_cotrrect_bits = %u\n", count_cotrrect_bits);
fprintf(f_out, "time start = %ld\n", tv1.tv_sec);
fprintf(f_out, "time finish = %ld\n", tv2.tv_sec);
fprintf(f_out, "execution time:
%ld mcs\n", ((tv2.tv_sec-tv1.tv_sec)*1000000 +
(tv2.tv_usec-tv1.tv_usec)/1000));
fprintf(f_out, "execution time:
%ld sec\t%ld msec\n", (tv2.tv_sec-tv1.tv_sec),
(tv2.tv_usec-tv1.tv_usec)/1000);
fprintf(f_out, "\n");
ant_done(&ant);
}
if (f_out != stdout) fclose(f_out);
return 0;
}
ant_des.c
#include
#include
#include
#include
#include
#include
#include
#include "cipher/des.h"
#include "ops/ops_des.h"
#include "ant/ant.h"
#include "ant/ant_des.h"
struct ant_seed_des
{
int text_cnt;
uint64_t *text;
uint64_t *cipher;
};
static void ant_tau_init_des(struct ant *p)
{
struct ops_data *ops = p->ops;
struct ant_seed_des *seed = p->priv;
int
i, k, prev_bit, bit, shift;
double
increment;
uint64_t cross;
increment = 1.0 / seed->text_cnt;
if(p->rounds == 2 || p->rounds == 5)
{
fprintf(p->f_out, "seed->text_cnt = %u", seed->text_cnt);
91
fprintf(p->f_out, "\n");
fprintf(p->f_out, "increment = %f", increment);
fprintf(p->f_out, "\n");
}
memset(p->tau, 0, ops->key_length * (4 * sizeof(double)));
for(i = 0; i < seed->text_cnt; i++)
{
cross = seed->text[i] ^ seed->cipher[i];
if(p->rounds == 2 || p->rounds == 5)
{
fprintf(p->f_out, "cross: \n");
for(uint64_t j = 0; j < 64; j++)
fprintf(p->f_out, "%lu", (cross>>j)&0x01);
fprintf(p->f_out, "\n");
}
if(p->rounds == 2 || p->rounds == 5)
{
fprintf(p->f_out, "\n");
fprintf(p->f_out, "Pheromons array init \n"
"-------------------------\n"
"bit\t\tvalue\to[0-0]\to[0-1]\to[1-0]\to[1-1]\t\n");
}
shift = 0;
prev_bit = 0;
for(k = 0; k < ops->key_length; k++)
{
if (p->known_bit[k] != -1) bit = p->known_bit[k];
else bit = (cross >> shift) & 0x01;
if(p->rounds == 2 || p->rounds == 5)
fprintf(p->f_out, "[ %03u ]\t=\t%u", k, bit);
p->tau[4 * k + 2 * prev_bit + bit] += increment;
prev_bit = bit;
if(p->rounds == 2 || p->rounds == 5)
{
fprintf(p->f_out, "\t%.5lf\t%.5lf\t%.5lf\t%.5lf\t",p->tau[4 * k + 0], p->tau[4 * k + 1], p-
>tau[4 * k + 2], p->tau[4 * k + 3]);
fprintf(p->f_out, "\n");
}
shift++;
if ((shift & 0x7) == 7) shift++;
}
}
}
int test_ant_des()
92
{
//char password[9] = "\x0\x0\x0\x0\x0\x0\x0\x0"; //UUUUUUUU
char password[9] = "CotaFota";
struct ant_cfg cfg =
{
.alpha = 1.50,
.beta = 1.00,
.rho = 0.90,
.gamma = 0.72,
.delta = 0.70,
.kappa = 10
};
struct ops_data ops;
struct ant
ant;
struct ant_seed_des seed;
int i;
int rounds, iterations, ant_count;
FILE
*f_out;
FILE
*in_fd;
const char *input_fname;
int out_option;
printf("Choose output_option: \n");
printf("0 - stdout for test case\n");
printf("1 - test file \n");
printf("2 - file \n");
scanf("%d", &out_option);
//out_option = 2;
switch(out_option)
{
case 0:
input_fname = "data_ant_des_test.txt";
f_out=stdout;
break;
case 1:
{
input_fname = "data_ant_des_test.txt";
f_out = fopen("out_ant_des_test.txt", "a");
}
break;
case 2:
{
input_fname = "data_ant_des.txt";
f_out = fopen("out_ant_des.txt", "a");
}
break;
default:
input_fname = "data_ant_des_test.txt";
f_out=stdout;
break;
}
93
for(int j = 0; j < 5; j++)
{
in_fd = fopen(input_fname, "r");
fscanf(in_fd, "%lf%lf%lf%lf%lf%u%u%u%u%u%u",
&cfg.alpha, &cfg.beta, &cfg.rho,
&cfg.gamma, &cfg.delta, &cfg.kappa,
&rounds, &iterations, &ant_count, &seed.text_cnt, &des_rounds);
fclose(in_fd);
srand(time(NULL));
ops_data_init_des(&ops);
seed.text = malloc(seed.text_cnt * sizeof(uint64_t));
seed.cipher = malloc(seed.text_cnt * sizeof(uint64_t));
FILE *in_txt = fopen("input.txt", "r");
fread(seed.text, sizeof(uint64_t), seed.text_cnt, in_txt);
fclose(in_txt);
for(i = 0; i < seed.text_cnt; i++)
ops.cipher(&ops, &seed.text[i], password, &seed.cipher[i]);
// ant_init(&ant, &cfg, &ops, &seed.text[0], &seed.cipher[0],
// rounds, iterations, ant_count,
// NULL, NULL, &seed, f_out);
ant_init(&ant, &cfg, &ops, &seed.text[0], &seed.cipher[0],
rounds, iterations, ant_count,
NULL, ant_tau_init_des, &seed, f_out);
struct timeval tv1, tv2;
gettimeofday(&tv1, NULL);
ant_run(&ant);
gettimeofday(&tv2, NULL);
fprintf(f_out, "---------RESULT [ %d ]-------:\n", j);
fprintf(f_out, "Case ANT-DES:\n");
fprintf(f_out,"\n");
fprintf(f_out, "parameters:\n"
"des_rounds = %u\n"
"rounds = %u\n"
"iterations = %u\n"
"ant_count = %u\n"
"seed.text_cnt = %u\n"
"cfg.alpha = %f\n"
"cfg.beta = %f\n"
"cfg.rho = %f\n"
94
"cfg.gamma = %f\n"
"cfg.delta = %f\n"
"cfg.kappa = %u\n",
des_rounds,
rounds,
iterations,
ant_count,
seed.text_cnt,
cfg.alpha,
cfg.beta,
cfg.rho,
cfg.gamma,
cfg.delta,
cfg.kappa
);
fprintf(f_out,"\n");
fprintf(f_out, "orig text:\n");
for(i = 0; i < seed.text_cnt; i++)
{
ops.print(&ops, OPS_DATA_TEXT, &seed.text[i], f_out);
fprintf(f_out,"\n");
}
fprintf(f_out,"\n");
fprintf(f_out,"\n");
fprintf(f_out,"orig cipher:\n");
for(i = 0; i < seed.text_cnt; i++)
{
ops.print(&ops, OPS_DATA_CIPHER, &seed.cipher[i], f_out);
fprintf(f_out,"\n");
}
fprintf(f_out,"\n");
fprintf(f_out,"\n");
fprintf(f_out, "actual key:\n");
fprintf(f_out," / \n");
fprintf(f_out, "founded key:\n");
ops.print(&ops, OPS_DATA_KEY, password, f_out);
fprintf(f_out,"\n");
for(i = 0; i < ops.key_length; i++)
{
if (ant.known_bit[i] != -1)
fprintf(f_out, "%d", ant.known_bit[i]);
else fprintf(f_out,"?");
if ((i % 7) == 6) fprintf(f_out, "x");
}
95
fprintf(f_out,"\n");
fprintf(f_out,"\n");
int count_known_bits = 0;
int count_correct_bits = 0;
fprintf(f_out, "Variant1: \n");
for(i = 0; i < ops.key_length; i++)
{
fprintf(f_out, "[ %d ]: known_bit = %d <-> %d = password", i, ant.known_bit[i],
ops.get_bit(&ops, OPS_DATA_KEY, password, i));
if (ant.known_bit[i] != -1)
{
count_known_bits++;
fprintf(f_out, " count_known = %d", count_known_bits);
if(ant.known_bit[i] == ops.get_bit(&ops, OPS_DATA_KEY, password, i))
{
count_correct_bits++;
fprintf(f_out, " count_correct = %d", count_correct_bits);
}
}
fprintf(f_out, "\n");
if ((i % 7) == 6) fprintf(f_out, "[ %d ] === x ===\n", i);
}
fprintf(f_out, "\n");
fprintf(f_out, "\n");
fprintf(f_out, "\n");
fprintf(f_out, "total bits = %u\n", ops.key_length);
fprintf(f_out, "count_known_bits = %u\n", count_known_bits);
fprintf(f_out, "count_correct_bits = %u\n", count_correct_bits);
fprintf(f_out, "time start
= %ld sec\t%ld msec\n", tv1.tv_sec, tv1.tv_usec/1000);
fprintf(f_out, "time start
= %ld sec\t%ld msec\n", tv2.tv_sec, tv2.tv_usec/1000);
fprintf(f_out, "execution time:
%ld mcs\n", ((tv2.tv_sec-tv1.tv_sec)*1000000 +
(tv2.tv_usec-tv1.tv_usec)/1000));
fprintf(f_out, "execution time:
%ld sec\t%ld msec\n", (tv2.tv_sec-tv1.tv_sec),
(tv2.tv_usec-tv1.tv_usec)/1000);
fprintf(f_out, "\n");
ant_done(&ant);
}
if (f_out != stdout) fclose(f_out);
return 0;
}
gen.h
#ifndef __GEN_H__
96
#define __GEN_H__
#include "ops/ops.h"
struct genotype
{
void
*key;
double
fitness;
};
struct gen_cfg
{
int
parents_to_keep; // number of parents to keep in new generation
double
mutation_rate; // per gene mutation rate
double
delta; // threshold value to set bit as known
};
struct gen
{
struct ops_data *ops;
struct gen_cfg *cfg;
int generations;
int population_size;
struct genotype *population;
void
*orig_text;
void
*orig_cipher;
void
*test_cipher;
struct genotype *tmp;
int
*known_bit;
double
best_fitness;
void
*best_key;
double
(*fitness)(struct gen *p, void *key);
void
(*select)(struct gen *p, struct genotype **parent1, struct genotype **parent2);
void
*priv; // private data
FILE
*f_out;
};
int gen_init(struct gen *p, struct gen_cfg *cfg, struct ops_data *ops,
void *orig_text, void *orig_cipher,
int generations, int population_size,
double (*fitness)(struct gen *p, void *key),
void (*select)(struct gen *p, struct genotype **parent1, struct genotype **parent2),
void *priv, FILE *f_out);
void gen_run(struct gen *p);
void gen_done(struct gen *p);
#endif // __GEN_H__
97
gen_aes.h
#ifndef __GEN_AES_H__
#define __GEN_AES_H__
int test_gen_aes();
#endif // __GEN_AES_H__
gen_des.h
#ifndef __GEN_DES_H__
#define __GEN_DES_H__
int test_gen_des();
#endif // __GEN_DES_H__
gen.c
#include
#include
#include
#include "gen/gen.h"
static int genotype_cmp(const void *a, const void *b)
{
double diff = ((struct genotype*)a)->fitness -
((struct genotype*)b)->fitness;
// sort in descent order
if (diff < 0) return +1;
if (diff > 0) return -1;
return 0;
}
static double gen_fitness(struct gen *p, void *key)
{
struct ops_data *ops = p->ops;
int i, result = 0;
ops->cipher(ops, p->orig_text, key, p->test_cipher);
for(i = 0; i < ops->cipher_length; i++)
{
if (ops->get_bit(ops, OPS_DATA_CIPHER, p->orig_cipher, i) ==
ops->get_bit(ops, OPS_DATA_CIPHER, p->test_cipher, i)) result++;
}
if(p->generations == 2)
{
98
fprintf(p->f_out, "GEN FITNESS DATA\n");
fprintf(p->f_out, "orig_text\n");
fprintf(p->f_out, " ");
p->ops->print(p->ops, OPS_DATA_TEXT, p->orig_text, p->f_out);
fprintf(p->f_out, "\n");
fprintf(p->f_out, "orig_cipher\n");
fprintf(p->f_out, " ");
p->ops->print(p->ops, OPS_DATA_CIPHER, p->orig_cipher, p->f_out);
fprintf(p->f_out, "\n");
fprintf(p->f_out, "test_cipher\n");
fprintf(p->f_out, " ");
p->ops->print(p->ops, OPS_DATA_CIPHER, p->test_cipher, p->f_out);
fprintf(p->f_out, "\n");
fprintf(p->f_out, "test_key\n");
fprintf(p->f_out, " ");
p->ops->print(p->ops, OPS_DATA_KEY, key, p->f_out);
fprintf(p->f_out, "\n");
fprintf(p->f_out, "---total cipher match = %d\n", result);
fprintf(p->f_out, "---gen_fitness = %f\n", ((double)result)/ops->cipher_length);
}
return ((double)result) / ops->cipher_length;
}
static struct genotype* gen_select_tournament(struct gen *p)
{
struct genotype *a1, *a2;
a1 = a2 = &p->population[rand() % p->population_size];
while(a1 == a2)
{
a2 = &p->population[rand() % p->population_size];
}
if(p->generations == 2)
{
fprintf(p->f_out, "---gen_select_tournament a1\n");
fprintf(p->f_out, " ");
p->ops->print(p->ops, OPS_DATA_KEY, a1->key, p->f_out);
fprintf(p->f_out, "\n");
fprintf(p->f_out, "---a1->fitess\t\%f\n", a1->fitness);
fprintf(p->f_out, "---gen_select_tournament a2\n");
fprintf(p->f_out, " ");
p->ops->print(p->ops, OPS_DATA_KEY, a2->key, p->f_out);
fprintf(p->f_out, "\n");
fprintf(p->f_out, "---a2->fitness\t\%f\n", a2->fitness);
}
return (a1->fitness >= a2->fitness) ? a1 : a2;
}
static void gen_select(struct gen *p,
struct genotype **parent1,
struct genotype **parent2)
99
{
*parent1 = gen_select_tournament(p);
*parent2 = *parent1;
while(*parent2 == *parent1) *parent2 = gen_select_tournament(p);
}
static struct genotype* gen_alloc_population(struct gen *p)
{
struct ops_data *ops = p->ops;
struct genotype *a;
int i;
a = malloc(p->population_size * sizeof(struct genotype));
if (a == NULL) return NULL;
for(i = 0; i < p->population_size; i++)
{
a[i].fitness = -1;
a[i].key = ops->allocate(ops, OPS_DATA_KEY);
if (a[i].key == NULL)
{
while(i > 0)
{
i--;
ops->destroy(ops, OPS_DATA_KEY, a[i].key);
}
free(a);
return NULL;
}
}
return a;
}
static void gen_free_population(struct gen *p, struct genotype a[])
{
struct ops_data *ops = p->ops;
int i;
for(i = 0; i < p->population_size; i++)
{
ops->destroy(ops, OPS_DATA_KEY, a[i].key);
}
free(a);
}
int gen_init(struct gen *p, struct gen_cfg *cfg, struct ops_data *ops,
void *orig_text, void *orig_cipher,
int generations, int population_size,
double (*fitness)(struct gen *p, void *key),
void (*select)(struct gen *p, struct genotype **parent1, struct genotype **parent2),
void *priv, FILE *f_out)
100
{
int i;
memset(p, 0, sizeof(struct gen));
p->ops = ops;
p->cfg = cfg;
p->priv = priv;
p->generations = generations;
p->population_size = population_size;
p->orig_text = orig_text;
p->orig_cipher = orig_cipher;
p->best_fitness = -1;
p->f_out = (f_out == NULL) ? stdout : f_out;
p->fitness = (fitness == NULL) ? gen_fitness : fitness;
p->select = (select == NULL) ? gen_select : select;
p->known_bit = malloc(ops->key_length * sizeof(int));
if (p->known_bit == NULL) goto error_known_bit;
for(i = 0; i < ops->key_length; i++) p->known_bit[i] = -1;
p->best_key = ops->allocate(ops, OPS_DATA_KEY);
if (p->best_key == NULL) goto error_best_key;
p->test_cipher = ops->allocate(ops, OPS_DATA_CIPHER);
if (p->test_cipher == NULL) goto error_test_cipher;
p->population = gen_alloc_population(p);
if (p->population == NULL) goto error_population;
p->tmp = gen_alloc_population(p);
if (p->tmp == NULL) goto error_tmp;
return 1;
error_tmp:
gen_free_population(p, p->population);
error_population:
ops->destroy(ops, OPS_DATA_CIPHER, p->test_cipher);
error_test_cipher:
ops->destroy(ops, OPS_DATA_KEY, p->best_key);
error_best_key:
free(p->known_bit);
error_known_bit:
memset(p, 0, sizeof(*p));
return 0;
}
void gen_done(struct gen *p)
{
struct ops_data *ops = p->ops;
101
gen_free_population(p, p->tmp);
gen_free_population(p, p->population);
ops->destroy(ops, OPS_DATA_CIPHER, p->test_cipher);
ops->destroy(ops, OPS_DATA_KEY, p->best_key);
free(p->known_bit);
memset(p, 0, sizeof(*p));
}
void gen_run(struct gen *p)
{
struct ops_data *ops = p->ops;
struct gen_cfg *cfg = p->cfg;
struct genotype *p1, *p2;
int i, j, sum, bit;
for(i = 0; i < ops->key_length; i++) p->known_bit[i] = -1;
// initial generation
p->best_fitness = -1;
for(j = 0; j < p->population_size; j++)
{
ops->random(ops, OPS_DATA_KEY, p->population[j].key);
p->population[j].fitness = p->fitness(p, p->population[j].key);
if(p->generations == 2)
{
fprintf(p->f_out, "Key----------\n");
fprintf(p->f_out, " ");
p->ops->print(p->ops, OPS_DATA_KEY, p->population[j].key, p->f_out);
fprintf(p->f_out, "\n");
fprintf(p->f_out, "Fitness \t\%f\n", p->population[j].fitness);
fprintf(p->f_out, "\n");
}
if (p->population[j].fitness > p->best_fitness)
{
p->best_fitness = p->population[j].fitness;
p->ops->copy(ops, OPS_DATA_KEY, p->population[j].key, p->best_key);
}
//fprintf(p->f_out, "Best key \n");
//fprintf(p->f_out, " ");
//p->ops->print(p->ops, OPS_DATA_KEY, p->best_key, p->f_out);
//fprintf(p->f_out, "\n");
//fprintf(p->f_out, "Best fitness \t\%f\n", p->best_fitness);
//fprintf(p->f_out, "\n");
}
qsort(p->population, p->population_size, sizeof(struct genotype), genotype_cmp);
if(p->generations == 2)
102
{
fprintf(p->f_out, "Keys after sort \n");
for(j = 0; j < p->population_size; j++)
{
fprintf(p->f_out, " ");
ops->print(p->ops, OPS_DATA_KEY, p->population[j].key, p->f_out);
fprintf(p->f_out, "\n");
}
}
for(i = 0; i < p->generations; i++)
{
fprintf(stdout, "---------------GENERATION [ %d ]----------------\n", i);
fprintf(p->f_out, "---------------GENERATION [ %d ]----------------\n", i);
for(j = 0; j < cfg->parents_to_keep; j++)
{
p->tmp[j].fitness = p->population[j].fitness;
ops->copy(ops, OPS_DATA_KEY, p->population[j].key, p->tmp[j].key);
}
if(p->generations == 2)
{
fprintf(p->f_out, "POPULATION\n");
for(j = 0; j < p->population_size; j++)
{
fprintf(p->f_out, " ");
ops->print(p->ops, OPS_DATA_KEY, p->population[j].key, p->f_out);
fprintf(p->f_out, "\n");
}
}
for(j = cfg->parents_to_keep; j < p->population_size; j++)
{
if(p->generations == 2)
fprintf(p->f_out, "Select parents [gener %d ], [popul %d ]\n", i, j);
// select parents
p->select(p, &p1, &p2);
if(p->generations == 2)
{
fprintf(p->f_out, "parents: %ld, %ld\n", p1 - &p->population[0], p2 - &p-
>population[0]);
fprintf(p->f_out, " ");
p->ops->print(p->ops, OPS_DATA_KEY, p1->key, p->f_out);
fprintf(p->f_out, "\n");
fprintf(p->f_out, " ");
p->ops->print(p->ops, OPS_DATA_KEY, p2->key, p->f_out);
fprintf(p->f_out, "\n");
}
103
// make child
ops->breed(ops, p1->key, p2->key, p->tmp[j].key);
if(p->generations == 2)
{
fprintf(p->f_out, " ");
ops->print(p->ops, OPS_DATA_KEY, p->tmp[j].key, p->f_out);
fprintf(p->f_out, " (child)\n");
}
// mutate
ops->mutate(ops, p->tmp[j].key, cfg->mutation_rate);
if(p->generations == 2)
{
fprintf(p->f_out, " ");
p->ops->print(p->ops, OPS_DATA_KEY, p->tmp[j].key, p->f_out);
fprintf(p->f_out, " (after mutate)\n");
}
p->tmp[j].fitness = p->fitness(p, p->tmp[j].key);
if (p->tmp[j].fitness > p->best_fitness)
{
p->best_fitness = p->tmp[j].fitness;
ops->copy(ops, OPS_DATA_KEY, p->tmp[j].key, p->best_key);
}
}
if(p->generations == 2)
{
fprintf(p->f_out, " Best key\n");
fprintf(p->f_out, " ");
p->ops->print(p->ops, OPS_DATA_KEY, p->best_key, p->f_out);
fprintf(p->f_out, " \n");
fprintf(p->f_out, " Best fitness\t\%f\n", p->best_fitness);
}
qsort(p->tmp, p->population_size, sizeof(struct genotype), genotype_cmp);
// swap generations
p1 = p->population;
p->population = p->tmp;
p->tmp = p1;
//fprintf(p->f_out, "best generations fitness [generation %d]= %lf\n", i, p->best_fitness);
//fprintf(p->f_out, "best generations key [generation %d] \n", i);
//p->ops->print(p->ops, OPS_DATA_KEY, p->best_key, p->f_out);
//fprintf(p->f_out, "\n");
}
if(p->generations == 2)
for(j = 0; j < p->population_size; j++)
{
104
fprintf(p->f_out, " ");
ops->print(p->ops, OPS_DATA_KEY, p->population[j].key, p->f_out);
fprintf(p->f_out, "\n");
}
for(i = 0; i < ops->key_length; i++)
{
bit = -1;
sum = 0;
for(j = 0; j < p->population_size; j++)
{
sum += ops->get_bit(ops, OPS_DATA_KEY, p->population[j].key, i);
}
if (sum >= p->population_size * cfg->delta) bit = 1;
if (sum <= p->population_size * (1.0 - cfg->delta)) bit = 0;
if (bit >= 0)
{
fprintf(p->f_out, " * bit %d set as %d\n", i, bit);
p->known_bit[i] = bit;
}
}
}
gen_aes.c
#include
#include
#include
#include
#include
#include
#include
#include "cipher/aes.h"
#include "ops/ops_aes.h"
#include "gen/gen.h"
#include "gen/gen_aes.h"
int test_gen_aes()
{
char password[33] = "CotaFota";
struct gen_cfg cfg =
{
.parents_to_keep = 5,
.mutation_rate = 0.02,
.delta = 0.70,
};
struct ops_data ops;
struct gen
gen;
unsigned char text[16], cipher[16];
int i;
int generations, population_size;
int key_len;
105
FILE
*f_out;
FILE
*in_fd;
const char *input_fname;
int out_option;
printf("Choose output_option: \n");
printf("0 - stdout for test case\n");
printf("1 - test file \n");
printf("2 - file \n");
scanf("%d", &out_option);
switch(out_option)
{
case 0:
input_fname = "data_gen_aes_test.txt";
f_out=stdout;
break;
case 1:
{
input_fname = "data_gen_aes_test.txt";
f_out = fopen("out_gen_aes_test.txt", "a");
}
break;
case 2:
{
input_fname = "data_gen_aes.txt";
f_out = fopen("out_gen_aes.txt", "a");
}
break;
default:
input_fname = "data_gen_aes_test.txt";
f_out=stdout;
break;
}
for(int j = 0; j < 5; j++)
{
in_fd = fopen(input_fname, "r");
fscanf(in_fd, "%u%lf%lf%u%u%u",
&cfg.parents_to_keep, &cfg.mutation_rate, &cfg.delta,
&generations, &population_size, &key_len );
fclose(in_fd);
if(cfg.parents_to_keep > population_size) cfg.parents_to_keep = population_size * 0.01;
srand(time(NULL));
ops_data_init_aes(&ops, key_len);
//ops.random(&ops, OPS_DATA_TEXT, text);
memset(text, 0, sizeof(text));
106
FILE *in_txt = fopen("input.txt", "r");
fread(text, sizeof(text), 1, in_txt);
fclose(in_txt);
ops.cipher(&ops, text, password, cipher);
fprintf(f_out, "Case GEN-AES:\n");
gen_init(&gen, &cfg, &ops, text, cipher,
generations, population_size, NULL, NULL, NULL, f_out); // 3000 500
struct timeval tv1, tv2;
gettimeofday(&tv1, NULL);
gen_run(&gen);
gettimeofday(&tv2, NULL);
fprintf(f_out, "---------RESULT [ %d ]-------:\n", j);
fprintf(f_out, "Case GEN-DES:\n");
fprintf(f_out, "parameters:\n"
"cfg.parents_to_keep = %u \n"
"cfg.mutation_rate = %f \n"
"cfg.delta = %f \n"
"generations = %u\n"
"population_size = %u\n"
"key_len = %u\n",
cfg.parents_to_keep,
cfg.mutation_rate,
cfg.delta,
generations,
population_size,
key_len
);
fprintf(f_out, "orig text:\n"
" ");
ops.print(&ops, OPS_DATA_TEXT, text, f_out);
fprintf(f_out,"\n");
fprintf(f_out,"orig cipher:\n"
" ");
ops.print(&ops, OPS_DATA_CIPHER, cipher, f_out);
fprintf(f_out, "\n");
fprintf(f_out, "best key:\n"
" ");
ops.print(&ops, OPS_DATA_KEY, gen.best_key, f_out);
fprintf(f_out, "\n"
"actual key:\n"
" ");
ops.print(&ops, OPS_DATA_KEY, password, f_out);
107
fprintf(f_out, "\n"
"founded bits:\n"
" ");
int count_known_bits = 0;
int count_cotrrect_bits = 0;
for(i = 0; i < ops.key_length; i++)
{
if (gen.known_bit[i] != -1)
{
fprintf(f_out, "%d", gen.known_bit[i]);
count_known_bits++;
if(gen.known_bit[i] == ops.get_bit(&ops, OPS_DATA_KEY, password, i))
count_cotrrect_bits++;
}
else fprintf(f_out, "?");
}
fprintf(f_out, "\n");
fprintf(f_out, "total bits = %u\n", ops.key_length);
fprintf(f_out, "count_known_bits = %u\n", count_known_bits);
fprintf(f_out, "count_cotrrect_bits = %u\n", count_cotrrect_bits);
fprintf(f_out, "time start
= %ld sec\t%ld msec\n", tv1.tv_sec, tv1.tv_usec/1000);
fprintf(f_out, "time start
= %ld sec\t%ld msec\n", tv2.tv_sec, tv2.tv_usec/1000);
fprintf(f_out, "execution time:
%ld mcs\n", ((tv2.tv_sec-tv1.tv_sec)*1000000 +
(tv2.tv_usec-tv1.tv_usec)/1000));
fprintf(f_out, "execution time:
%ld sec\t%ld msec\n", (tv2.tv_sec-tv1.tv_sec),
(tv2.tv_usec-tv1.tv_usec)/1000);
fprintf(f_out, "\n");
gen_done(&gen);
}
if (f_out != stdout) fclose(f_out);
return 0;
}
gen_des.c
#include
#include
#include
#include
#include
#include
#include
#include "cipher/des.h"
#include "ops/ops_des.h"
#include "gen/gen.h"
#include "gen/gen_des.h"
int test_gen_des()
{
char password[9] = "CotaFota";
struct gen_cfg cfg =
108
{
.parents_to_keep = 5,
.mutation_rate = 0.02,
.delta = 0.70,
};
struct ops_data ops;
struct gen
gen;
char text[8], cipher[8];
int
i;
int generations, population_size;
FILE
*f_out;
FILE
*in_fd;
const char *input_fname;
int out_option;
printf("Choose output_option: \n");
printf("0 - stdout for test case\n");
printf("1 - test file \n");
printf("2 - file \n");
scanf("%d", &out_option);
switch(out_option)
{
case 0:
input_fname = "data_gen_des_test.txt";
f_out=stdout;
break;
case 1:
{
input_fname = "data_gen_des_test.txt";
f_out = fopen("out_gen_des_test.txt", "a");
}
break;
case 2:
{
input_fname = "data_gen_des.txt";
f_out = fopen("out_gen_des.txt", "a");
}
break;
default:
input_fname = "data_gen_des_test.txt";
f_out=stdout;
break;
}
for(int j = 0; j < 5; j++)
{
in_fd = fopen(input_fname, "r");
fscanf(in_fd, "%u%lf%lf%u%u%u",
&cfg.parents_to_keep, &cfg.mutation_rate, &cfg.delta,
&generations, &population_size, &des_rounds );
109
fclose(in_fd);
if(cfg.parents_to_keep > population_size) cfg.parents_to_keep = population_size * 0.01;
srand(time(NULL));
ops_data_init_des(&ops);
//ops.random(&ops, OPS_DATA_TEXT, text);
memset(text, 0, sizeof(text));
FILE *in_txt = fopen("input.txt", "r");
fread(text, sizeof(text), 1, in_txt);
fclose(in_txt);
ops.cipher(&ops, text, password, cipher);
gen_init(&gen, &cfg, &ops, text, cipher,
generations, population_size, NULL, NULL, NULL, f_out);
struct timeval tv1, tv2;
gettimeofday(&tv1, NULL);
gen_run(&gen);
gettimeofday(&tv2, NULL);
fprintf(f_out, "---------RESULT [ %d ]-------:\n", j);
fprintf(f_out, "Case GEN-DES:\n");
fprintf(f_out, "parameters:\n"
"cfg.parents_to_keep = %u \n"
"cfg.mutation_rate = %f \n"
"cfg.delta = %f \n"
"generations = %u\n"
"population_size = %u\n"
"des_rounds = %u\n",
cfg.parents_to_keep,
cfg.mutation_rate,
cfg.delta,
generations,
population_size,
des_rounds
);
fprintf(f_out, "orig text:\n"
" ");
ops.print(&ops, OPS_DATA_TEXT, text, f_out);
fprintf(f_out,"\n");
fprintf(f_out,"orig cipher:\n"
" ");
ops.print(&ops, OPS_DATA_CIPHER, cipher, f_out);
110
fprintf(f_out, "\n");
fprintf(f_out, "best key:\n"
" ");
ops.print(&ops, OPS_DATA_KEY, gen.best_key, f_out);
fprintf(f_out,"\n");
fprintf(f_out, "actual key:\n");
fprintf(f_out," / \n");
fprintf(f_out, "founded key:\n");
fprintf(f_out, " ");
ops.print(&ops, OPS_DATA_KEY, password, f_out);
fprintf(f_out,"\n");
fprintf(f_out, " ");
int count_known_bits = 0;
int count_cotrrect_bits = 0;
for(i = 0; i < ops.key_length; i++)
{
if (gen.known_bit[i] != -1)
{
fprintf(f_out, "%d", gen.known_bit[i]);
count_known_bits++;
if(gen.known_bit[i] == ops.get_bit(&ops, OPS_DATA_KEY, password, i))
count_cotrrect_bits++;
}
else fprintf(f_out, "?");
if ((i % 7) == 6) fprintf(f_out, "x");
}
fprintf(f_out, "\n");
fprintf(f_out, "total bits = %u\n", ops.key_length);
fprintf(f_out, "count_known_bits = %u\n", count_known_bits);
fprintf(f_out, "count_cotrrect_bits = %u\n", count_cotrrect_bits);
fprintf(f_out, "time start
= %ld sec\t%ld msec\n", tv1.tv_sec, tv1.tv_usec/1000);
fprintf(f_out, "time start
= %ld sec\t%ld msec\n", tv2.tv_sec, tv2.tv_usec/1000);
fprintf(f_out, "execution time:
%ld mcs\n", ((tv2.tv_sec-tv1.tv_sec)*1000000 +
(tv2.tv_usec-tv1.tv_usec)/1000));
fprintf(f_out, "execution time:
%ld sec\t%ld msec\n", (tv2.tv_sec-tv1.tv_sec),
(tv2.tv_usec-tv1.tv_usec)/1000);
fprintf(f_out, "\n");
gen_done(&gen);
}
if (f_out != stdout) fclose(f_out);
return 0;
}
Do'stlaringiz bilan baham: |