wraiford / encrypt-gib

Encryption using hashing.
2 stars 0 forks source link

Improve README.md with existing jargon #1

Closed wraiford closed 1 year ago

wraiford commented 2 years ago

I'm not a cryptographer, but I've studied it throughout my lifetime and am aware of some of the jargon of some existing encryption algorithms. I'm creating this issue to see if we can adjust the verbiage in the README.md to align with core concepts in that jargon. (Fundamentally, I have yet to find another present-day encryption algorithm that works at the high level in hex that I'm working with, as opposed to working at the binary level.)

note: I am aware that not working at the binary level seems to be "inefficient". However the efficiency comes in reducing complexity to the point where the only primitive required beyond basic loops, concatenation, etc. is a hash function.

key stretching

For example, I am aware that in code at doInitialRecursions (cruft removed for simplicity):

for (let i = 0; i < initialRecursions; i++) {
    const preHash = getPreHash({secret, prevHash: hash, salt, saltStrategy});
    hash = await h.hash({s: preHash, algorithm: hashAlgorithm});
}
return hash;

Here, we are performing functionality similar to (precisely described in?) key stretching:

There are several ways to perform key stretching. One way is to apply a cryptographic hash function or a block cipher repeatedly in a loop.

In this case, I am recursively calling hash on the preHash driven by the parameters.

hex encoding plaintext --> ?

There is an initial step that encodes the original plaintext data into hex in order to prepare for the function rounding. What is the term for this data massaging/preparation?

key schedule, substitution and/or product cipher?

Here is a snapshot of the current heart of the encrypt algorithm (again cruft removed):

// we have our prevHash starting point, so now we can iterate through the data
let encryptedDataIndexes = [];
for (let i = 0; i < hexEncodedData.length; i++) {
    // this is the character of data that we want to map to an index into the generated alphabet
    const hexCharFromData: string = hexEncodedData[i];
    let alphabet: string = "";
    let hash: string;
    while (!alphabet.includes(hexCharFromData)) {
        for (let j = 0; j < recursionsPerHash; j++) {
            const preHash = getPreHash({prevHash, salt, saltStrategy});
            hash = await h.hash({s: preHash, algorithm: hashAlgorithm});
            prevHash = hash;
        }
        alphabet += hash!;
    }

    // we now have the alphabet, so find the index of hex character
    const charIndex = alphabet.indexOf(hexCharFromData);
    encryptedDataIndexes.push(charIndex);
}

const encryptedData = encryptedDataIndexes.join(encryptedDataDelimiter);

This definitely seems to correspond to a key schedule managing function rounds:

In cryptography, the so-called product ciphers are a certain kind of cipher, where the (de-)ciphering of data is typically done as an iteration of rounds. The setup for each round is generally the same, except for round-specific fixed values called a round constant, and round-specific data derived from the cipher key called a round key. A key schedule is an algorithm that calculates all the round keys from the key.

It doesn't seem to be a conventional substitution cipher because the encrypt-gib "alphabet" (existing README term which does already correspond to jargon) is produced/extended just-in-time per hex-encoded plaintext character. This JIT style seems to be more in line with keystreams, but our indexing into the JIT alphabet is definitely substituting an index as opposed to "combining' with the alphabet.

_note: Similarity mentioned between polyalphabetic and stream ciphers: "Modern stream ciphers can also be seen, from a sufficiently abstract perspective, to be a form of polyalphabetic cipher in which all the effort has gone into making the keystream as long and unpredictable as possible."_

substitution ciphers it is NOT

Here's a list of negatives for us:

conclusions

That's enough for now. Overall, it still does not seem to fit into the "substitution cipher" category, but it appears that there are some abstract grey areas acknowledged on Wikipedia, which shouldn't be too surprising.

I've gone through block and stream ciphers previously, but perhaps I'll do more on those here as this was pretty fruitful. And then we can get the README updated.

wraiford commented 1 year ago

I've gone through and rehashed the documentation after getting some interesting feedback on reddit. My thanks to everyone there, who helped me make a couple decisions here: