<sub>*Please don't use this for anything critical*</sub>
## What the hell is this?
An educational project on implementing a block cipher using a feistel network.
This block cipher employs a few modes of operation. Read more about them [here](#modes-of-operation).
## Features
* It has very easy syntax
* It's slow
* It absolutely tanks your ram when working with files
* Even leaves some key fragments in there✨
* It's probably super insecure
* 512-bit keys <sup>\*</sup>
* But the syntax is pythonlike easy🙇
It's pretty ghetto, you know?
## What are the actual advantages?
* It's two files to import into your project
* 1 Line to use
* 100% cross plattform
## What could I use it for?
* For data obfuscation
* If your only other option would be no encryption at all
### I am not kidding, don't use this for critical stuff! Homebrew ciphers tend to be shit!
Especially mine!🗡️
Even assumed it's a good cipher, it's implementation leaves a lot to be desired in terms of being cryptographically secure. The whole leaving partial keys in ram- thingy...
## How do I use this?
### *"I don't care about the library. Just let me use it from the command line!"*
There is a CLI version availabile [here](https://gitea.leonetienne.de/leonetienne/GCrypt/src/branch/master/GhettoCryptCLI).
### Installation as a library
Download the `.h` and `.cpp` file from [INCLUDE/](https://gitea.leonetienne.de/leonetienne/GCrypt/src/branch/master/INCLUDE) and add them to your projects files. *Single-header-magic*.
If you want to do more complex stuff, use the cipher-class [`GhettoCipher::Cipher`](https://gitea.leonetienne.de/leonetienne/GCrypt/src/branch/master/GhettoCrypt/Cipher.h) aswell as the conversion methods in [Util.h](https://gitea.leonetienne.de/leonetienne/GCrypt/src/branch/master/GhettoCrypt/Util.h). This way you can cipher on bitlevel. Examples on how to do this are in [GhettoCryptWrapper.cpp](https://gitea.leonetienne.de/leonetienne/GCrypt/src/branch/master/GhettoCrypt/GhettoCryptWrapper.cpp).
This way you could, for example, decrypt an ecrypted file directly into memory. Or use a full-length key instead of a password.
Without saying, this is more advanced and not as-easy as the methods supplied in the wrapper.
---
<sup>\*</sup> A key is always of size `BLOCK_SIZE`. The default block size is 512 (bit), but you can easily change it in [Config.h](https://gitea.leonetienne.de/leonetienne/GCrypt/src/branch/master/GhettoCrypt/Config.h) or wherever it'll be put in the INCLUDE/*.cpp. `BLOCK_SIZE` is also the minimal output length!
## The deets 🍝
### Modes of operation
* [CBC] This block cipher makes use of cipher block chaining. Nothing special.
* [IV] The initialization vector is indeed a bit of special sauce, as it depends on your key instead of being static. It is generated by running the feistel network on *E(m=seed, k=seed)*, which is a one-way function, because *m=k*.
* [RRKM] Never heard of a mode like this, so i've named it **R**olling**R**ound**K**ey**M**ode. This basically means that the round key extrapolation is carried out continously over EVERY round on EVERY block. So in addition to *M<sub>i</sub>* being dependent on *E(M<sub>i-1</sub>,K<sub>i-1,0</sub>)* due to CBC, so is now *K<sub>i</sub>* dependent on *K<sub>i-1,r</sub>* with *r* being the maximum number of extrapolated keys within a call of *E()*. This is handled within the feistel network class, as an instance lifecycle sees all blocks. Just in case you want to take a peek.
### Password to key
How does *GC* transform a password to a key?
First up, we have to establish what requirements this transformation must fulfill:
* A full key. Not just *len(passwd)\*8* bits and the rest zero-padded.
* Even if *len(passwd)\*8 > KEY_SIZE*, every bit of the password should affect the key
* Diffusion
* Ideally good collision resistance
Let's be honest, I'm not a cryptographer, I have no idea how collision resistant this is.
This means, it has to be considered *insecure*!
I have tried a few passwords brute-forcibly, experimentally (about 1mil) and have not been able to produce a collision.
size KEY_SIZE, and they are combined using *c<sub>i+1</sub> = c<sub>i</sub> ⨁ E(c=block<sub>i</sub>, k=block<sub>i</sub>)*. *c<sub>0</sub>* is a static initialization vector. The final *c* is they key corresponding to a password.