Крошечные реализации алгоритма шифрования в C


Я просто ищу общие отзывы про этот код, который шифрует файл с крошечный алгоритм шифрования. Я в настоящее время учусь C и я хотел бы знать, если я могу что-нибудь улучшить в моем стиле кодирования или ничего. Извините за мой английский.

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>

#define BASE_DELTA 0x9e3779b9
#define KEY_VALUE 0x7A24432646294A404E635266556A586E //128bits value


void encrypt (u_int32_t* v, u_int32_t* k) {
  u_int32_t delta = BASE_DELTA * 1;
  for (int i = 1; i <= 32; i++) {
    v[0] += (v[1] * delta) ^ ((v[1] << 4) + k[0]) ^ ((v[1] >> 5) + k[1]);
    v[1] += (v[0] * delta) ^ ((v[0] << 4) + k[2]) ^ ((v[0] >> 5) + k[3]);
    delta += BASE_DELTA;
  }
}

void encryptFile(const char file_to_encrypt_path[], u_int32_t key[4]){

  u_int32_t block[2];

  int nb_bytes_read = 0;
  int fd_to_encrypt = open(file_to_encrypt_path, O_RDONLY, 0655); //RDONLY permissions are 0655
  int fd_result_file = open("encrypted_file.dec", O_CREAT|O_TRUNC|O_WRONLY, 0666);


  while(1){
    memset(block, 0x0, sizeof(u_int64_t));

    nb_bytes_read = read(fd_to_encrypt, block, sizeof(u_int64_t));
    if(nb_bytes_read == -1){
      perror("read");
      exit(errno);
    }
    if(nb_bytes_read == 0){
      break; //EOF
    }
    encrypt(block, key);

    if(write(fd_result_file, block, sizeof(u_int64_t)) ==-1){
      perror("write");
      exit(errno);
    }
  }
}



int main(int argc, char const *argv[]) {
  if (argc < 2){
        printf("usage : %s <file to encrypt> \n", argv[0]);
        exit(EXIT_FAILURE);
  }

  u_int32_t key[4];
  u_int32_t block[2];
  memset(key, 0x0, sizeof(u_int32_t) * 4);
  memset(block, 0x0, sizeof(u_int32_t) * 2);

  __uint128_t key_val = KEY_VALUE; //Note that __uint128_t requiers gcc version > 4.4
  *key = key_val;


  encryptFile(argv[1], key);

  return 0;
}


487
4
задан 12 февраля 2018 в 06:02 Источник Поделиться
Комментарии
1 ответ

Хорошее форматирование и макет.

Помимо ошибок, хороший код.

Ошибка?

Я ожидал v[1] + delta, v[0] + delta за крошечный алгоритм шифрования.

// Reference code
// for (i=0; i < 32; i++) { /* basic cycle start */
// sum += delta;
// v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
// v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
// }

for (int i = 1; i <= 32; i++) {
// v--- ???
v[0] += (v[1] * delta) ^ ((v[1] << 4) + k[0]) ^ ((v[1] >> 5) + k[1]);
v[1] += (v[0] * delta) ^ ((v[0] << 4) + k[2]) ^ ((v[0] >> 5) + k[3]);
delta += BASE_DELTA;
}

Сомнительный пример кода.

*key = key_val; только первый элемент key[4], безусловно, ниже функциональность нужные.

// *key = key_val;
key[0] = key_val >> 0;
key[1] = key_val >> 32;
key[2] = key_val >> 64;
key[3] = key_val >> 96;

Использовать стандартные типы

Использовать стандартные типы от #include <stdint.h> как uint32_t вместо u_int32_t. Они лучше известны и более портативный.


Незначительные

const

Использовать const как смогли передать код намерением.

// void encrypt(u_int32_t* v, u_int32_t* k) {
void encrypt(u_int32_t* v, const u_int32_t* k) {

// void encryptFile(const char file_to_encrypt_path[], u_int32_t key[4]) {
void encryptFile(const char file_to_encrypt_path[], const u_int32_t key[4]) {

Константы unsigned

Константы unsigned для беззнаковых переменных путем добавления u.

// #define BASE_DELTA 0x9e3779b9
#define BASE_DELTA 0x9e3779b9u

Ненужные *1

Возможно, есть какая-то причина для этого, - я не вижу его.

// u_int32_t delta = BASE_DELTA * 1;
u_int32_t delta = BASE_DELTA;

Код отлаживать?

Сняв блок немного выступает в сторону от чистого отладки. Не использовать тип несвязанной переменной.

// memset(block, 0x0, sizeof(u_int64_t));
memset(block, 0x0, sizeof block);

0 база

Начиная с 0-это более C-иш, но у меня нет проблемы с кодом ОП.

// for (int i = 1; i <= 32; i++) {
for (int i = 0; i < 32; i++) {

Избежать голый магических чисел

Чай использует 64 раундов, приятно самостоятельного документа, который в коде

#define TEA_ROUNDS 64
for (int i = 0; i < TEA_ROUNDS/2; i++) {

открыть (теста), закрыть()?

Недостающие анализы, если open() успех.
Отсутствует close()Х2, в encryptFile().


Дополнительно

restrict

Использовать restrict (С99), чтобы позволить encrypt() знаю, что v, k не перекрываются. Это позволяет для некоторых оптимизаций.

// void encrypt(u_int32_t* v, u_int32_t* k) {
void encrypt(u_int32_t* restrict v, const u_int32_t* restrict k) {

Из постоянного ассортимента.

0x7A24432646294A404E635266556A586E вне диапазона большинства компиляторов, даже когда __uint128_t существует.

Портативный код будет использовать другой способ установить key а также и различный тип. Хорошо, что это работа для вас.

4
ответ дан 12 февраля 2018 в 09:02 Источник Поделиться