init
This commit is contained in:
commit
624a774bb1
42
README.md
Normal file
42
README.md
Normal file
@ -0,0 +1,42 @@
|
||||
# RENSA cipher
|
||||
|
||||
## Contents
|
||||
|
||||
- [About](#about)
|
||||
- [How it works](#how-it-works)
|
||||
- [Usage](#usage)
|
||||
|
||||
## About
|
||||
|
||||
RENSA (_jp._ 連差, _lit._ "chain variation", _omon._ 連鎖 "chain") is an encryption method I invented a couple of days ago while relaxing at sea. Actually, I'm not sure if I'm not reinventing the wheel with this method because it is pretty simple and obvious, but anyway, it really works. As for me, one of the coolest features of RENSA is that it can even be used for encrypted communications with virtually no latency.
|
||||
|
||||
## How it works
|
||||
|
||||
First of all, RENSA needs a key. This key maps each char to a specific value. Let's call these values _hashes_ of chars. When encrypting, each char is shifted up by the hash of the previous char; when decrypting, it is shifted down. Very simple.
|
||||
|
||||
For example, if you have a message like "kagi", "a" is shifted by the hash of "k", "g" is shifted by the hash of "a" and so on. By default, the first char in the message is shifted by the hash of the _zeroth_ char which defaults to `'\0'` but can also be specified particularly.
|
||||
|
||||
## Usage
|
||||
|
||||
Just compile [`main.c`](main.c), [`rensa.h`](rensa.h) and [`rensa.c`](rensa.c) and you are all set.
|
||||
|
||||
```
|
||||
Usage:
|
||||
rensa [-e/-d] [-i <input_path>] [-o <output_path>] [-k <key_path>] [-s <key_shift>] [-z <zeroth_char>]
|
||||
|
||||
Options:
|
||||
-h Print help and exit
|
||||
-e Encryption mode (default)
|
||||
-d Decryption mode
|
||||
-i <input_path> Input file path (stdio by default)
|
||||
-o <output_path> Output file path (stdout by default)
|
||||
-k <key_path> Key file path
|
||||
-s <key_shift> Key shift in bytes (0 by default)
|
||||
-z <zeroth_char> Zeroth char (0 by default)
|
||||
```
|
||||
|
||||
If `-k` is omitted, the default key is used. The default key simply maps each char to its value.
|
||||
|
||||
---
|
||||
|
||||
_© Masahiko AMANO aka H1K0, 2024-present_
|
||||
92
main.c
Normal file
92
main.c
Normal file
@ -0,0 +1,92 @@
|
||||
#include <stdlib.h>
|
||||
#include <getopt.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "rensa.h"
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc == 1) {
|
||||
fprintf(stderr, "No options provided\n");
|
||||
return 1;
|
||||
}
|
||||
int opt;
|
||||
FILE *input = stdin, *output = stdout, *key = NULL;
|
||||
size_t key_shift = 0;
|
||||
char zeroth_char = 0;
|
||||
int encrypt_mode = 1;
|
||||
char *endptr = NULL;
|
||||
while ((opt = getopt(argc, argv, "hedi:o:k:s:z:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'h':
|
||||
printf(
|
||||
"(c) Masahiko AMANO aka H1K0, 2024-present\n"
|
||||
"(https://github.com/H1K0/rensa)\n\n"
|
||||
"Usage:\n"
|
||||
" rensa [-e/-d] [-i <input_path>] [-o <output_path>] [-k <key_path>] [-s <key_shift>] [-z <zeroth_char>]\n\n"
|
||||
"Options:\n"
|
||||
" -h Print help and exit\n"
|
||||
" -e Encryption mode (default)\n"
|
||||
" -d Decryption mode\n"
|
||||
" -i <input_path> Input file path (stdio by default)\n"
|
||||
" -o <output_path> Output file path (stdout by default)\n"
|
||||
" -k <key_path> Key file path\n"
|
||||
" -s <key_shift> Key shift in bytes (0 by default)\n"
|
||||
" -z <zeroth_char> Zeroth char (0 by default)\n"
|
||||
);
|
||||
return 0;
|
||||
case 'd':
|
||||
encrypt_mode = 0;
|
||||
break;
|
||||
case 'i':
|
||||
input = fopen(optarg, "rb");
|
||||
if (input == NULL) {
|
||||
perror("Failed to open input file");
|
||||
return errno;
|
||||
}
|
||||
break;
|
||||
case 'o':
|
||||
output = fopen(optarg, "wb");
|
||||
if (output == NULL) {
|
||||
perror("Failed to open output file");
|
||||
return errno;
|
||||
}
|
||||
break;
|
||||
case 'k':
|
||||
key = fopen(optarg, "rb");
|
||||
if (key == NULL) {
|
||||
perror("Failed to open key file");
|
||||
return errno;
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
if (key == NULL) {
|
||||
fprintf(stderr, "Key shift is only available if key file specified\n");
|
||||
return 1;
|
||||
}
|
||||
key_shift = strtoull(optarg, &endptr, 10);
|
||||
if (*endptr != 0) {
|
||||
fprintf(stderr, "Invalid key shift\n");
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case 'z':
|
||||
zeroth_char = (char) strtol(optarg, &endptr, 10);
|
||||
if (*endptr != 0) {
|
||||
fprintf(stderr, "Invalid zeroth char\n");
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case '?':
|
||||
return 1;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (encrypt_mode) {
|
||||
return rensa_fencrypt(input, output, key, key_shift, zeroth_char);
|
||||
} else {
|
||||
return rensa_fdecrypt(input, output, key, key_shift, zeroth_char);
|
||||
}
|
||||
}
|
||||
106
rensa.c
Normal file
106
rensa.c
Normal file
@ -0,0 +1,106 @@
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "rensa.h"
|
||||
|
||||
|
||||
#define BUFSIZ 8192
|
||||
|
||||
|
||||
int rensa_encrypt(const char *plain, size_t len, const char *key, char zeroth_char, char *cipher) {
|
||||
if (key == NULL) {
|
||||
*(cipher++) = *(plain++) + zeroth_char;
|
||||
for (int i = 1; i < len; i++, plain++, cipher++) {
|
||||
*cipher = *plain + *(plain - 1);
|
||||
}
|
||||
} else {
|
||||
*(cipher++) = *(plain++) + key[(unsigned char) zeroth_char];
|
||||
for (int i = 1; i < len; i++, plain++, cipher++) {
|
||||
*cipher = *plain + key[(unsigned char) *(plain - 1)];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rensa_decrypt(const char *cipher, size_t len, const char *key, char zeroth_char, char *plain) {
|
||||
if (key == NULL) {
|
||||
*(plain++) = *(cipher++) - zeroth_char;
|
||||
for (int i = 1; i < len; i++, plain++, cipher++) {
|
||||
*plain = *cipher - *(plain - 1);
|
||||
}
|
||||
} else {
|
||||
*(plain++) = *(cipher++) - key[(unsigned char) zeroth_char];
|
||||
for (int i = 1; i < len; i++, plain++, cipher++) {
|
||||
*plain = *cipher - key[(unsigned char) *(plain - 1)];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rensa_fencrypt(FILE *input, FILE *output, FILE *key, size_t key_shift, char zeroth_char) {
|
||||
if (input == NULL) {
|
||||
input = stdin;
|
||||
}
|
||||
if (output == NULL) {
|
||||
output = stdout;
|
||||
}
|
||||
int status;
|
||||
size_t readcount;
|
||||
char key_buffer[256];
|
||||
if (key != NULL) {
|
||||
if (fseek(key, key_shift, SEEK_SET) != 0) {
|
||||
return errno;
|
||||
}
|
||||
readcount = fread(key_buffer, 1, 256, key);
|
||||
for (int i = readcount; i < 256; i += readcount) {
|
||||
rewind(key);
|
||||
readcount = fread(key_buffer + i, 1, 256 - i, key);
|
||||
}
|
||||
}
|
||||
char rbuffer[BUFSIZ], wbuffer[BUFSIZ];
|
||||
while ((readcount = fread(rbuffer, 1, BUFSIZ, input)) != 0) {
|
||||
status = rensa_encrypt(rbuffer, BUFSIZ, (key != NULL) ? key_buffer : NULL, zeroth_char, wbuffer);
|
||||
if (status != 0) {
|
||||
return status;
|
||||
}
|
||||
if (fwrite(wbuffer, 1, readcount, output) < readcount) {
|
||||
return -1;
|
||||
}
|
||||
zeroth_char = rbuffer[BUFSIZ - 1];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rensa_fdecrypt(FILE *input, FILE *output, FILE *key, size_t key_shift, char zeroth_char) {
|
||||
if (input == NULL) {
|
||||
input = stdin;
|
||||
}
|
||||
if (output == NULL) {
|
||||
output = stdout;
|
||||
}
|
||||
int status;
|
||||
size_t readcount;
|
||||
char key_buffer[256];
|
||||
if (key != NULL) {
|
||||
if (fseek(key, key_shift, SEEK_SET) != 0) {
|
||||
return errno;
|
||||
}
|
||||
readcount = fread(key_buffer, 1, 256, key);
|
||||
for (int i = readcount; i < 256; i += readcount) {
|
||||
rewind(key);
|
||||
readcount = fread(key_buffer + i, 1, 256 - i, key);
|
||||
}
|
||||
}
|
||||
char rbuffer[BUFSIZ], wbuffer[BUFSIZ];
|
||||
while ((readcount = fread(rbuffer, 1, BUFSIZ, input)) != 0) {
|
||||
status = rensa_decrypt(rbuffer, BUFSIZ, (key != NULL) ? key_buffer : NULL, zeroth_char, wbuffer);
|
||||
if (status != 0) {
|
||||
return status;
|
||||
}
|
||||
if (fwrite(wbuffer, 1, readcount, output) < readcount) {
|
||||
return -1;
|
||||
}
|
||||
zeroth_char = wbuffer[BUFSIZ - 1];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
11
rensa.h
Normal file
11
rensa.h
Normal file
@ -0,0 +1,11 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
int rensa_encrypt(const char *plain, size_t len, const char *key, char zeroth_char, char *cipher);
|
||||
|
||||
int rensa_decrypt(const char *cipher, size_t len, const char *key, char zeroth_char, char *plain);
|
||||
|
||||
int rensa_fencrypt(FILE *input, FILE *output, FILE *key, size_t key_shift, char zeroth_char);
|
||||
|
||||
int rensa_fdecrypt(FILE *input, FILE *output, FILE *key, size_t key_shift, char zeroth_char);
|
||||
Reference in New Issue
Block a user