Compare commits
No commits in common. "master" and "feature/relaunch" have entirely different histories.
master
...
feature/re
56
.drone.yml
56
.drone.yml
@ -1,56 +0,0 @@
|
||||
kind: pipeline
|
||||
type: kubernetes
|
||||
name: cicd-pipeline
|
||||
|
||||
steps:
|
||||
- name: Build docs
|
||||
image: ubuntu
|
||||
commands:
|
||||
- apt-get update
|
||||
- >-
|
||||
apt-get
|
||||
install
|
||||
make
|
||||
doxygen
|
||||
graphviz
|
||||
-y
|
||||
- cd "GCryptLib/doxygen"
|
||||
- make
|
||||
|
||||
- name: Deploy docs to production
|
||||
image: ubuntu
|
||||
environment:
|
||||
SSH_PRIV:
|
||||
from_secret: ssh-priv
|
||||
SSH_PUB:
|
||||
from_secret: ssh-pub
|
||||
KNOWN_HOSTS:
|
||||
from_secret: known-hosts # this is just $(ssh-keyscan -p 2222 leonetienne.de)
|
||||
commands:
|
||||
- apt-get update
|
||||
- >-
|
||||
apt-get
|
||||
install
|
||||
openssh-client
|
||||
rsync
|
||||
-y
|
||||
- eval "$(ssh-agent -s)"
|
||||
- mkdir -p ~/.ssh
|
||||
- echo "$SSH_PRIV" > ~/.ssh/id_ed25519
|
||||
- echo "$SSH_PUB" > ~/.ssh/id_ed25519.pub
|
||||
- echo "$KNOWN_HOSTS" > ~/.ssh/known_hosts
|
||||
- chmod 600 ~/.ssh/id_ed25519
|
||||
- chmod 644 ~/.ssh/id_ed25519.pub
|
||||
- chmod 644 ~/.ssh/known_hosts
|
||||
- ssh-add
|
||||
- cd "GCryptLib/doxygen"
|
||||
- >-
|
||||
rsync
|
||||
-avz
|
||||
--recursive
|
||||
--delete
|
||||
--delete-excluded
|
||||
-e
|
||||
"ssh -o IdentitiesOnly=yes -p 2222"
|
||||
./build/
|
||||
doxygen-gcrypt@leonetienne.de:app
|
12
.gitmodules
vendored
12
.gitmodules
vendored
@ -1,17 +1,15 @@
|
||||
[submodule "StringTools"]
|
||||
path = StringTools
|
||||
url = https://code.ze.mawtrixx.net/leonetienne/StringTools.git
|
||||
url = https://gitea.leonetienne.de/leonetienne/StringTools.git
|
||||
[submodule "Hazelnupp"]
|
||||
path = Hazelnupp
|
||||
url = https://code.ze.mawtrixx.net/leonetienne/Hazelnupp.git
|
||||
url = https://gitea.leonetienne.de/leonetienne/Hazelnupp.git
|
||||
[submodule "GeneralUtility"]
|
||||
path = GeneralUtility
|
||||
url = https://code.ze.mawtrixx.net/leonetienne/GeneralUtility.git
|
||||
url = https://gitea.leonetienne.de/leonetienne/GeneralUtility.git
|
||||
[submodule "GCryptLib/exec/Eule"]
|
||||
path = GCryptLib/exec/Eule
|
||||
url = https://code.ze.mawtrixx.net/leonetienne/Eule.git
|
||||
url = https://gitea.leonetienne.de/leonetienne/Eule.git
|
||||
[submodule "GCryptLib/exec/BmpPP"]
|
||||
path = GCryptLib/exec/BmpPP
|
||||
url = https://code.ze.mawtrixx.net/leonetienne/BmpPP.git
|
||||
[submodule "BmpPP"]
|
||||
url = https://code.ze.mawtrixx.net/leonetienne/BmpPP.git
|
||||
url = https://gitea.leonetienne.de/leonetienne/BmpPP.git
|
||||
|
@ -1 +0,0 @@
|
||||
<mxfile host="app.diagrams.net" modified="2022-05-17T08:55:29.265Z" agent="5.0 (X11)" etag="82noNgqBrG7hiBNRM9Jy" version="18.0.6"><diagram id="ngb83caThQZh03zxjPih" name="Page-1">7VpNc+I4EP01VJHDUDYEkhwDJDvMMMXWcNjZuWwJq7G1sS2PLALk169alr9hQwhkApULltpS66Pfe2q5aHQGweoPQSLvG6fgN9oWXTU6w0a7bXdvLPVAyzqxXHdvEoMrGDWNcsOUPYExmn7uglGISw0l575kUdno8DAER5ZsRAi+LDebc788akRcqBmmDvHr1r8YlV66Ciu3fwbmeunItmXeBCRtbAyxRyhfFkydu0ZnIDiXSSlYDcDHzUv3Jel3v+VtNjEBodylw7/Bl88/u/F0YP9Yj9rf5uLrl+4n4+WR+Auz4Ea75yt/fcoeVdHF4pBIgo5CF2LJeKjKPlmDUM/mcDS+SLvMRNojtajZFPyUXFvEZ26ox+z9WuAm9H2Yy7xW7XUc79+B0Fi1748ng6//TEc/71RlxiTa5oIH6CrUi48WEhc8Zwoa7QEGVFIWJkUi3PjCFEOKzYMAKCMS/DU6AtCDSI/hY+Zz50EDWduUO2s4HLfU4ztEQPTYi1AyjN7d5B7doUkAcTyg2G5MYllwpF9LwvyIUAo4/pIp9LUtq3XKsbn1Y67XHUc8jNkMN14xGHFHnF8LJhQi0/hA6Ih1ZND5AOuTXvho3kAyJ11Zap0t5nMQowSI2WAsHyrBQa2fFIrbGzsMcvyNxho1WjFCLg1o9e6uFWz1RqeYhEcQmdEjmiosZLGnOyiYKl64+wXgpburhVWuU7UWfBEiATpDS71eekzCNCIOvl2q80nZPBn4qmarolqFZErpb01UJI8yn/gOVluV1s70Wx18wAOQAnmedrg0km/OPLtn6sv8BOmmJ4hXPD06xkjMqeVmvnNhVwWj7S/Q+c4LdJ6yTTo/zHX+gPHbix0hk0w1fgJEHs7YYZGnp6mRiaBmAaJ6iT8zcFGmrUhwB+LYaAbCHJYauVpWmrnXKbbi4UXrkJO+K88sU31NGAfYY7YYI+rITSZzUs4gC42mWdMoHlbuKeRlRUhFxF2CtfPkN59pNFHjJRG0cphNxnqCKwcimUk2zktv/kCjXmQBCo3QJMvE1ccX70a+T0JgOle7Cox1LIG5fIHA8IVMkqlcXSbvRl02E3XyQqIuBZMSwpQXoNIxvVKVM3JcOnZKEhkjQQcVm9+XnUxMaA+dnkxq6QnuMJTyk0EhRdEBMfGimRu/nDY373XWkuq9smyNwknIQEb5Z2XAPpYMdDfIQGXvIKS3eDFXNUcFJGZOebvKewsrJn9gudU1tb9NOywPV4Vmw7WpJEMCrd3sKxurpsUXwoHn78dSXfBAPpdf1QNVDMSGOKQ2AT6RCqnlrxcbYmNG+JOzUOY46FxXjoNqGpks0/QqfiKoOqoCql1xlOxDzZGGSrbs/dHTq6HnXuUGzT7y9aIOJBXgMZmBX8ZPKmOOCrbS3Dr/AkYp+uiriyV7IjPtD3ET4br0Srv9Rnf4fyQ1n5tM5/wjTxFj2wmyldGfrFan23sdKNImfD6P4Shhujolkv82UtplLrVv9iWlvSXZe4aUav/JutDMoHvnCacqkoMn8XhQKF3XoFS7hzUfYH0m5L86A/LffJD/efJnB+dryV91dCzy18Z5C/KnglM874sZefNMaH9zBrS3N31B/OB9hUaX9mXrqldi0mWVsbtSf4Ov7DL3Rvm4Xf+qc3YJub3l6nZa7Dype/d7Scn3pmbV0a68fG1K3rXf4lSu38LPOSe3z+FGbn9cyffIyvfmf9XRsfhfG+dN+F+/k59lVm6/79u4qub/DUua5/+w69z9Bw==</diagram></mxfile>
|
Binary file not shown.
Before Width: | Height: | Size: 25 KiB |
@ -1,24 +0,0 @@
|
||||
* Add a new iobase: bytes.
|
||||
For cleartext:
|
||||
Format is ALWAYS raw bytes. That works fine with text, and files.
|
||||
The iobase ONLY affects ciphertext!
|
||||
|
||||
For ciphertext:
|
||||
format depends..:
|
||||
|
||||
If none specified:
|
||||
- raw bytes if an outputfile is given
|
||||
- hex if output to stdout
|
||||
|
||||
If specified:
|
||||
Just use the specified iobase. Even if it means dumping bytes to stdout, or writing base-2 to files.
|
||||
|
||||
|
||||
* --intext or --infile should no longer be required. Default behaviour should be reading from stdin.
|
||||
* No guessing where to output (like file-in got saved to another file beforehand.) Default behaviour should be stdout.
|
||||
|
||||
* --progress should output reports to stderr. This way it won't disturb piping the ciphertext to another program.
|
||||
|
||||
* Add a module to generate keyfiles.
|
||||
Should seed a gcrypt prng with std::random_device, and then dump BLOCK_SIZE bits to the specified output.
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef GCRYPTCLI_VERSION_H
|
||||
#define GCRYPTCLI_VERSION_H
|
||||
|
||||
#define GCRYPTCLI_VERSION 0.12512
|
||||
#define GCRYPTCLI_VERSION 0.1251
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -23,14 +23,15 @@ Have these depencies installed:
|
||||
6) Compile: `make`.
|
||||
The executable `gcrypt` should now lie in `build/`.
|
||||
|
||||
If you want to use this globally, you could move it to `/usr/bin/`, or some other location in your $PATH. ### Options and flags
|
||||
If you want to use this globally, you could move it to `/usr/bin/`, or some other location in your $PATH.
|
||||
|
||||
### All arguments and flags:
|
||||
### Options and flags
|
||||
All arguments and flags:
|
||||
```
|
||||
CLI for the GCrypt cipher/obfuscator
|
||||
Copyright (c) 2022 Leon Etienne
|
||||
GCryptLib v0.236
|
||||
GCryptCLI v0.12511
|
||||
GCrypt v0.236
|
||||
GCrypt CLI v0.1241
|
||||
THIS IS EXPERIMENTAL SOFTWARE AND MUST BE CONSIDERED INSECURE. DO NOT USE THIS TO ENCRYPT SENSITIVE DATA! READ THE README FILES ACCESSIBLE AT "https://gitea.leonetienne.de/leonetienne/GCrypt"
|
||||
|
||||
==== AVAILABLE PARAMETERS ====
|
||||
@ -39,11 +40,7 @@ THIS IS EXPERIMENTAL SOFTWARE AND MUST BE CONSIDERED INSECURE. DO NOT USE THIS T
|
||||
|
||||
--iobase-16 VOID incompatibilities=[--iobase-bytes, --iobase-2, --iobase-8, --iobase-64, --iobase-uwu, --iobase-ugh] Interpret and format ciphertexts in base16 (hex)
|
||||
|
||||
--progress-interval INT default=['1000'] Print digestion progress reports every these many data blocks.
|
||||
|
||||
--buffer-input VOID Will read the entire input before beginning any digestion.
|
||||
|
||||
--progress -p VOID Print digestion progress to stderr. May be advisable for large files, as the cipher is rather slow.
|
||||
--progress -p VOID Print digestion progress to stdout. May be advisable for large files, as the cipher is rather slow.
|
||||
|
||||
--cli-version -v VOID Will supply the version of GCryptCLI used.
|
||||
|
||||
@ -53,7 +50,19 @@ THIS IS EXPERIMENTAL SOFTWARE AND MUST BE CONSIDERED INSECURE. DO NOT USE THIS T
|
||||
|
||||
--iobase-10 VOID incompatibilities=[--iobase-bytes, --iobase-2, --iobase-8, --iobase-16, --iobase-64, --iobase-uwu, --iobase-ugh] Interpret and format ciphertexts in base10
|
||||
|
||||
--buffer-output VOID Will digest the entire data before initiating any output.
|
||||
--ofile -o STRING incompatibilities=[--ostdout, --hash] Write output in this file.
|
||||
|
||||
--key -k STRING incompatibilities=[--keyfile, --keyask, --hash] Use this value as a password to extrapolate the encryption key. WARNING: Arguments may be logged by the system!
|
||||
|
||||
--keyask -ka VOID incompatibilities=[--key, --keyfile, --hash] Read the encryption key from stdin.
|
||||
|
||||
--no-newline VOID Don't postfix stdout output with a newline
|
||||
|
||||
--puffer-output VOID Will digest the entire data before initiating any output.
|
||||
|
||||
--puffer-input VOID Will read the entire input before beginning any digestion.
|
||||
|
||||
--decrypt -d VOID incompatibilities=[--encrypt, --hash, --generate-key] Use decryption module.
|
||||
|
||||
--lib-version VOID Will supply the version of GCryptLib used.
|
||||
|
||||
@ -71,16 +80,6 @@ THIS IS EXPERIMENTAL SOFTWARE AND MUST BE CONSIDERED INSECURE. DO NOT USE THIS T
|
||||
|
||||
--generate-key VOID incompatibilities=[--encrypt, --decrypt, --hash] Use the key generation module. Will generate a random key based on hardware events, output it, and exit.
|
||||
|
||||
--ofile -o STRING incompatibilities=[--ostdout, --hash] Write output in this file.
|
||||
|
||||
--key -k STRING incompatibilities=[--keyfile, --keyask, --hash] Use this value as a password to extrapolate the encryption key. WARNING: Arguments may be logged by the system!
|
||||
|
||||
--keyask -ka VOID incompatibilities=[--key, --keyfile, --hash] Read the encryption key from stdin.
|
||||
|
||||
--no-newline VOID Don't postfix stdout output with a newline
|
||||
|
||||
--decrypt -d VOID incompatibilities=[--encrypt, --hash, --generate-key] Use decryption module.
|
||||
|
||||
--hash -h VOID incompatibilities=[--encrypt, --decrypt, --generate-key] Use the GHash hash module to calculate a hashsum.
|
||||
|
||||
--intext -it STRING incompatibilities=[--infile] Encrypt this string.
|
||||
@ -102,8 +101,9 @@ hello, world!
|
||||
```
|
||||
|
||||
#### What about not using hex?
|
||||
> :warning: Custom bases are super imperformant. Please only use them for text-based input...
|
||||
> The larger the base, the exponentially longer it takes to recode.
|
||||
> :warning: Custom bases are super imperformant.
|
||||
> Encrypting all text in main.cpp took about two seconds.
|
||||
> Outputting it in base-64 took just over ONE MINUTE. In base-2 over SEVEN MINUTES. The general trend seems to be, the larger the base, the better it performs.
|
||||
|
||||
```sh
|
||||
$ gcrypt -e --keyask --intext "hello, world!" --iobase-2
|
||||
@ -130,34 +130,44 @@ $ gcrypt -e --key "secretpassword" --intext "hello, world!"
|
||||
```sh
|
||||
$ gcrypt -e --keyfile "dog.jpg" --intext "hello, world!"
|
||||
```
|
||||
> :warning: Some operating systems will log cli arguments! One might find your keyfile!
|
||||
|
||||
#### Creating keyfiles
|
||||
```sh
|
||||
$ gcrypt --generate-key --ofile "my-keyfile.bin"
|
||||
```
|
||||
This will generate a random 512-bit keyfile from hardware events and other random sources, if available.
|
||||
To see how this randomness gets sourced, see [std::random_device](https://en.cppreference.com/w/cpp/numeric/random/random_device).
|
||||
This will generate a random 512-bit keyfile from hardware events
|
||||
> :warning: Some operating systems will log cli arguments! One might find your keyfile!
|
||||
|
||||
#### Encrypting files
|
||||
```sh
|
||||
$ gcrypt -e --keyask --infile "cat.jpg" --ofile "cat.jpg.crypt"
|
||||
$ gcrypt -e --keyask --infile "cat.jpg"
|
||||
```
|
||||
File `cat.jpg.crypt` will be created.
|
||||
|
||||
#### Encrypting files to a target file name
|
||||
```sh
|
||||
$ gcrypt -e --keyask --infile "cat.jpg" -o "encrypted_cat.jpg"
|
||||
```
|
||||
File `encrypted_cat.jpg` will be created.
|
||||
|
||||
#### Decrypting files
|
||||
```sh
|
||||
$ gcrypt -d --keyask --infile "cat.jpg.crypt" --ofile "decrypted_cat.jpg"
|
||||
$ gcrypt -d --keyask --infile "cat.jpg.crypt"
|
||||
```
|
||||
File `decrypted_cat.jpg` will be created. You can now open it again. Its contents match `cat.jpg`.
|
||||
File `cat.jpg.crypt.plain` will be created. Its contents match `cat.jpg`
|
||||
> :warning: Since this is a block cipher, decrypted files may be tailpadded with a few nullbytes.
|
||||
|
||||
#### Decrypting files to a target file name
|
||||
```sh
|
||||
$ gcrypt -d --keyask --infile "cat.jpg.crypt" -o "decrypted_cat.jpg"
|
||||
```
|
||||
File `decrypted_cat.jpg` will be created. You can now open it again.
|
||||
|
||||
#### Encrypting large files takes time. How's the progress?
|
||||
```sh
|
||||
$ gcrypt -e --keyask --infile "cat.jpg" --buffer-input --progress
|
||||
$ gcrypt -e --keyask --infile "cat.jpg" --progress
|
||||
```
|
||||
Something along the lines of `Encrypting... (Block 200 / 1148 - 17.4216%)` will be regularly, but not too often, printed to stderr.
|
||||
Obviously, to print progress, we have to know the size of the input. Hence, it has to be buffered.
|
||||
Something along the lines of `Encrypting... (Block 200 / 1148 - 17.4216%)` will be regularly, but not too often, printed to stdout.
|
||||
|
||||
#### Any cipher can also compute hashsums
|
||||
```sh
|
||||
@ -167,16 +177,15 @@ a96f42c9d97e46b9e1ed7de5182770170d4ef9b7b8264f3fbd89b38dc60c1fe06232653f58560133
|
||||
$ gcrypt -h --infile "cat.jpg"
|
||||
fe6bdfb6ec39771c4fdcdc40e52397bcd67fbfef0ad5a15ebbd8b9e4c2a815848b3984eda5ef6f727e9e420c23500c90c42ab80ac5659048be8969357741e3e5
|
||||
```
|
||||
The hashsum will always be of size BLOCK_SIZE. That is 512 bits.
|
||||
The hashsum will always be of size BLOCK_SIZE. That is 512.
|
||||
|
||||
#### What version am i running?
|
||||
Depending on whether you want to know the GCryptLib version or the CLI's version,
|
||||
Depending on wether you want to know the GCrypt version or the CLI's version,
|
||||
use either `--cli-version` or `--lib-version`.
|
||||
It will print out a floating point number.
|
||||
You can see both in the `--help`-page.
|
||||
|
||||
#### Streaming the output of file en/decryption.
|
||||
Easily! If you do not supply any output or input, stdout and stdin will be used instead!
|
||||
#### I want to stream the output of file en/decryption.
|
||||
// Easily! If you do not supply any output or input, stdout and stdin will be used instead!
|
||||
```sh
|
||||
# mpv is a media player, as an example
|
||||
$ gcrypt -d --key "123" --infile "music.mp3.crypt" | mpv -
|
||||
@ -186,8 +195,8 @@ $ gcrypt -d --key "123" --infile "music.mp3.crypt" | mpv -
|
||||
By default, gcrypt will read a block, digest it, and output the result immediately.
|
||||
Sometimes you don't want that. Use these flags, respectively:
|
||||
```
|
||||
--buffer-input # Reads all input to memory before beginning to digest it
|
||||
--buffer-output # Digests all input before beginning to write any
|
||||
--puffer-input # Reads all input to memory before beginning to digest it
|
||||
--puffer-output # Digests all input before beginning to write any
|
||||
```
|
||||
|
||||
## Esoteric data formats
|
||||
@ -203,14 +212,6 @@ $ gcrypt -e --keyask --intext "hello, world!" --iobase-ugh
|
||||
Grr... Wha-? Aah! Aah! Uh-huh... Aah! Grr... Aah! Aah! Uh-huh... Ah... Ugh Grr... Ugh Pft! Nu-uh... Gah! Bah! Huh...? Ah... Uh-huh... Wha-? Pft! Nu-uh... Ugh Wha-? Psh! Agh! Ah... Aah! Nu-uh... Psh! Pft! Nu-uh... Psh! Shh! Gah! Ah... Pft! Gah! Shh! Bah! Gah! Uh-huh... Gah! Duh! Aah! Uh-huh... Er- Nu-uh... Gah! Wha-? Pft! Er- Shh! Ah... Huh...? Er- Wha-? Uh-huh... Ah... Shh! Ugh Bah! Wha-? Uaah! Ah... Nu-uh... Uh-huh... Ugh Pft! Pft! Gah! Shh! Shh! Wha-? Bah! Ugh Grr... Aah! Pft! Nu-uh... Ah... Aah! Agh! Er- Psh! Uaah! Nu-uh... Ugh Wha-? Uh-huh... Shh! Pft! Aah! Agh! Grr... Agh! Agh! Grr... Pft! Wha-? Wha-? Uh-huh... Aah! Ugh Aah! Pft! Gah! Bah! Huh...? Ugh Bah! Uaah! Gah! Bah! Duh! Duh! Uh-huh... Grr... Ah... Grr... Ugh Ah... Pft!
|
||||
```
|
||||
|
||||
Yes, you can send these... *adventorous* texsts to your friends, and they can actually decipher them
|
||||
back to the original message :). Almost going a bit into the steganography territory here, hehe.
|
||||
|
||||
These weird number bases don't impact security at all. This is because they are just that.
|
||||
Number bases, to represent a bunch of bytes, that is our ciphertext.
|
||||
|
||||
These just bring a bit more fun into the big world of cryptography :).
|
||||
|
||||
## LICENSE
|
||||
```
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
|
@ -13,8 +13,8 @@ void CommandlineInterface::Init(int argc, const char* const* argv) {
|
||||
std::stringstream ss;
|
||||
ss << "CLI for the GCrypt cipher/obfuscator" << std::endl
|
||||
<< "Copyright (c) 2022 Leon Etienne" << std::endl
|
||||
<< "GCryptLib v" << GCRYPT_VERSION << std::endl
|
||||
<< "GCryptCLI v" << GCRYPTCLI_VERSION << std::endl
|
||||
<< "GCrypt v" << GCRYPT_VERSION << std::endl
|
||||
<< "GCrypt CLI v" << GCRYPTCLI_VERSION << std::endl
|
||||
<< "THIS IS EXPERIMENTAL SOFTWARE AND MUST BE CONSIDERED INSECURE. DO NOT USE THIS TO ENCRYPT SENSITIVE DATA! READ THE README FILES ACCESSIBLE AT \"https://gitea.leonetienne.de/leonetienne/GCrypt\"";
|
||||
nupp.SetBriefDescription(ss.str());
|
||||
ss.str("");
|
||||
@ -102,11 +102,11 @@ void CommandlineInterface::Init(int argc, const char* const* argv) {
|
||||
nupp.RegisterConstraint("--cli-version", ParamConstraint(true, DATA_TYPE::VOID, {}, false, {}));
|
||||
nupp.RegisterAbbreviation("-v", "--cli-version");
|
||||
|
||||
nupp.RegisterDescription("--buffer-input", "Will read the entire input before beginning any digestion.");
|
||||
nupp.RegisterConstraint("--buffer-input", ParamConstraint(true, DATA_TYPE::VOID, {}, false, {}));
|
||||
nupp.RegisterDescription("--puffer-input", "Will read the entire input before beginning any digestion.");
|
||||
nupp.RegisterConstraint("--puffer-input", ParamConstraint(true, DATA_TYPE::VOID, {}, false, {}));
|
||||
|
||||
nupp.RegisterDescription("--buffer-output", "Will digest the entire data before initiating any output.");
|
||||
nupp.RegisterConstraint("--buffer-output", ParamConstraint(true, DATA_TYPE::VOID, {}, false, {}));
|
||||
nupp.RegisterDescription("--puffer-output", "Will digest the entire data before initiating any output.");
|
||||
nupp.RegisterConstraint("--puffer-output", ParamConstraint(true, DATA_TYPE::VOID, {}, false, {}));
|
||||
|
||||
nupp.RegisterDescription("--no-newline", "Don't postfix stdout output with a newline");
|
||||
nupp.RegisterConstraint("--no-newline", ParamConstraint(true, DATA_TYPE::VOID, {}, false, {}));
|
||||
@ -173,10 +173,10 @@ void CommandlineInterface::SpecialCompatibilityChecking() {
|
||||
|
||||
if (
|
||||
(nupp.HasParam("--progress")) &&
|
||||
(!nupp.HasParam("--buffer-input"))
|
||||
(!nupp.HasParam("--puffer-input"))
|
||||
|
||||
) {
|
||||
CrashWithMsg("--progress requires --buffer-input to work!");
|
||||
CrashWithMsg("--progress requires --puffer-input to work!");
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -57,7 +57,9 @@ void DataIngestionLayer::Init() {
|
||||
}
|
||||
|
||||
// Derive from our the current module if we're reading ciphertext or not
|
||||
if (Configuration::activeModule == Configuration::MODULE::DECRYPTION) {
|
||||
if (
|
||||
(Configuration::activeModule == Configuration::MODULE::DECRYPTION)
|
||||
) {
|
||||
isReadingCiphertext = true;
|
||||
}
|
||||
else {
|
||||
@ -323,16 +325,16 @@ bool DataIngestionLayer::ReachedEOF() {
|
||||
}
|
||||
|
||||
bool DataIngestionLayer::IsBlockReady() {
|
||||
// We're not ready, if we haven't reached EOF, if we should buffer
|
||||
// We're not ready, if we haven't reached EOF, if we should puffer
|
||||
// the input.
|
||||
if (
|
||||
(CommandlineInterface::Get().HasParam("--buffer-input")) &&
|
||||
(CommandlineInterface::Get().HasParam("--puffer-input")) &&
|
||||
(!reachedEof)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we're not buffering, just return whether or not
|
||||
// If we're not puffering, just return whether or not
|
||||
// we have any blocks...
|
||||
return blocks.size() > 0;
|
||||
}
|
||||
|
@ -65,13 +65,13 @@ void DataOutputLayer::WriteBlock() {
|
||||
}
|
||||
|
||||
// Check if we have any block to write
|
||||
// and if we should (output-buffering)
|
||||
// and if we should (output-puffering)
|
||||
// Basically: only output if we have anything to output, and
|
||||
// if --buffer-output is given, only output once we have reachedEof.
|
||||
// if --puffer-output is given, only output once we have reachedEof.
|
||||
if (
|
||||
(blocks.size() > 0) &&
|
||||
(
|
||||
(!CommandlineInterface::Get().HasParam("--buffer-output")) ||
|
||||
(!CommandlineInterface::Get().HasParam("--puffer-output")) ||
|
||||
(reachedEof)
|
||||
)
|
||||
) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
all:
|
||||
# Copy all but the header of the readme here
|
||||
tail ../../readme.md -n +9 > index.md
|
||||
tail ../../readme.md -n +2 > index.md
|
||||
#
|
||||
# Run doxygen
|
||||
doxygen doxyfig
|
||||
|
@ -32,7 +32,7 @@ DOXYFILE_ENCODING = UTF-8
|
||||
# title of most generated pages and in a few other places.
|
||||
# The default value is: My Project.
|
||||
|
||||
PROJECT_NAME = "Leonetienne/GCrypt"
|
||||
PROJECT_NAME = "Leonetienne/GhettoCrypt"
|
||||
|
||||
# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
|
||||
# could be handy for archiving the generated documentation or if some version
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include <cstdint>
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include <iosfwd>
|
||||
#include <ostream>
|
||||
#include <bitset>
|
||||
|
||||
namespace Leonetienne::GCrypt {
|
||||
|
@ -9,11 +9,7 @@
|
||||
|
||||
// Just to be sure, the compiler will optimize this
|
||||
// little formula out, let's do it in the preprocessor
|
||||
namespace {
|
||||
constexpr std::size_t MAT_INDEX(const std::size_t row, const std::size_t column) {
|
||||
return column*4 + row;
|
||||
}
|
||||
}
|
||||
#define MAT_INDEX(row, column) (column*4 + row)
|
||||
|
||||
namespace Leonetienne::GCrypt {
|
||||
|
||||
@ -152,25 +148,25 @@ namespace Leonetienne::GCrypt {
|
||||
|
||||
// Maybe pre-calculate the 1d-index...?
|
||||
|
||||
m.Get(MAT_INDEX(0, 0)) = (this->Get(MAT_INDEX(0, 0)) * o.Get(MAT_INDEX(0, 0))) + (this->Get(MAT_INDEX(0, 1)) * o.Get(MAT_INDEX(1, 0))) + (this->Get(MAT_INDEX(0, 2)) * o.Get(MAT_INDEX(2, 0))) + (this->Get(MAT_INDEX(0, 3)) * o.Get(MAT_INDEX(3, 0)));
|
||||
m.Get(MAT_INDEX(0, 1)) = (this->Get(MAT_INDEX(0, 0)) * o.Get(MAT_INDEX(0, 1))) + (this->Get(MAT_INDEX(0, 1)) * o.Get(MAT_INDEX(1, 1))) + (this->Get(MAT_INDEX(0, 2)) * o.Get(MAT_INDEX(2, 1))) + (this->Get(MAT_INDEX(0, 3)) * o.Get(MAT_INDEX(3, 1)));
|
||||
m.Get(MAT_INDEX(0, 2)) = (this->Get(MAT_INDEX(0, 0)) * o.Get(MAT_INDEX(0, 2))) + (this->Get(MAT_INDEX(0, 1)) * o.Get(MAT_INDEX(1, 2))) + (this->Get(MAT_INDEX(0, 2)) * o.Get(MAT_INDEX(2, 2))) + (this->Get(MAT_INDEX(0, 3)) * o.Get(MAT_INDEX(3, 2)));
|
||||
m.Get(MAT_INDEX(0, 3)) = (this->Get(MAT_INDEX(0, 0)) * o.Get(MAT_INDEX(0, 3))) + (this->Get(MAT_INDEX(0, 1)) * o.Get(MAT_INDEX(1, 3))) + (this->Get(MAT_INDEX(0, 2)) * o.Get(MAT_INDEX(2, 3))) + (this->Get(MAT_INDEX(0, 3)) * o.Get(MAT_INDEX(3, 3)));
|
||||
m.Get(0, 0) = (this->Get(0, 0) * o.Get(0, 0)) + (this->Get(0, 1) * o.Get(1, 0)) + (this->Get(0, 2) * o.Get(2, 0)) + (this->Get(0, 3) * o.Get(3, 0));
|
||||
m.Get(0, 1) = (this->Get(0, 0) * o.Get(0, 1)) + (this->Get(0, 1) * o.Get(1, 1)) + (this->Get(0, 2) * o.Get(2, 1)) + (this->Get(0, 3) * o.Get(3, 1));
|
||||
m.Get(0, 2) = (this->Get(0, 0) * o.Get(0, 2)) + (this->Get(0, 1) * o.Get(1, 2)) + (this->Get(0, 2) * o.Get(2, 2)) + (this->Get(0, 3) * o.Get(3, 2));
|
||||
m.Get(0, 3) = (this->Get(0, 0) * o.Get(0, 3)) + (this->Get(0, 1) * o.Get(1, 3)) + (this->Get(0, 2) * o.Get(2, 3)) + (this->Get(0, 3) * o.Get(3, 3));
|
||||
|
||||
m.Get(MAT_INDEX(1, 0)) = (this->Get(MAT_INDEX(1, 0)) * o.Get(MAT_INDEX(0, 0))) + (this->Get(MAT_INDEX(1, 1)) * o.Get(MAT_INDEX(1, 0))) + (this->Get(MAT_INDEX(1, 2)) * o.Get(MAT_INDEX(2, 0))) + (this->Get(MAT_INDEX(1, 3)) * o.Get(MAT_INDEX(3, 0)));
|
||||
m.Get(MAT_INDEX(1, 1)) = (this->Get(MAT_INDEX(1, 0)) * o.Get(MAT_INDEX(0, 1))) + (this->Get(MAT_INDEX(1, 1)) * o.Get(MAT_INDEX(1, 1))) + (this->Get(MAT_INDEX(1, 2)) * o.Get(MAT_INDEX(2, 1))) + (this->Get(MAT_INDEX(1, 3)) * o.Get(MAT_INDEX(3, 1)));
|
||||
m.Get(MAT_INDEX(1, 2)) = (this->Get(MAT_INDEX(1, 0)) * o.Get(MAT_INDEX(0, 2))) + (this->Get(MAT_INDEX(1, 1)) * o.Get(MAT_INDEX(1, 2))) + (this->Get(MAT_INDEX(1, 2)) * o.Get(MAT_INDEX(2, 2))) + (this->Get(MAT_INDEX(1, 3)) * o.Get(MAT_INDEX(3, 2)));
|
||||
m.Get(MAT_INDEX(1, 3)) = (this->Get(MAT_INDEX(1, 0)) * o.Get(MAT_INDEX(0, 3))) + (this->Get(MAT_INDEX(1, 1)) * o.Get(MAT_INDEX(1, 3))) + (this->Get(MAT_INDEX(1, 2)) * o.Get(MAT_INDEX(2, 3))) + (this->Get(MAT_INDEX(1, 3)) * o.Get(MAT_INDEX(3, 3)));
|
||||
m.Get(1, 0) = (this->Get(1, 0) * o.Get(0, 0)) + (this->Get(1, 1) * o.Get(1, 0)) + (this->Get(1, 2) * o.Get(2, 0)) + (this->Get(1, 3) * o.Get(3, 0));
|
||||
m.Get(1, 1) = (this->Get(1, 0) * o.Get(0, 1)) + (this->Get(1, 1) * o.Get(1, 1)) + (this->Get(1, 2) * o.Get(2, 1)) + (this->Get(1, 3) * o.Get(3, 1));
|
||||
m.Get(1, 2) = (this->Get(1, 0) * o.Get(0, 2)) + (this->Get(1, 1) * o.Get(1, 2)) + (this->Get(1, 2) * o.Get(2, 2)) + (this->Get(1, 3) * o.Get(3, 2));
|
||||
m.Get(1, 3) = (this->Get(1, 0) * o.Get(0, 3)) + (this->Get(1, 1) * o.Get(1, 3)) + (this->Get(1, 2) * o.Get(2, 3)) + (this->Get(1, 3) * o.Get(3, 3));
|
||||
|
||||
m.Get(MAT_INDEX(2, 0)) = (this->Get(MAT_INDEX(2, 0)) * o.Get(MAT_INDEX(0, 0))) + (this->Get(MAT_INDEX(2, 1)) * o.Get(MAT_INDEX(1, 0))) + (this->Get(MAT_INDEX(2, 2)) * o.Get(MAT_INDEX(2, 0))) + (this->Get(MAT_INDEX(2, 3)) * o.Get(MAT_INDEX(3, 0)));
|
||||
m.Get(MAT_INDEX(2, 1)) = (this->Get(MAT_INDEX(2, 0)) * o.Get(MAT_INDEX(0, 1))) + (this->Get(MAT_INDEX(2, 1)) * o.Get(MAT_INDEX(1, 1))) + (this->Get(MAT_INDEX(2, 2)) * o.Get(MAT_INDEX(2, 1))) + (this->Get(MAT_INDEX(2, 3)) * o.Get(MAT_INDEX(3, 1)));
|
||||
m.Get(MAT_INDEX(2, 2)) = (this->Get(MAT_INDEX(2, 0)) * o.Get(MAT_INDEX(0, 2))) + (this->Get(MAT_INDEX(2, 1)) * o.Get(MAT_INDEX(1, 2))) + (this->Get(MAT_INDEX(2, 2)) * o.Get(MAT_INDEX(2, 2))) + (this->Get(MAT_INDEX(2, 3)) * o.Get(MAT_INDEX(3, 2)));
|
||||
m.Get(MAT_INDEX(2, 3)) = (this->Get(MAT_INDEX(2, 0)) * o.Get(MAT_INDEX(0, 3))) + (this->Get(MAT_INDEX(2, 1)) * o.Get(MAT_INDEX(1, 3))) + (this->Get(MAT_INDEX(2, 2)) * o.Get(MAT_INDEX(2, 3))) + (this->Get(MAT_INDEX(2, 3)) * o.Get(MAT_INDEX(3, 3)));
|
||||
m.Get(2, 0) = (this->Get(2, 0) * o.Get(0, 0)) + (this->Get(2, 1) * o.Get(1, 0)) + (this->Get(2, 2) * o.Get(2, 0)) + (this->Get(2, 3) * o.Get(3, 0));
|
||||
m.Get(2, 1) = (this->Get(2, 0) * o.Get(0, 1)) + (this->Get(2, 1) * o.Get(1, 1)) + (this->Get(2, 2) * o.Get(2, 1)) + (this->Get(2, 3) * o.Get(3, 1));
|
||||
m.Get(2, 2) = (this->Get(2, 0) * o.Get(0, 2)) + (this->Get(2, 1) * o.Get(1, 2)) + (this->Get(2, 2) * o.Get(2, 2)) + (this->Get(2, 3) * o.Get(3, 2));
|
||||
m.Get(2, 3) = (this->Get(2, 0) * o.Get(0, 3)) + (this->Get(2, 1) * o.Get(1, 3)) + (this->Get(2, 2) * o.Get(2, 3)) + (this->Get(2, 3) * o.Get(3, 3));
|
||||
|
||||
m.Get(MAT_INDEX(3, 0)) = (this->Get(MAT_INDEX(3, 0)) * o.Get(MAT_INDEX(0, 0))) + (this->Get(MAT_INDEX(3, 1)) * o.Get(MAT_INDEX(1, 0))) + (this->Get(MAT_INDEX(3, 2)) * o.Get(MAT_INDEX(2, 0))) + (this->Get(MAT_INDEX(3, 3)) * o.Get(MAT_INDEX(3, 0)));
|
||||
m.Get(MAT_INDEX(3, 1)) = (this->Get(MAT_INDEX(3, 0)) * o.Get(MAT_INDEX(0, 1))) + (this->Get(MAT_INDEX(3, 1)) * o.Get(MAT_INDEX(1, 1))) + (this->Get(MAT_INDEX(3, 2)) * o.Get(MAT_INDEX(2, 1))) + (this->Get(MAT_INDEX(3, 3)) * o.Get(MAT_INDEX(3, 1)));
|
||||
m.Get(MAT_INDEX(3, 2)) = (this->Get(MAT_INDEX(3, 0)) * o.Get(MAT_INDEX(0, 2))) + (this->Get(MAT_INDEX(3, 1)) * o.Get(MAT_INDEX(1, 2))) + (this->Get(MAT_INDEX(3, 2)) * o.Get(MAT_INDEX(2, 2))) + (this->Get(MAT_INDEX(3, 3)) * o.Get(MAT_INDEX(3, 2)));
|
||||
m.Get(MAT_INDEX(3, 3)) = (this->Get(MAT_INDEX(3, 0)) * o.Get(MAT_INDEX(0, 3))) + (this->Get(MAT_INDEX(3, 1)) * o.Get(MAT_INDEX(1, 3))) + (this->Get(MAT_INDEX(3, 2)) * o.Get(MAT_INDEX(2, 3))) + (this->Get(MAT_INDEX(3, 3)) * o.Get(MAT_INDEX(3, 3)));
|
||||
m.Get(3, 0) = (this->Get(3, 0) * o.Get(0, 0)) + (this->Get(3, 1) * o.Get(1, 0)) + (this->Get(3, 2) * o.Get(2, 0)) + (this->Get(3, 3) * o.Get(3, 0));
|
||||
m.Get(3, 1) = (this->Get(3, 0) * o.Get(0, 1)) + (this->Get(3, 1) * o.Get(1, 1)) + (this->Get(3, 2) * o.Get(2, 1)) + (this->Get(3, 3) * o.Get(3, 1));
|
||||
m.Get(3, 2) = (this->Get(3, 0) * o.Get(0, 2)) + (this->Get(3, 1) * o.Get(1, 2)) + (this->Get(3, 2) * o.Get(2, 2)) + (this->Get(3, 3) * o.Get(3, 2));
|
||||
m.Get(3, 3) = (this->Get(3, 0) * o.Get(0, 3)) + (this->Get(3, 1) * o.Get(1, 3)) + (this->Get(3, 2) * o.Get(2, 3)) + (this->Get(3, 3) * o.Get(3, 3));
|
||||
|
||||
return m;
|
||||
}
|
||||
@ -187,25 +183,25 @@ namespace Leonetienne::GCrypt {
|
||||
|
||||
// Maybe pre-calculate the 1d-index...?
|
||||
|
||||
this->Get(MAT_INDEX(0, 0)) = (m.Get(MAT_INDEX(0, 0)) * o.Get(MAT_INDEX(0, 0))) + (m.Get(MAT_INDEX(0, 1)) * o.Get(MAT_INDEX(1, 0))) + (m.Get(MAT_INDEX(0, 2)) * o.Get(MAT_INDEX(2, 0))) + (m.Get(MAT_INDEX(0, 3)) * o.Get(MAT_INDEX(3, 0)));
|
||||
this->Get(MAT_INDEX(0, 1)) = (m.Get(MAT_INDEX(0, 0)) * o.Get(MAT_INDEX(0, 1))) + (m.Get(MAT_INDEX(0, 1)) * o.Get(MAT_INDEX(1, 1))) + (m.Get(MAT_INDEX(0, 2)) * o.Get(MAT_INDEX(2, 1))) + (m.Get(MAT_INDEX(0, 3)) * o.Get(MAT_INDEX(3, 1)));
|
||||
this->Get(MAT_INDEX(0, 2)) = (m.Get(MAT_INDEX(0, 0)) * o.Get(MAT_INDEX(0, 2))) + (m.Get(MAT_INDEX(0, 1)) * o.Get(MAT_INDEX(1, 2))) + (m.Get(MAT_INDEX(0, 2)) * o.Get(MAT_INDEX(2, 2))) + (m.Get(MAT_INDEX(0, 3)) * o.Get(MAT_INDEX(3, 2)));
|
||||
this->Get(MAT_INDEX(0, 3)) = (m.Get(MAT_INDEX(0, 0)) * o.Get(MAT_INDEX(0, 3))) + (m.Get(MAT_INDEX(0, 1)) * o.Get(MAT_INDEX(1, 3))) + (m.Get(MAT_INDEX(0, 2)) * o.Get(MAT_INDEX(2, 3))) + (m.Get(MAT_INDEX(0, 3)) * o.Get(MAT_INDEX(3, 3)));
|
||||
this->Get(0, 0) = (m.Get(0, 0) * o.Get(0, 0)) + (m.Get(0, 1) * o.Get(1, 0)) + (m.Get(0, 2) * o.Get(2, 0)) + (m.Get(0, 3) * o.Get(3, 0));
|
||||
this->Get(0, 1) = (m.Get(0, 0) * o.Get(0, 1)) + (m.Get(0, 1) * o.Get(1, 1)) + (m.Get(0, 2) * o.Get(2, 1)) + (m.Get(0, 3) * o.Get(3, 1));
|
||||
this->Get(0, 2) = (m.Get(0, 0) * o.Get(0, 2)) + (m.Get(0, 1) * o.Get(1, 2)) + (m.Get(0, 2) * o.Get(2, 2)) + (m.Get(0, 3) * o.Get(3, 2));
|
||||
this->Get(0, 3) = (m.Get(0, 0) * o.Get(0, 3)) + (m.Get(0, 1) * o.Get(1, 3)) + (m.Get(0, 2) * o.Get(2, 3)) + (m.Get(0, 3) * o.Get(3, 3));
|
||||
|
||||
this->Get(MAT_INDEX(1, 0)) = (m.Get(MAT_INDEX(1, 0)) * o.Get(MAT_INDEX(0, 0))) + (m.Get(MAT_INDEX(1, 1)) * o.Get(MAT_INDEX(1, 0))) + (m.Get(MAT_INDEX(1, 2)) * o.Get(MAT_INDEX(2, 0))) + (m.Get(MAT_INDEX(1, 3)) * o.Get(MAT_INDEX(3, 0)));
|
||||
this->Get(MAT_INDEX(1, 1)) = (m.Get(MAT_INDEX(1, 0)) * o.Get(MAT_INDEX(0, 1))) + (m.Get(MAT_INDEX(1, 1)) * o.Get(MAT_INDEX(1, 1))) + (m.Get(MAT_INDEX(1, 2)) * o.Get(MAT_INDEX(2, 1))) + (m.Get(MAT_INDEX(1, 3)) * o.Get(MAT_INDEX(3, 1)));
|
||||
this->Get(MAT_INDEX(1, 2)) = (m.Get(MAT_INDEX(1, 0)) * o.Get(MAT_INDEX(0, 2))) + (m.Get(MAT_INDEX(1, 1)) * o.Get(MAT_INDEX(1, 2))) + (m.Get(MAT_INDEX(1, 2)) * o.Get(MAT_INDEX(2, 2))) + (m.Get(MAT_INDEX(1, 3)) * o.Get(MAT_INDEX(3, 2)));
|
||||
this->Get(MAT_INDEX(1, 3)) = (m.Get(MAT_INDEX(1, 0)) * o.Get(MAT_INDEX(0, 3))) + (m.Get(MAT_INDEX(1, 1)) * o.Get(MAT_INDEX(1, 3))) + (m.Get(MAT_INDEX(1, 2)) * o.Get(MAT_INDEX(2, 3))) + (m.Get(MAT_INDEX(1, 3)) * o.Get(MAT_INDEX(3, 3)));
|
||||
this->Get(1, 0) = (m.Get(1, 0) * o.Get(0, 0)) + (m.Get(1, 1) * o.Get(1, 0)) + (m.Get(1, 2) * o.Get(2, 0)) + (m.Get(1, 3) * o.Get(3, 0));
|
||||
this->Get(1, 1) = (m.Get(1, 0) * o.Get(0, 1)) + (m.Get(1, 1) * o.Get(1, 1)) + (m.Get(1, 2) * o.Get(2, 1)) + (m.Get(1, 3) * o.Get(3, 1));
|
||||
this->Get(1, 2) = (m.Get(1, 0) * o.Get(0, 2)) + (m.Get(1, 1) * o.Get(1, 2)) + (m.Get(1, 2) * o.Get(2, 2)) + (m.Get(1, 3) * o.Get(3, 2));
|
||||
this->Get(1, 3) = (m.Get(1, 0) * o.Get(0, 3)) + (m.Get(1, 1) * o.Get(1, 3)) + (m.Get(1, 2) * o.Get(2, 3)) + (m.Get(1, 3) * o.Get(3, 3));
|
||||
|
||||
this->Get(MAT_INDEX(2, 0)) = (m.Get(MAT_INDEX(2, 0)) * o.Get(MAT_INDEX(0, 0))) + (m.Get(MAT_INDEX(2, 1)) * o.Get(MAT_INDEX(1, 0))) + (m.Get(MAT_INDEX(2, 2)) * o.Get(MAT_INDEX(2, 0))) + (m.Get(MAT_INDEX(2, 3)) * o.Get(MAT_INDEX(3, 0)));
|
||||
this->Get(MAT_INDEX(2, 1)) = (m.Get(MAT_INDEX(2, 0)) * o.Get(MAT_INDEX(0, 1))) + (m.Get(MAT_INDEX(2, 1)) * o.Get(MAT_INDEX(1, 1))) + (m.Get(MAT_INDEX(2, 2)) * o.Get(MAT_INDEX(2, 1))) + (m.Get(MAT_INDEX(2, 3)) * o.Get(MAT_INDEX(3, 1)));
|
||||
this->Get(MAT_INDEX(2, 2)) = (m.Get(MAT_INDEX(2, 0)) * o.Get(MAT_INDEX(0, 2))) + (m.Get(MAT_INDEX(2, 1)) * o.Get(MAT_INDEX(1, 2))) + (m.Get(MAT_INDEX(2, 2)) * o.Get(MAT_INDEX(2, 2))) + (m.Get(MAT_INDEX(2, 3)) * o.Get(MAT_INDEX(3, 2)));
|
||||
this->Get(MAT_INDEX(2, 3)) = (m.Get(MAT_INDEX(2, 0)) * o.Get(MAT_INDEX(0, 3))) + (m.Get(MAT_INDEX(2, 1)) * o.Get(MAT_INDEX(1, 3))) + (m.Get(MAT_INDEX(2, 2)) * o.Get(MAT_INDEX(2, 3))) + (m.Get(MAT_INDEX(2, 3)) * o.Get(MAT_INDEX(3, 3)));
|
||||
this->Get(2, 0) = (m.Get(2, 0) * o.Get(0, 0)) + (m.Get(2, 1) * o.Get(1, 0)) + (m.Get(2, 2) * o.Get(2, 0)) + (m.Get(2, 3) * o.Get(3, 0));
|
||||
this->Get(2, 1) = (m.Get(2, 0) * o.Get(0, 1)) + (m.Get(2, 1) * o.Get(1, 1)) + (m.Get(2, 2) * o.Get(2, 1)) + (m.Get(2, 3) * o.Get(3, 1));
|
||||
this->Get(2, 2) = (m.Get(2, 0) * o.Get(0, 2)) + (m.Get(2, 1) * o.Get(1, 2)) + (m.Get(2, 2) * o.Get(2, 2)) + (m.Get(2, 3) * o.Get(3, 2));
|
||||
this->Get(2, 3) = (m.Get(2, 0) * o.Get(0, 3)) + (m.Get(2, 1) * o.Get(1, 3)) + (m.Get(2, 2) * o.Get(2, 3)) + (m.Get(2, 3) * o.Get(3, 3));
|
||||
|
||||
this->Get(MAT_INDEX(3, 0)) = (m.Get(MAT_INDEX(3, 0)) * o.Get(MAT_INDEX(0, 0))) + (m.Get(MAT_INDEX(3, 1)) * o.Get(MAT_INDEX(1, 0))) + (m.Get(MAT_INDEX(3, 2)) * o.Get(MAT_INDEX(2, 0))) + (m.Get(MAT_INDEX(3, 3)) * o.Get(MAT_INDEX(3, 0)));
|
||||
this->Get(MAT_INDEX(3, 1)) = (m.Get(MAT_INDEX(3, 0)) * o.Get(MAT_INDEX(0, 1))) + (m.Get(MAT_INDEX(3, 1)) * o.Get(MAT_INDEX(1, 1))) + (m.Get(MAT_INDEX(3, 2)) * o.Get(MAT_INDEX(2, 1))) + (m.Get(MAT_INDEX(3, 3)) * o.Get(MAT_INDEX(3, 1)));
|
||||
this->Get(MAT_INDEX(3, 2)) = (m.Get(MAT_INDEX(3, 0)) * o.Get(MAT_INDEX(0, 2))) + (m.Get(MAT_INDEX(3, 1)) * o.Get(MAT_INDEX(1, 2))) + (m.Get(MAT_INDEX(3, 2)) * o.Get(MAT_INDEX(2, 2))) + (m.Get(MAT_INDEX(3, 3)) * o.Get(MAT_INDEX(3, 2)));
|
||||
this->Get(MAT_INDEX(3, 3)) = (m.Get(MAT_INDEX(3, 0)) * o.Get(MAT_INDEX(0, 3))) + (m.Get(MAT_INDEX(3, 1)) * o.Get(MAT_INDEX(1, 3))) + (m.Get(MAT_INDEX(3, 2)) * o.Get(MAT_INDEX(2, 3))) + (m.Get(MAT_INDEX(3, 3)) * o.Get(MAT_INDEX(3, 3)));
|
||||
this->Get(3, 0) = (m.Get(3, 0) * o.Get(0, 0)) + (m.Get(3, 1) * o.Get(1, 0)) + (m.Get(3, 2) * o.Get(2, 0)) + (m.Get(3, 3) * o.Get(3, 0));
|
||||
this->Get(3, 1) = (m.Get(3, 0) * o.Get(0, 1)) + (m.Get(3, 1) * o.Get(1, 1)) + (m.Get(3, 2) * o.Get(2, 1)) + (m.Get(3, 3) * o.Get(3, 1));
|
||||
this->Get(3, 2) = (m.Get(3, 0) * o.Get(0, 2)) + (m.Get(3, 1) * o.Get(1, 2)) + (m.Get(3, 2) * o.Get(2, 2)) + (m.Get(3, 3) * o.Get(3, 2));
|
||||
this->Get(3, 3) = (m.Get(3, 0) * o.Get(0, 3)) + (m.Get(3, 1) * o.Get(1, 3)) + (m.Get(3, 2) * o.Get(2, 3)) + (m.Get(3, 3) * o.Get(3, 3));
|
||||
|
||||
return;
|
||||
}
|
||||
@ -837,3 +833,6 @@ namespace Leonetienne::GCrypt {
|
||||
template class Basic_Block<std::uint16_t>;
|
||||
}
|
||||
|
||||
|
||||
#undef MAT_INDEX
|
||||
|
||||
|
@ -302,8 +302,8 @@ TEST_CASE(__FILE__"/operator-&=", "[Block]") {
|
||||
// Tests that subtraction undoes addition, and vica versa
|
||||
TEST_CASE(__FILE__"/subtraction-undoes-addition", "[Block]") {
|
||||
// Setup
|
||||
const Block a = Key::Random();
|
||||
const Block b = Key::Random();
|
||||
const Block a = Key::FromPassword("Halleluja");
|
||||
const Block b = Key::FromPassword("Ananas");
|
||||
|
||||
// Exercise
|
||||
const Block a_plus_b = a + b;
|
||||
@ -441,7 +441,7 @@ TEST_CASE(__FILE__"/shift-rows-up", "[Block]") {
|
||||
// Tests that ShiftRowsUpInplace() does the exact same thing as ShiftRowsUp()
|
||||
TEST_CASE(__FILE__"/shift-rows-up-same-as-inplace", "[Block]") {
|
||||
// Setup
|
||||
Block a = Key::Random();
|
||||
Block a = Key::FromPassword("Halleluja");
|
||||
const Block initial_a = a;
|
||||
|
||||
// Exercise and verify
|
||||
@ -475,7 +475,7 @@ TEST_CASE(__FILE__"/shift-rows-down", "[Block]") {
|
||||
// Tests that ShiftRowsDownInplace() does the exact same thing as ShiftRowsDown()
|
||||
TEST_CASE(__FILE__"/shift-rows-down-same-as-inplace", "[Block]") {
|
||||
// Setup
|
||||
Block a = Key::Random();
|
||||
Block a = Key::FromPassword("Halleluja");
|
||||
const Block initial_a = a;
|
||||
|
||||
// Exercise and verify
|
||||
@ -509,7 +509,7 @@ TEST_CASE(__FILE__"/shift-columns-left", "[Block]") {
|
||||
// Tests that ShiftColumnsLeftInplace()() does the exact same thing as ShiftColumnsLeft()
|
||||
TEST_CASE(__FILE__"/shift-columns-left-same-as-inplace", "[Block]") {
|
||||
// Setup
|
||||
Block a = Key::Random();
|
||||
Block a = Key::FromPassword("Halleluja");
|
||||
const Block initial_a = a;
|
||||
|
||||
// Exercise and verify
|
||||
@ -543,7 +543,7 @@ TEST_CASE(__FILE__"/shift-columns-right", "[Block]") {
|
||||
// Tests that ShiftColumnsRightInplace()() does the exact same thing as ShiftColumnsRight()
|
||||
TEST_CASE(__FILE__"/shift-columns-right-same-as-inplace", "[Block]") {
|
||||
// Setup
|
||||
Block a = Key::Random();
|
||||
Block a = Key::FromPassword("Halleluja");
|
||||
const Block initial_a = a;
|
||||
|
||||
// Exercise and verify
|
||||
@ -576,7 +576,7 @@ TEST_CASE(__FILE__"/shift-cells-left", "[Block]") {
|
||||
// Tests that ShiftCellsLeftInplace()() does the exact same thing as ShiftCellsLeft()
|
||||
TEST_CASE(__FILE__"/shift-cells-left-same-as-inplace", "[Block]") {
|
||||
// Setup
|
||||
Block a = Key::Random();
|
||||
Block a = Key::FromPassword("Halleluja");
|
||||
const Block initial_a = a;
|
||||
|
||||
// Exercise and verify
|
||||
@ -609,7 +609,7 @@ TEST_CASE(__FILE__"/shift-cells-right", "[Block]") {
|
||||
// Tests that ShiftCellsRightInplace()() does the exact same thing as ShiftCellsRight()
|
||||
TEST_CASE(__FILE__"/shift-cells-right-same-as-inplace", "[Block]") {
|
||||
// Setup
|
||||
Block a = Key::Random();
|
||||
Block a = Key::FromPassword("Halleluja");
|
||||
const Block initial_a = a;
|
||||
|
||||
// Exercise and verify
|
||||
@ -620,7 +620,7 @@ TEST_CASE(__FILE__"/shift-cells-right-same-as-inplace", "[Block]") {
|
||||
// Tests that shifting down undoes shifting up, and vica versa
|
||||
TEST_CASE(__FILE__"/shift-down-undoes-shift-up", "[Block]") {
|
||||
// Setup
|
||||
Block a = Key::Random();
|
||||
Block a = Key::FromPassword("Halleluja");
|
||||
const Block initial_a = a;
|
||||
|
||||
// Exercise
|
||||
@ -634,7 +634,7 @@ TEST_CASE(__FILE__"/shift-down-undoes-shift-up", "[Block]") {
|
||||
// Tests that shifting left undoes shifting right, and vica versa
|
||||
TEST_CASE(__FILE__"/shift-left-undoes-shift-right", "[Block]") {
|
||||
// Setup
|
||||
Block a = Key::Random();
|
||||
Block a = Key::FromPassword("Halleluja");
|
||||
const Block initial_a = a;
|
||||
|
||||
// Exercise
|
||||
@ -648,7 +648,7 @@ TEST_CASE(__FILE__"/shift-left-undoes-shift-right", "[Block]") {
|
||||
// Tests that shifting cells left undoes shifting cells right, and vica versa
|
||||
TEST_CASE(__FILE__"/cellshift-left-undoes-cellshift-right", "[Block]") {
|
||||
// Setup
|
||||
Block a = Key::Random();
|
||||
Block a = Key::FromPassword("Halleluja");
|
||||
const Block initial_a = a;
|
||||
|
||||
// Exercise
|
||||
@ -662,7 +662,7 @@ TEST_CASE(__FILE__"/cellshift-left-undoes-cellshift-right", "[Block]") {
|
||||
// Tests that multiple, combined shifts and additions can be undone
|
||||
TEST_CASE(__FILE__"/multiple-combined-shifts-and-additions-can-be-undone", "[Block]") {
|
||||
// Setup
|
||||
Block a = Key::Random();
|
||||
Block a = Key::FromPassword("Halleluja");
|
||||
Block key = Key::FromPassword("Papaya");
|
||||
|
||||
const Block initial_a = a;
|
||||
@ -689,42 +689,23 @@ TEST_CASE(__FILE__"/multiple-combined-shifts-and-additions-can-be-undone", "[Blo
|
||||
|
||||
// Tests that the get-bit method works
|
||||
TEST_CASE(__FILE__"/get-bit", "[Block]") {
|
||||
for (std::size_t i = 0; i < 100; i++) {
|
||||
// Setup
|
||||
Block a = Key::Random();
|
||||
// Setup
|
||||
Block a = Key::FromPassword("Halleluja");
|
||||
|
||||
// Exercise
|
||||
std::stringstream ss;
|
||||
for (std::size_t i = 0; i < 512; i++) {
|
||||
ss << a.GetBit(i);
|
||||
}
|
||||
|
||||
// Verify
|
||||
REQUIRE(ss.str() == a.ToBinaryString());
|
||||
// Exercise
|
||||
std::stringstream ss;
|
||||
for (std::size_t i = 0; i < 512; i++) {
|
||||
ss << a.GetBit(i);
|
||||
}
|
||||
}
|
||||
|
||||
// Tests that the set-bit method works
|
||||
TEST_CASE(__FILE__"/set-bit", "[Block]") {
|
||||
for (std::size_t i = 0; i < 100; i++) {
|
||||
// Setup
|
||||
const std::string a_bits = Key::Random().ToBinaryString();
|
||||
|
||||
// Exercise
|
||||
Block a;
|
||||
for (std::size_t i = 0; i < 512; i++) {
|
||||
a.SetBit(i, a_bits[i] == '1');
|
||||
}
|
||||
|
||||
// Verify
|
||||
REQUIRE(a_bits == a.ToBinaryString());
|
||||
}
|
||||
// Verify
|
||||
REQUIRE(ss.str() == a.ToBinaryString());
|
||||
}
|
||||
|
||||
// Tests that the set-bit to-false method works
|
||||
TEST_CASE(__FILE__"/set-bit-to-false", "[Block]") {
|
||||
// Setup
|
||||
Block a = Key::Random();
|
||||
Block a = Key::FromPassword("Halleluja");
|
||||
|
||||
// Exercise
|
||||
a.SetBit(5, 0);
|
||||
@ -742,7 +723,7 @@ TEST_CASE(__FILE__"/set-bit-to-false", "[Block]") {
|
||||
// Tests that the set-bit to-true method works
|
||||
TEST_CASE(__FILE__"/set-bit-to-true", "[Block]") {
|
||||
// Setup
|
||||
Block a = Key::Random();
|
||||
Block a = Key::FromPassword("Halleluja");
|
||||
|
||||
// Exercise
|
||||
a.SetBit(5, 1);
|
||||
@ -760,7 +741,7 @@ TEST_CASE(__FILE__"/set-bit-to-true", "[Block]") {
|
||||
// Tests that the flip-bit method works
|
||||
TEST_CASE(__FILE__"/flip-bit", "[Block]") {
|
||||
// Setup
|
||||
Block a = Key::Random();
|
||||
Block a = Key::FromPassword("Halleluja");
|
||||
|
||||
std::string compare = a.ToBinaryString();
|
||||
compare[5] = compare[5] == '1' ? '0' : '1';
|
||||
@ -882,7 +863,7 @@ TEST_CASE(__FILE__"/bitshift-right-inplace", "[Block]") {
|
||||
TEST_CASE(__FILE__"/bitshifting-undoes-itself", "[Block]") {
|
||||
|
||||
// Setup
|
||||
Block a = Key::Random();
|
||||
Block a = Key::FromPassword("Halleluja");
|
||||
|
||||
const Block initial_a = a;
|
||||
|
||||
|
60
readme.md
60
readme.md
@ -1,12 +1,7 @@
|
||||
[](https://drone.leonetienne.de/leonetienne/GCrypt)
|
||||
|
||||
# GCrypt
|
||||
# GCrypt
|
||||
*(GhettoCrypt), because frankly I have no idea what the fuck I'm doing*
|
||||
<sub>*Please don't use this for anything critical*</sub>
|
||||
|
||||
## [Documentation](https://gcrypt.rtfm.leonetienne.de/)
|
||||
|
||||
|
||||
## 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).
|
||||
@ -14,15 +9,15 @@ This block cipher employs a few modes of operation. Read more about them [here](
|
||||
## 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
|
||||
* But the syntax is pythonlike easy🙇
|
||||
* 512-bit keys
|
||||
|
||||
It's pretty ghetto, you know?
|
||||
|
||||
## What are the actual advantages?
|
||||
* It's two files to import into your project
|
||||
* No dependencies
|
||||
* 1 Line to use
|
||||
* 100% cross plattform
|
||||
|
||||
@ -32,7 +27,7 @@ It's pretty ghetto, you know?
|
||||
|
||||
### 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.
|
||||
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!"*
|
||||
@ -107,8 +102,6 @@ This way you can cipher on bitlevel. Examples on how to do this are in [GWrapper
|
||||
This way you could, for example, decrypt an ecrypted file directly into memory.
|
||||
Without saying, this is more advanced and not as-easy as the methods supplied in the wrapper.
|
||||
|
||||
Want more documentation? See the [doxygen page](https://gcrypt.rtfm.leonetienne.de/).
|
||||
|
||||
---
|
||||
|
||||
## The deets 🍝
|
||||
@ -117,26 +110,25 @@ Want more documentation? See the [doxygen page](https://gcrypt.rtfm.leonetienne.
|
||||
* [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.
|
||||
* [I-don't-even-know-any-more] Inspired by Rijndael, it does some monkey tricks with reversible matrix-mutators after each feistel round.
|
||||
|
||||
### Password to key
|
||||
How does GCrypt transform a password to a key?..
|
||||
Well, it uses the included hash function [GHash](https://gitea.leonetienne.de/leonetienne/GCrypt/src/branch/master/GCryptLib/include/GCrypt/GHash.h).
|
||||
Well, it uses the included hash function [GHash](https://gitea.leonetienne.de/leonetienne/GCrypt/src/branch/feature/relaunch/GCryptLib/include/GCrypt/GHash.h).
|
||||
|
||||
### Hashing with GHash
|
||||
GHash is a streaming hash function based on the GCipher.
|
||||
For all intents and purposes, it does the following:
|
||||
You have a *Block b*, which is initialized with a static random distribution.
|
||||
Once you give the GHash instance a data block to digest, it will use the GCipher to encrypt it, with itself as a key, and xor that onto *b*.
|
||||
(*b<sub>i</sub> = b<sub>i-1</sub> ⊕ E(key=b<sub>new</sub>, data=b<sub>new</sub>)*)
|
||||
(*b<sub>i</sub> = b<sub>i-1</sub> ⊕ E(key=b, data=b)*)
|
||||
|
||||
The lastest *b* represents the current result of the hash function.
|
||||
|
||||
GHash also supports a do-it-all wrapper method that takes a vector of blocks, and returns a hashsum for it.
|
||||
This wrapper function adds an additional block including the length of the input, if provided. This wrapper function is used to transform Passwords to Keys.
|
||||
GHash also supports a do-it-all wrapper method that takes a Flexblock (A block of arbitrary length), and returns a hashsum for it.
|
||||
This wrapper function adds an additional block including the length of the input. This wrapper function is used to transform Passwords to Keys.
|
||||
|
||||
### GPrng...?
|
||||
Whilst we're at it, why not implement a pseudo-random number generator based on GHash aswell. So here it is, [GPrng](https://gitea.leonetienne.de/leonetienne/GCrypt/src/branch/master/GCryptLib/include/GCrypt/GPrng.h).
|
||||
Whilst we're at it, why not implement a pseudo-random number generator based on GHash aswell. So here it is, [GPrng](https://gitea.leonetienne.de/leonetienne/GCrypt/src/branch/feature/relaunch/GCryptLib/include/GCrypt/GPrng.h).
|
||||
GPrng is really nothing special. I just wanted to implement it, mainly to visualize the GCiphers entropy.
|
||||
|
||||
GPrng basically does the following: It creates a GHash instance, which initially digests the prng's seed. This produces a hash result, which is one block in size.
|
||||
@ -148,30 +140,30 @@ future output.
|
||||
#### Single-block diffusion
|
||||
`"Hello :3"` in binary, and it's ciphertext:
|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||
Now, let's flip a single bit in the input:
|
||||
|
||||
One bit flipped, and again the corresponding ciphertext:
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||
Let's gif them together, to better see the difference:
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||
As shown, flipping even a single bit, affects the entire ciphertext.
|
||||
|
||||
#### What about input longer than a single block?
|
||||
|
||||
Input, and ciphertext:
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||
Notice how the ciphertext doesn't change until the block containing the bitflip is reached? This is a limitation of cipher block chaining.
|
||||
|
||||
@ -179,11 +171,11 @@ Notice how the ciphertext doesn't change until the block containing the bitflip
|
||||
How non-transparent is the cipher with extreme inputs? Even with a super problematic key?:
|
||||
|
||||
Input, key, and ciphertext:
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||
Notice how even cleartexts that are completely uniform, with a key that is almost just zeores, will still produce ambiguous ciphertexts.
|
||||
|
||||
@ -191,18 +183,18 @@ Notice how even cleartexts that are completely uniform, with a key that is almos
|
||||
Check it out, here are the distributions of a few different getter-methods, some in black/white, some in grayscale, some in color.
|
||||
|
||||
Blackwhite - GetBit(), Grayscale - GetRandom<T>(), and Grayscale - operator():
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||
Color - GetRandom<T>(), Color - operator(), and Color - GetBlock():
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||
## Noteworthy:
|
||||
* This is no fixed algorithm. Newer versions may very well be unable to decrypt ciphertexts encrypted with earlier versions.
|
||||
|
Loading…
x
Reference in New Issue
Block a user