Skip to content

Commit

Permalink
First version
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidValin committed Jun 19, 2024
0 parents commit 385e04f
Show file tree
Hide file tree
Showing 9 changed files with 179 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
./bin
13 changes: 13 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Copyright 2023 David Valin <[email protected]>

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
13 changes: 13 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
build:
@echo " - Building..."
@mkdir -p bin
@gcc -o bin/otp src/otp.c
@echo " - Built!"
@echo " - Testing..."
@sh test/otp.test.sh
@echo " - Tested!"

install:
@echo " - Installing..."
@mv ./bin/otp /usr/local/bin/otp
@echo " - Installed! You can use "otp" now"
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
## One Time Pad "otp" command

This program takes stdin, xor's it with a key file and outputs to stdout.
When it finishes it writes a new file containing the part of the key file that was not used, ending with ".next". When using one time pad, remember to never reuse the keys, that is why a new key file is created with the part that wasn't used. You should always remove the key that you have used once.

### Tutorial

[![YouTube](http://i.ytimg.com/vi/AE1kFnRsTuY/hqdefault.jpg)](https://www.youtube.com/watch?v=AE1kFnRsTuY)

### Install

* Build and test: `make`
* Install: `sudo make install`

#### How to use it

* Create a key file: `echo -n "mysupersecretkey" > key.txt`
* Encrypt using key: `echo -n "hello" | otp key.txt > cipher.txt`
* Decrypt using key: `cat cipher.txt | otp key.txt > plain.txt`

#### Next key

Everytime you run the command it will create a new file with the same name as the key file ending with ".next". You should never reuse keys once they are used (one time pad algorithm requirements), therefore you should remove the original key file and use the new key file generated next time.

Binary file added diagram.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
81 changes: 81 additions & 0 deletions src/otp.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#include <stdlib.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <time.h>

int min( int a, int b) {if (a<b) return a; return b;}

int main(int argc, char *argv[]) {
unsigned char instructions[] = "\nThis program takes stdin, xor's it with a key file, outputs the result to stdout and creates a new file containing the part of the key file that was not used, ending with \".next\".\n\nUses:\n encrypt\techo \"plain\" | otp KEY_FILE.txt > cipher.txt\n decrypt\tcat cipher.txt | otp KEY_FILE.txt > plain.txt\n\n";
if (argc == 1) {
puts(instructions);
exit(0);
}

char outfileunused[1024];
sprintf(outfileunused, argv[optind]);
time_t t = time(NULL);
struct tm tm = *localtime(&t);
sprintf(outfileunused+strlen(argv[optind]), ".%d-%02d-%02d_%02d:%02d:%02d.next", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);

struct stat buffer;
if (stat (outfileunused, &buffer) == 0) {
fputs("\n A file named %s already exists, please remove it\n\n", stderr);
return -1;
}

FILE *infile;
FILE *unused_infile_file_part;
unsigned char filebuffer;
unsigned char stdinbuffer;
int nreadfile, nreadfile2, nreadstdin;
int i;

infile=fopen(argv[optind], "r");
unused_infile_file_part = fopen(outfileunused, "w");

if (infile == NULL) {
fputs("Error opening input key file, check that it exist\n", stderr);
return -1;
}
if (unused_infile_file_part == NULL) {
fputs("Error opening next input key file\n", stderr);
return -1;
}

while(1) {
nreadstdin=fread(&stdinbuffer, 1, sizeof(unsigned char), stdin);
if (nreadstdin==1) {
nreadfile=fread(&filebuffer, 1, sizeof(unsigned char), infile);
if (nreadfile==1) {
stdinbuffer^=filebuffer;
fwrite(&stdinbuffer, 1, sizeof(unsigned char), stdout);
fflush(stdout);
continue;
} else {
printf("\n Error! Key file not as long as stdin input.\n");
return -1;
}
} else {
break;
}
}

// produce new file excluding the part of the key that was used
while(1) {
nreadfile2=fread(&filebuffer, 1, sizeof(unsigned char), infile);
if (nreadfile2==1) {
fwrite(&filebuffer, 1, sizeof(unsigned char), unused_infile_file_part);
fflush(unused_infile_file_part);
} else {
break;
}
}

fclose(stdin);
fclose(stdout);
fclose(infile);
fclose(unused_infile_file_part);
}
46 changes: 46 additions & 0 deletions test/otp.test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#!/bin/sh

# plain: 16ag
# key: abcdefghijklmn (first 4 bytes in ./test_data/test.txt file)
# expected cipher: PT
# expected next key: efghijklmn (last 4 bytes in ./test_data/test.txt file)
export PLAIN='16ag'
export OUTPUT=`echo -n $PLAIN | ./bin/otp ./test/test_data/test.txt`
export EXPECTED_OUTPUT='PT'
export EXPECTED_NEXT_KEY="efghijklmn"
export NOW=`date +"%Y-%m-%d_%H:%M:%S"`

if [[ "$OUTPUT" = "$EXPECTED_OUTPUT" ]]; then
echo " - PASS - output is correct"
else
echo " ! FAIL : Expected $EXPECTED_OUTPUT but got $OUTPUT"
exit -1
fi

if test -f "./test/test_data/test.txt.$NOW.next"; then
echo " - PASS - next key file was created"
else
echo " - FAIL : next key file was NOT created!"
exit -1
fi

export NEXT_KEY=`cat ./test/test_data/test.txt.$NOW.next`
if [[ "$NEXT_KEY" = "$EXPECTED_NEXT_KEY" ]]; then
echo " - PASS - next key file has correct key (content)"
else
echo " ! FAIL : next key file has WRONG key (content), expected '$EXPECTED_NEXT_KEY' but got '$NEXT_KEY'"
exit -1
fi

rm ./test/test_data/test.txt.$NOW.next

export ORIGINAL=`echo -n $OUTPUT | ./bin/otp ./test/test_data/test.txt`
if [[ "$ORIGINAL" = "$PLAIN" ]]; then
echo " - PASS - decryption (content) is correct"
else
echo " ! FAIL : decryption (content) is incorrect, expected '$PLAIN' but got '$ORIGINAL'"
exit -1
fi


exit 0
1 change: 1 addition & 0 deletions test/test_data/test.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
abcdefghijklmn
Binary file added tutorial.mp4
Binary file not shown.

0 comments on commit 385e04f

Please sign in to comment.