Author SHA1 Message Date
Leonetienne 08f6e7d907 Add parameter to control progress report interval 2022-06-01 03:30:18 +02:00
Leonetienne e8d81af6f2 Implement progress output 2022-06-01 03:29:05 +02:00
Leonetienne fb1e6a9e8c Update CLI readme 2022-06-01 02:49:49 +02:00
Leonetienne 855ecaaa2f Fix docs 2022-06-01 02:34:16 +02:00
Leonetienne 136e03e65e Doxygen now using makefile 2022-06-01 02:34:11 +02:00
Leonetienne 834b799849 Fix outdated information in readme 2022-06-01 02:29:20 +02:00
Leonetienne b87ba395e3 Docs 2022-06-01 02:23:51 +02:00
Leonetienne 70111f906c Bump version 2022-06-01 02:10:08 +02:00
Leonetienne ffea2bfb5b Added module for hashing 2022-06-01 02:09:49 +02:00
Leonetienne bf8a6454ae Implemented low space-complexity stream decoding for all ioformats 2022-06-01 01:53:52 +02:00
Leonetienne 4c8c45ad04 Fix wrong minlen for base ugh 2022-06-01 01:49:10 +02:00
Leonetienne 0917e9c6cb Fix wrong minlen for base uwu 2022-05-31 22:19:01 +02:00
Leonetienne a93b3b3fe5 Sophisticated and bug-fixed DataOutput/InputLayer, and added ModuleDecryption 2022-05-31 21:40:13 +02:00
Leonetienne d9fb90a01e Now by-default prepending a newline to stdout 2022-05-31 18:26:02 +02:00
Leonetienne ba37b4325c Integrated DataOutputLayer to ModuleGenerateKey 2022-05-31 18:19:12 +02:00
Leonetienne 0ab87de23c More streamlined handling of io bases 2022-05-31 18:17:29 +02:00
Leonetienne fd75678ea3 Added encryption module, and data output layer 2022-05-31 17:35:05 +02:00
Leonetienne a00b8cc310 Fix Indentation 2022-05-31 17:07:45 +02:00
Leonetienne f979b9c187 Add additional methods to data ingestion layer 2022-05-31 15:32:17 +02:00
Leonetienne 6a14b7b428 Forbid instanciation of static classes 2022-05-31 14:28:17 +02:00
Leonetienne 2f6df42696 Implement relevant methods for DataIngestionLayer 2022-05-31 14:25:23 +02:00
Leonetienne 3823eb6cc7 Fix typo in comment 2022-05-31 10:44:05 +02:00
Leonetienne 87987f6fe2 Implement unified istream for ingestion layer 2022-05-27 18:26:48 +02:00
Leonetienne 5df625e610 Rename cmake cli target name 2022-05-27 17:21:30 +02:00
Leonetienne b9d81d1425 Change module GenerateKeyfile to more versatile GenerateKey, which doesnt have to output to a file 2022-05-27 17:21:10 +02:00
Leonetienne 93be4d9cdc Implement GenerateKeyfile module 2022-05-27 17:04:16 +02:00
Leonetienne 191b17c631 Fix Key::WriteToFile method being not const qualified 2022-05-27 17:04:05 +02:00
Leonetienne 5365233b43 A bit of cleanup 2022-05-27 16:50:18 +02:00
Leonetienne b0d0f831d9 Removed bunch of garbage from main.cpp 2022-05-27 16:14:24 +02:00
Leonetienne 186fea1383 More tests on data formatter 2022-05-27 16:08:24 +02:00
Leonetienne cf22f8c569 Added tests for recoding single blocks to all formats 2022-05-27 15:56:28 +02:00
Leonetienne 2fa67b6860 Renamed method, and added first test to cli 2022-05-27 15:34:16 +02:00
Leonetienne 612157bcac Added test project 2022-05-27 15:27:33 +02:00
Leonetienne b888585f75 A bit of error handling and better comments 2022-05-27 14:47:26 +02:00
Leonetienne 2eb0754b4e Remove unused code 2022-05-27 03:34:02 +02:00
Leonetienne 0a248b6d86 Fix multiple definition issue 2022-05-27 03:30:11 +02:00
Leonetienne 0e47b11a2c Proper include guard 2022-05-27 03:29:51 +02:00
Leonetienne 6834ea4ad8 Move blocklenght lookup table to Bases.h 2022-05-27 03:27:43 +02:00
Leonetienne 407c0ad5bc Better comment. 2022-05-27 03:01:47 +02:00
Leonetienne 2ecf0cc427 Added multiblocks methods to data formatter 2022-05-27 03:00:34 +02:00
Leonetienne 8e04e91e88 Got block conversions working... 2022-05-27 02:13:05 +02:00
Leonetienne f6d646da55 Implemented to-block methods of dataformatter 2022-05-26 23:22:04 +02:00
Leonetienne 6ac775105b Implement output formatting module 2022-05-26 22:30:59 +02:00
Leonetienne fad87e9944 Add exceptoins 2022-05-26 22:06:04 +02:00
Leonetienne dddc2d16f6 Added module PrepareKey 2022-05-26 21:56:15 +02:00
Leonetienne 8b9221e2e0 Add Configuration class to intelligently decide default settings 2022-05-26 21:32:55 +02:00
Leonetienne f28e510dba Adjust cli parameter definitions 2022-05-26 20:19:15 +02:00
Leonetienne 0f46ed7115 GCryptLib version bump 2022-05-26 19:59:16 +02:00
Leonetienne 75c4b0a0d9 More streamlined naming scheme for digestion method of ghash 2022-05-26 19:57:14 +02:00
Leonetienne f246e3a5ef Fix dangling hint 2022-05-26 19:34:58 +02:00
Leonetienne 2194ad1ce3 Fix apple linker problem 2022-05-26 19:25:40 +02:00
Leonetienne 876129f05f Added how2compile to readme 2022-05-26 19:05:35 +02:00
Leonetienne 849d34613e Add new visualizations 2022-05-26 18:59:59 +02:00
Leonetienne cad96a19a2 Fix bad filename in visualization 2022-05-26 18:59:05 +02:00
Leonetienne c0418766d9 Tidied up example/static test executables 2022-05-26 18:24:44 +02:00
Leonetienne e7c1e17e2c Got rid of flexblocks 2022-05-26 15:47:24 +02:00
Leonetienne 143ec19bf3 Many methods now using vectors of blocks instead of flexblocks 2022-05-26 15:04:39 +02:00
Leonetienne 800140bafa Added a method to GPrng to get a random uint32, which is about twice as fast as GetRandom<uint32_t> 2022-05-26 12:52:04 +02:00
Leonetienne e9377699f2 Made GPrng::GetBlock() faster by a factor of 100 2022-05-26 12:23:27 +02:00
Leonetienne 660ab5e999 Unstupided mathematical expression 2022-05-26 04:40:23 +02:00
Leonetienne c3ff7a1326 Fix markup in artifacts 2022-05-26 04:25:02 +02:00
Leonetienne 8cf8ad2628 Add artifact directory 2022-05-26 04:23:32 +02:00
Leonetienne 81a9570673 Implement direct file i/o to- and from blocks. 2022-05-26 04:22:42 +02:00
Leonetienne 101a1e0fd6 Add additional jumbling-up in feistel rounds 2022-05-26 02:44:22 +02:00
Leonetienne bc3dae96a3 Implement new sbox, reduction, and expansion function 2022-05-26 02:30:16 +02:00
Leonetienne 8ddd9d6bfb Replaced halfblock with instanciation of Basic_Block 2022-05-26 00:55:24 +02:00
Leonetienne 1f913b3a54 Typo in comment 2022-05-25 16:51:38 +02:00
Leonetienne f7d8093668 Templatified block class 2022-05-25 16:38:16 +02:00
Leonetienne 21cbd80488 Merge origin feature/relaunch into feature/relaunch 2022-05-25 14:58:40 +02:00
Leonetienne 3630243d8d Fix macos compile issue 2022-05-25 14:57:40 +02:00
Leonetienne edbf36eb6d Cipher now using new block class 2022-05-25 13:05:25 +02:00
Leonetienne b5369a3c32 Added bitshift methods to block class 2022-05-25 12:54:26 +02:00
Leonetienne 9a9cd05bed Add SetBit, and FlipBit methods to block 2022-05-24 23:51:17 +02:00
Leonetienne e552e1a6f8 Add GetBit() method to Block 2022-05-24 23:18:39 +02:00
Leonetienne db0add6e6e Implemented remaining operands for block class 2022-05-24 22:09:06 +02:00
Leonetienne 83854e42cb Fix blanklines in block.cpp 2022-05-24 01:07:00 +02:00
Leonetienne fa47a48dae Add comment 2022-05-24 01:05:45 +02:00
Leonetienne 939df4731b [Progress:] Completely re-done Block class to not use bitsets, and provide custom operators. 2022-05-24 01:02:06 +02:00
Leonetienne ed45b69342 Experimentally implement matrix-mult 2022-05-23 22:42:14 +02:00
Leonetienne 3819fbe693 Typo readme 2022-05-22 23:27:23 +02:00
Leonetienne 2815be238b Merge branch 'feature/relaunch' of gitea.leonetienne.de:leonetienne/GCrypt into feature/relaunch 2022-05-22 23:23:31 +02:00
Leonetienne 7cf55414b5 Wording readme 2022-05-22 23:22:54 +02:00
Leonetienne b873c13bf2 Fix typo in readme 2022-05-22 23:16:57 +02:00
Leonetienne 12b0f6b031 Fix typo in readme 2022-05-22 22:39:25 +02:00
Leonetienne 3978bb6b18 Fix invalid html in readme 2022-05-22 21:25:53 +02:00
Leonetienne 8c7506297f Added another visualization to readme 2022-05-22 21:22:02 +02:00
Leon Etienne 17dece8daf Put images in readme next to each other 2022-05-22 20:55:04 +02:00
Leonetienne 1e479986fc Readme and visualizations 2022-05-22 20:40:56 +02:00
Leonetienne 5677d94e6a Improved security 2022-05-22 20:13:41 +02:00
Leonetienne 19660fc696 Add method to load and save keyfiles 2022-05-22 17:54:26 +02:00
Leonetienne 88cb36fd7b Fix include guard 2022-05-22 17:54:04 +02:00
Leonetienne cd119f21bb Indentation 2022-05-22 17:32:54 +02:00
Leonetienne 91819c9723 Bump gcryptlib version 2022-05-22 17:30:15 +02:00
Leonetienne cb6c50b684 Now using actual include guards 2022-05-22 17:29:38 +02:00
Leonetienne a3c04b957f Implemented a Key::Random() method 2022-05-22 17:24:56 +02:00
Leonetienne 04c67436c4 Implemented GPrng pnrg 2022-05-22 16:54:40 +02:00
Leonetienne bedfc91e04 GHash now uses a full-size key for the cipher 2022-05-22 14:30:24 +02:00
Leonetienne fe6ec11672 Adjusted tests 2022-05-22 14:29:21 +02:00
Leonetienne 967eba2f03 Cmake make colored output 2022-05-22 14:21:21 +02:00
Leonetienne b0e0c0cd99 Moved utility functions to cpp file 2022-05-22 14:13:10 +02:00
Leonetienne fedb30bb43 Added padding direction option for Util::StringToBitblock 2022-05-22 13:54:03 +02:00
Leonetienne 9fdc642bd6 Implemented a key class 2022-05-22 13:45:40 +02:00
Leonetienne bb76cbb2d7 Renamed class GCryptWrapper to GWrapper 2022-05-22 13:07:40 +02:00
Leonetienne cf784ca8ac Renamed method DigestFlexblock to CipherFlexblock, and made it public 2022-05-22 13:04:20 +02:00
Leonetienne 734324ec10 Renamed class Hasher to GHash 2022-05-22 12:55:39 +02:00
Leonetienne 4e2f99c28e Renamed class Cipher to GCipher 2022-05-22 12:51:58 +02:00
Leonetienne 1cc01a840d Cmake specify color output as always 2022-05-22 12:51:29 +02:00
Leonetienne 29f0efbba5 Fix warning 2022-05-22 12:31:48 +02:00
Leonetienne 201917d385 Warnings are now treated as errors 2022-05-22 12:31:33 +02:00
Leonetienne 6dce12b6ee Added class for hashing, that is now used for password to key transformation 2022-05-22 00:23:10 +02:00
Leonetienne f3b6dc155c Implemented digestion (feeding one block at a time) 2022-05-21 20:41:09 +02:00
Leonetienne 71de8270d8 Added warning to readme 2022-05-21 20:40:44 +02:00
Leon Etienne baf3190665 Fix typo in code samples in readme 2022-05-17 14:16:17 +02:00
Leonetienne 4015ee5dda Switch to https-based git submodules 2022-05-17 01:31:26 +02:00
Leonetienne 9faea67af3 Version bump gcryptlib 2022-05-17 01:18:00 +02:00
Leonetienne 7a61d2e6c3 Step 2: fix broken submodule config 2022-05-17 01:17:48 +02:00
Leonetienne e416fe05cb Step 1: fix broken submodule config 2022-05-17 01:16:25 +02:00
Leonetienne a8230086d3 Streamlined workflow of GCryptCLI 2022-05-17 01:13:42 +02:00
Leonetienne 845c77a985 unbloated readme 2022-05-16 23:49:08 +02:00
Leonetienne e8305399ea Fix dangling var in cmakelist of gcryptlib 2022-05-16 23:47:36 +02:00
Leonetienne 5fb38e1ed3 Update readme 2022-05-16 23:37:14 +02:00
Leonetienne f75a41d8dc Translated encryption/decryption consistency tests to catch2 2022-05-16 23:26:29 +02:00
Leonetienne 14e1fbe32c Translated password2key transformation collision resistance tests to catch2 2022-05-16 23:03:55 +02:00
Leonetienne b998a51e11 Renamed ghettocryptwrapper class to gcryptwrapper 2022-05-16 22:50:52 +02:00
Leonetienne 13a7abd82d Translated gcrypt wrapper tests to catch2 2022-05-16 22:47:41 +02:00
Leonetienne 7fe9dcc6dc GCryptLib: Fix include paths 2022-05-16 22:35:28 +02:00
Leonetienne 9432325b4a Fix directory structure for include dir 2022-05-16 22:22:42 +02:00
Leonetienne 7c556e5b3d Doxygen adjustment, and better directory name for GCryptLib 2022-05-16 22:19:20 +02:00
Leonetienne acf9dea387 Gcryptlib: new brace style, and moved to Leonetienne namespace 2022-05-16 22:15:34 +02:00
Leonetienne c551f5fa64 retabbed gcryptlib 2022-05-16 22:01:52 +02:00
Leonetienne ae276e49af New directory structure for libghettocrypt 2022-05-16 21:43:22 +02:00
Leon Etienne 9772c5fcf8 Added comment 2022-05-16 00:21:01 +02:00
Leonetienne a29e199125 Remove bunch of microsoft crap 2022-05-13 22:28:01 +02:00
Leon Etienne b8d6be8f4c Typos 2022-05-13 22:12:59 +02:00
Leon Etienne ec3dd1ab07 Rename header in cli/readme 2022-05-13 12:46:56 +02:00
Leon Etienne 518fc054ed Update readme.md 2022-05-13 11:58:34 +02:00
Leon Etienne 5afd772a84 Update documentation for PasswordToKey function 2022-05-13 11:37:08 +02:00
Leon Etienne 754db08e7d Update 'readme.md' 2022-04-13 18:56:56 +02:00
Leonetienne 17ba2a373e Rename cli cmake target 2022-03-18 17:10:32 +01:00
Leon Etienne c7b13ca7ab Fix filename 2022-03-16 22:45:56 +01:00
Leonetienne 698647f7af readme 2022-03-16 01:42:19 +01:00
Leonetienne 4a40dfbba4 Update readme 2022-03-16 01:37:53 +01:00
Leonetienne 117798d0fb Implemented hashsum mode 2022-03-16 01:31:28 +01:00
Leonetienne cdad33c738 Updated hazelnupp 2022-03-13 19:48:29 +01:00
Leonetienne 6e13a5196a fix broken base uwu 2022-03-13 19:36:29 +01:00
Leonetienne 6f08848aed more digits for uwu base 2022-03-13 19:23:13 +01:00
Leonetienne 3359fdab17 Fix build command 2022-03-13 19:15:43 +01:00
Leonetienne ea0778e203 Fix build command 2022-03-13 19:15:29 +01:00
Leonetienne 29117aff0c Updated installation instructions, and removed useless non-crossplatform binary 2022-03-13 19:13:54 +01:00
Leonetienne f250f77557 readme 2022-03-13 19:08:09 +01:00
Leonetienne 09e6dff9d3 more uwu digits and readme 2022-03-13 19:06:14 +01:00
Leonetienne c9953a1078 readme 2022-03-13 18:56:55 +01:00
Leonetienne 829de7c1f4 More uwu digits, and included warning in readme 2022-03-13 18:55:56 +01:00
Leonetienne bfe7152f1f readme 2022-03-13 18:26:24 +01:00
Leonetienne a64c0541ed readme 2022-03-13 18:25:20 +01:00
Leonetienne aa860bad76 readme 2022-03-13 18:24:11 +01:00
Leonetienne 6eae039c37 readme 2022-03-13 18:23:16 +01:00
Leonetienne 5722110bce Merge branch 'master' of github.com:Leonetienne/GhettoCrypt 2022-03-13 18:22:30 +01:00
16 changed files with 170 additions and 275 deletions
-56
View File
@@ -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
+5 -7
View File
@@ -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

-24
View File
@@ -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 -1
View File
@@ -1,7 +1,7 @@
#ifndef GCRYPTCLI_VERSION_H
#define GCRYPTCLI_VERSION_H
#define GCRYPTCLI_VERSION 0.12512
#define GCRYPTCLI_VERSION 0.1251
#endif
+47 -46
View File
@@ -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
+8 -8
View File
@@ -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;
+6 -4
View File
@@ -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;
}
+3 -3
View File
@@ -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 -1
View File
@@ -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
+2 -2
View File
@@ -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
@@ -44,7 +44,7 @@ PROJECT_NUMBER =
# for a project that appears at the top of each page and should give viewer a
# quick idea about the purpose of the project. Keep the description short.
PROJECT_BRIEF = "An educational cryptography library (GCrypt / GNU Crypt)"
PROJECT_BRIEF = "Ghetto (but also super easy) cryptography!"
# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
# in the documentation. The maximum height of the logo should not exceed 55
+1 -1
View File
@@ -4,7 +4,7 @@
#include <cstdint>
#include <array>
#include <string>
#include <iosfwd>
#include <ostream>
#include <bitset>
namespace Leonetienne::GCrypt {
+36 -37
View File
@@ -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
+17 -36
View File
@@ -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,9 +689,8 @@ 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();
Block a = Key::FromPassword("Halleluja");
// Exercise
std::stringstream ss;
@@ -701,30 +700,12 @@ TEST_CASE(__FILE__"/get-bit", "[Block]") {
// Verify
REQUIRE(ss.str() == a.ToBinaryString());
}
}
// 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());
}
}
// 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;
+36 -41
View File
@@ -1,26 +1,23 @@
[![Build Status](https://drone.leonetienne.de/api/badges/leonetienne/GCrypt/status.svg)](https://drone.leonetienne.de/leonetienne/GCrypt)
# GCrypt
*GCrypt (GNU Crypt) — an educational project for learning how block ciphers work*
# GCrypt
*(GhettoCrypt), because frankly I have no idea what the fuck I'm doing*
<sub>*Please don't use this for anything critical*</sub>
> **Note:** This project is unrelated to [libgcrypt](https://www.gnupg.org/software/libgcrypt/index.html), the cryptographic library used by GnuPG. Any naming similarity is coincidental — "GCrypt" here just stands for "GNU Crypt".
## [Documentation](https://gcrypt.rtfm.leonetienne.de/)
## What is this?
## 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
* Very easy to use
* 512-bit keys
* Not performance-optimized, and not audited for security
* 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🙇
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
@@ -28,8 +25,9 @@ This block cipher employs a few modes of operation. Read more about them [here](
* For data obfuscation
* If your only other option would be no encryption at all
### Seriously, don't use this for anything critical. Homebrew ciphers are rarely secure — this one included.
Even assuming it's a good cipher, its implementation leaves a lot to be desired in terms of being cryptographically secure.
### 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!"*
@@ -104,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 🍝
@@ -114,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> &#8853; E(key=b<sub>new</sub>, data=b<sub>new</sub>)*)
(*b<sub>i</sub> = b<sub>i-1</sub> &#8853; 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.
@@ -145,30 +140,30 @@ future output.
#### Single-block diffusion
`"Hello :3"` in binary, and it's ciphertext:
![Hello :3 in binary](https://gitea.leonetienne.de/leonetienne/GCrypt/raw/branch/master/GCryptLib/visualizations/visualize-singleblock-diffusion-input.bmp.png)
!["Hello :3" in binary](https://gitea.leonetienne.de/leonetienne/GCrypt/raw/branch/feature/relaunch/GCryptLib/visualizations/visualize-singleblock-diffusion-input.bmp.png)
&nbsp;&nbsp;&nbsp;
![Ciphertext 1](https://gitea.leonetienne.de/leonetienne/GCrypt/raw/branch/master/GCryptLib/visualizations/visualize-singleblock-diffusion-output.bmp.png)
![Ciphertext 1](https://gitea.leonetienne.de/leonetienne/GCrypt/raw/branch/feature/relaunch/GCryptLib/visualizations/visualize-singleblock-diffusion-output.bmp.png)
Now, let's flip a single bit in the input:
One bit flipped, and again the corresponding ciphertext:
![One bit flipped](https://gitea.leonetienne.de/leonetienne/GCrypt/raw/branch/master/GCryptLib/visualizations/visualize-singleblock-diffusion-input-flip.bmp.png)
![One bit flipped](https://gitea.leonetienne.de/leonetienne/GCrypt/raw/branch/feature/relaunch/GCryptLib/visualizations/visualize-singleblock-diffusion-input-flip.bmp.png)
&nbsp;&nbsp;&nbsp;
![Ciphertext for flipped bit](https://gitea.leonetienne.de/leonetienne/GCrypt/raw/branch/master/GCryptLib/visualizations/visualize-singleblock-diffusion-output-flip.bmp.png)
![Ciphertext for flipped bit](https://gitea.leonetienne.de/leonetienne/GCrypt/raw/branch/feature/relaunch/GCryptLib/visualizations/visualize-singleblock-diffusion-output-flip.bmp.png)
Let's gif them together, to better see the difference:
![Input](https://gitea.leonetienne.de/leonetienne/GCrypt/raw/branch/master/GCryptLib/visualizations/visualize-singleblock-diffusion-input.gif)
![Input](https://gitea.leonetienne.de/leonetienne/GCrypt/raw/branch/feature/relaunch/GCryptLib/visualizations/visualize-singleblock-diffusion-input.gif)
&nbsp;&nbsp;&nbsp;
![Ciphertext](https://gitea.leonetienne.de/leonetienne/GCrypt/raw/branch/master/GCryptLib/visualizations/visualize-singleblock-diffusion-output.gif)
![Ciphertext](https://gitea.leonetienne.de/leonetienne/GCrypt/raw/branch/feature/relaunch/GCryptLib/visualizations/visualize-singleblock-diffusion-output.gif)
As shown, flipping even a single bit, affects the entire ciphertext.
#### What about input longer than a single block?
Input, and ciphertext:
![Input](https://gitea.leonetienne.de/leonetienne/GCrypt/raw/branch/master/GCryptLib/visualizations/visualize-multiblock-diffusion-input.gif)
![Input](https://gitea.leonetienne.de/leonetienne/GCrypt/raw/branch/feature/relaunch/GCryptLib/visualizations/visualize-multiblock-diffusion-input.gif)
&nbsp;&nbsp;&nbsp;
![Ciphertext](https://gitea.leonetienne.de/leonetienne/GCrypt/raw/branch/master/GCryptLib/visualizations/visualize-multiblock-diffusion-output.gif)
![Ciphertext](https://gitea.leonetienne.de/leonetienne/GCrypt/raw/branch/feature/relaunch/GCryptLib/visualizations/visualize-multiblock-diffusion-output.gif)
Notice how the ciphertext doesn't change until the block containing the bitflip is reached? This is a limitation of cipher block chaining.
@@ -176,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:
![Input](https://gitea.leonetienne.de/leonetienne/GCrypt/raw/branch/master/GCryptLib/visualizations/visualize-extreme-input-diffusion-input.gif)
![Input](https://gitea.leonetienne.de/leonetienne/GCrypt/raw/branch/feature/relaunch/GCryptLib/visualizations/visualize-extreme-input-diffusion-input.gif)
&nbsp;&nbsp;&nbsp;
![Key](https://gitea.leonetienne.de/leonetienne/GCrypt/raw/branch/master/GCryptLib/visualizations/visualize-extreme-input-diffusion-key.bmp.png)
![Key](https://gitea.leonetienne.de/leonetienne/GCrypt/raw/branch/feature/relaunch/GCryptLib/visualizations/visualize-extreme-input-diffusion-key.bmp.png)
&nbsp;&nbsp;&nbsp;
![Ciphertext](https://gitea.leonetienne.de/leonetienne/GCrypt/raw/branch/master/GCryptLib/visualizations/visualize-extreme-input-diffusion-output.gif)
![Ciphertext](https://gitea.leonetienne.de/leonetienne/GCrypt/raw/branch/feature/relaunch/GCryptLib/visualizations/visualize-extreme-input-diffusion-output.gif)
Notice how even cleartexts that are completely uniform, with a key that is almost just zeores, will still produce ambiguous ciphertexts.
@@ -188,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():
![Input](https://gitea.leonetienne.de/leonetienne/GCrypt/raw/branch/master/GCryptLib/visualizations/visualize-prng-distribution-blackwhite.bmp.png)
![Input](https://gitea.leonetienne.de/leonetienne/GCrypt/raw/branch/feature/relaunch/GCryptLib/visualizations/visualize-prng-distribution-blackwhite.bmp.png)
&nbsp;&nbsp;&nbsp;
![Key](https://gitea.leonetienne.de/leonetienne/GCrypt/raw/branch/master/GCryptLib/visualizations/visualize-prng-distribution-getrandom-grayscale.bmp.png)
![Key](https://gitea.leonetienne.de/leonetienne/GCrypt/raw/branch/feature/relaunch/GCryptLib/visualizations/visualize-prng-distribution-getrandom-grayscale.bmp.png)
&nbsp;&nbsp;&nbsp;
![Ciphertext](https://gitea.leonetienne.de/leonetienne/GCrypt/raw/branch/master/GCryptLib/visualizations/visualize-prng-distribution-operator-grayscale.bmp.png)
![Ciphertext](https://gitea.leonetienne.de/leonetienne/GCrypt/raw/branch/feature/relaunch/GCryptLib/visualizations/visualize-prng-distribution-operator-grayscale.bmp.png)
Color - GetRandom<T>(), Color - operator(), and Color - GetBlock():
![Input](https://gitea.leonetienne.de/leonetienne/GCrypt/raw/branch/master/GCryptLib/visualizations/visualize-prng-distribution-getrandom-color.bmp.png)
![Input](https://gitea.leonetienne.de/leonetienne/GCrypt/raw/branch/feature/relaunch/GCryptLib/visualizations/visualize-prng-distribution-getrandom-color.bmp.png)
&nbsp;&nbsp;&nbsp;
![Key](https://gitea.leonetienne.de/leonetienne/GCrypt/raw/branch/master/GCryptLib/visualizations/visualize-prng-distribution-operator-color.bmp.png)
![Key](https://gitea.leonetienne.de/leonetienne/GCrypt/raw/branch/feature/relaunch/GCryptLib/visualizations/visualize-prng-distribution-operator-color.bmp.png)
&nbsp;&nbsp;&nbsp;
![Ciphertext](https://gitea.leonetienne.de/leonetienne/GCrypt/raw/branch/master/GCryptLib/visualizations/visualize-prng-distribution-getblock-color.bmp.png)
![Ciphertext](https://gitea.leonetienne.de/leonetienne/GCrypt/raw/branch/feature/relaunch/GCryptLib/visualizations/visualize-prng-distribution-getblock-color.bmp.png)
## Noteworthy:
* This is no fixed algorithm. Newer versions may very well be unable to decrypt ciphertexts encrypted with earlier versions.