Created
July 14, 2015 18:23
-
-
Save lnsp/acf7e03a441de4541f60 to your computer and use it in GitHub Desktop.
a ARC4 encryption / decryption program
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ARC4 by Ronald L. Rivest | |
// Implementation by mooxmirror | |
#include <stdio.h> | |
#include <string.h> | |
#include <stdlib.h> | |
#include <assert.h> | |
#define byte unsigned char | |
#define STDIN_BUFFER_SIZE 8 | |
/* | |
How to use: | |
arcfour keyfile inputfile outputfile | |
*/ | |
void swap(byte *arr, size_t i, size_t j) | |
{ | |
byte tmp = arr[i]; | |
arr[i] = arr[j]; | |
arr[j] = tmp; | |
} | |
/* | |
Generates a cipher sqeezed by the given key. | |
*/ | |
byte *rc4(byte *key, byte *data, size_t key_length, size_t data_length) | |
{ | |
assert(key != NULL && data != NULL); | |
size_t i, j, t; | |
byte *seg, *cip, n; | |
if (key_length < 5) | |
{ | |
puts("ERROR: Key to small ( < 5 bytes)\n"); | |
abort(); | |
} | |
// generate seg bytes (KSA) | |
seg = calloc(256, sizeof(byte)); | |
if (seg == NULL) | |
{ | |
puts("ERROR: Out of memory\n"); | |
abort(); | |
} | |
for (i = 0; i < 256; i++) | |
{ | |
seg[i] = i; | |
} | |
j = 0; | |
for (i = 0; i < 256; i++) | |
{ | |
j = (j + seg[i] + key[i % key_length]) % 256; | |
swap(seg, i, j); | |
} | |
// sponge function (PRG) | |
cip = calloc(data_length, sizeof(byte)); | |
if (cip == NULL) | |
{ | |
puts("ERROR: Out of memory\n"); | |
abort(); | |
} | |
j = i = 0; | |
for (t = 0; t < data_length; t++) | |
{ | |
i = (i + 1) % 256; | |
j = (j + seg[i]) % 256; | |
swap(seg, i, j); | |
n = seg[(seg[i] + seg[j]) % 256]; | |
cip[t] = n ^ data[t]; | |
} | |
return cip; | |
} | |
/* | |
Prints the bytes in hexadecimal format to the standard output stream. | |
*/ | |
void print_bytes(byte *arr, size_t arr_length) | |
{ | |
size_t i; | |
for (i = 0; i < arr_length; i++) | |
{ | |
printf("%.2X ", arr[i]); | |
} | |
puts("\n"); | |
} | |
/* | |
Reads all bytes from file. | |
Resizes the destination fitting for all the shit. | |
Returns the amount of bytes read. | |
*/ | |
byte *bytes_from_file(FILE *file_ptr, size_t file_length) | |
{ | |
char *file_str; | |
// allocate memory, throw error | |
file_str = calloc(file_length + 1, sizeof(char)); | |
if (file_str == NULL) | |
{ | |
puts("ERROR: Out of memory"); | |
abort(); | |
} | |
// read and close key file | |
fread(file_str, file_length, 1, file_ptr); | |
// copies the content to the destination | |
return (byte*) file_str; | |
} | |
size_t get_file_length(FILE *file_ptr) | |
{ | |
size_t file_length; | |
fseek(file_ptr, 0, SEEK_END); | |
file_length = (size_t) ftell(file_ptr); | |
rewind(file_ptr); | |
return file_length; | |
} | |
int main(int argc, char *argv[]) | |
{ | |
// exit, if no key file exists | |
if (argc < 4) | |
{ | |
puts("ERROR: No key file"); | |
puts("USAGE: ./arcfour [key_file] [input_file] [output_file]"); | |
abort(); | |
} | |
FILE *key_file, *input_file, *output_file; | |
byte *key, *input, *output; | |
size_t key_length, input_length; | |
key_file = fopen(argv[1], "rb"); | |
key_length = get_file_length(key_file); | |
key = bytes_from_file(key_file, key_length); | |
fclose(key_file); | |
input_file = fopen(argv[2], "rb"); | |
input_length = get_file_length(input_file); | |
input = bytes_from_file(input_file, input_length); | |
fclose(input_file); | |
output = rc4(key, input, key_length, input_length); | |
output_file = fopen(argv[3], "wb"); | |
fwrite(output, sizeof(byte), input_length, output_file); | |
fclose(output_file); | |
return 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment