OSDN Git Service

Updated README file.
authorLoRd_MuldeR <mulder2@gmx.de>
Sun, 14 Mar 2021 21:36:38 +0000 (22:36 +0100)
committerLoRd_MuldeR <mulder2@gmx.de>
Sat, 20 Mar 2021 20:19:04 +0000 (21:19 +0100)
README.md

index 35fb421..1a8a0d7 100644 (file)
--- a/README.md
+++ b/README.md
@@ -94,6 +94,24 @@ Examples on how to use the SlunkCrypt command-line application:
        cmp --silent plaintext.txt plaintext.out && echo "files are the same"
 
 
+Encryption algorithm
+====================
+
+The SlunkCrypt algorithm is based on concepts of the well-known [**Enigma**](https://en.wikipedia.org/wiki/Enigma_machine) machine, but with various improvements:
+
+- The original Enigma machine had only *three* rotors (spinning wheels), plus a static "reflector" wheel. In SlunkCrypt, we uses **256** simulated rotors.
+
+- The original Enigma machine supported only 26 distinct symbols, i.e. the letters `A` to `Z`. In SlunkCrypt, we use **256** distinct symbols, i.e. the byte values `0x00` to `0xFF`, which allows the encryption (and decryption) of arbitrary steams of bytes, rather than just plain text. Of course, SlunkCrypt can encrypt (and decrypt) plain text as well.
+
+- In the original Enigma machine, the signal passes through the rotors *twice*, once in forward direction and then again in backwards direction &ndash; thus the "reflector" wheel. This way, the Enigma's encryption was made *involutory*, i.e. encryption and decryption were the same operation. While this was highly convenient, it also severely weakened the cryptographic strength of the Enigma maschine, because the number of possible permutations was reduced drastically! This is one of the main reasons why the Enigma machine eventually was defeated. In SlunkCrypt, the signal passes through the simulated rotors just *once*, in order to maximize the number of possible permutations. This eliminates the most important known weakness of the Enigma machine. Obviously, in SlunkCrypt, separate modes for encryption and decryption need to be provided, because encryption and decryption *no* longer are the same.
+
+- In the original Enigma machine, *only* the rightmost rotor was stepped after every symbol. The other rotors were stepped infrequently. Specifically, if one rotor has completed a full turn, it will carry on the next wheel by one step &ndash; much like the odometer in a car. The fact that most of the rotors remained in the same position for a long time was another important weakness of the Enigma machine that ultimately lead to its demise. Furthermore, the positions of the Enigma's rotors would repeat after only 16,900 characters. In SlunkCrypt an improved stepping algorithm is used, which ensures that *all* rotors are stepped at an equal frequency. At the same time, the rotor positions in SlunkCrypt practically *never* repeat.
+
+- The internal wiring of each of the original Enigma machine's rotors was *fixed*. Each rotor came with a different internal wiring (i.e. permutation). Some models even had more than three rotors to choose from, but only three rotors were used at a time. Nonetheless, TTBOMK, the internal wiring of each of the supplied rotors was *never* changed, for a specific model. This severely restricted the key space of the Enigma machine, as far as the rotors are concerned, because *only* the order of the rotors and the initial position of each rotor could be varied. In SlunkCrypt, a fully randomized wiring is generated from the password, using a [PRNG](https://en.wikipedia.org/wiki/Pseudorandom_number_generator), for each of the 256 simulated rotors. The initial rotor positions are randomized as well.
+
+- SlunkCrypt does **not** currently implement the *plugboard* of the original Enigma machine. That is because, even though the plugboard has a large key space, it effectively is just a *fixed* substitution cipher that does **not** contribute much to the cryptographic strength of the Enigma machine. In fact, the [bombe](https://en.wikipedia.org/wiki/Bombe#Stecker_values) was able to circumvent the plugboard.
+
+
 Programming Interface (API)
 ===========================
 
@@ -336,7 +354,7 @@ Erase the contents of a byte array, by overwriting it with *zero* bytes. Compile
  * `buffer`  
    A pointer to the buffer whose content is to be erased.
 
-   The buffer must be *at least* `length` bytes in size. If the buffer is longer than `length` bytes, then *only* the first `length` bytes of the buffer will be erased!
+   The buffer must be *at least* `length` bytes in size. If the buffer is longer than `length` bytes, then *only* the first `length` bytes of the buffer will be erased; the remainder of the buffer will *not* be modified!
 
  * `length`  
    The size of the buffer to be erased, in bytes.
@@ -411,7 +429,7 @@ Encrypt the next message chunk, using separate input/output containers (`std::ve
     A reference to the `std::vector<uint8_t>` instance containing the next chunk of the plaintext to be encrypted. This can be arbitrary binary data, e.g. UTF-8 encoded text. NULL bytes are **not** treated specially.
 
  * `output`  
-    A reference to the `std::vector<uint8_t>` instance where the ciphertext chunk that corresponds to the given plaintext chunk will be stored.
+    A reference to the `std::vector<uint8_t>` instance where the ciphertext that corresponds to the given plaintext will be stored.
     
     The `output.size()` must be *greater than or equal* to `input.size()`. If the `output.size()` is larger than the `input.size()`, then only the first `input.size()` elements of `output` will be filled with encrypted data!
 
@@ -535,7 +553,7 @@ Decrypt the next message chunk, using separate input/output containers (`std::ve
     A reference to the `std::vector<uint8_t>` instance containing the next chunk of the ciphertext to be decrypted.
 
  * `output`  
-    A reference to the `std::vector<uint8_t>` instance where the plaintext chunk that corresponds to the given ciphertext chunk will be stored.
+    A reference to the `std::vector<uint8_t>` instance where the plaintext that corresponds to the given ciphertext will be stored.
     
     The `output.size()` must be *greater than or equal* to `input.size()`. If the `output.size()` is greater than the `input.size()`, then only the first `input.size()` elements of `output` will be filled with decrypted data!