in reply to crypto with core modules only

The best (unbreakable) and simplest has to be the One-time_pad. This originally was restricted to 26 letters. To include all printables you would need to transpose "\n" to say chr(127) (unprintable just after 126 printable) to keep the printables + a token for "\n" sequential. Then you generate N random numbers between 0 and 95 (hereafter the key), one for each character in the input. The encryption is to subtract 32 from the ord of each character in the input and add it to its corresponding key value modulo 95. Add 32 to that and you have the ord of a printable except for 127 which you replace with "\n". Same for the key - add 32, chr it and transpose chr(127) to "\n" for printing it out. The key (one-time pad) is issued on encryption and is needed for decryption. Decryption is simply the inverse -- subtract 32 from the key characters and input characters, subtract each key value from the input character value modulo 95, add 32, print except that 127 is printed as "\n". Both the key and the encrypted files are random, so without the key, the code is completely unbreakable.

Replies are listed 'Best First'.
Re^2: crypto with core modules only
by tobyink (Canon) on Aug 30, 2018 at 16:34 UTC

    One-time pads can be implemented much more easily than that. Just create a string of random characters the same length as your message (we'll call it $key), then do this:

    my $encrypted = $message ^ $key; my $decrypted = $encrypted ^ $key;

    This will result in a ciphertext which is full of non-printable characters, but you can base64 encode it (MIME::Base64 has been in core since before Perl 5.8).

    The problem with one-time pads is that the keys are very long (same length as the message) and need to have a decent amount of randomness, so cannot be committed to memory. They need to be stored somewhere.

      I considered XOR before choosing the algorithm and rejected it because XOR only changes those bits that are different = about 50% of them. Although that seems plausibly enough to have the same effect, it seemed easier to block possible security loopholes therein than to have to do days of work analysing them statistically.

      And because you then have to choose something like MIME::Base64 to make it printable, this would increase the average lengths of both key and message by (95-64)/64 * 100% = 60.8%, exacerbating your own final point about lengths.

      Conversely, the OP is trying to encode a small list of info, I imagine to be something like:-

      pwd google p&BBw0RD
      pin iphone 8642
      etc.

      So I chose the solution that best fits what I imagine to be the use case. Yes the user needs to note the key which is issued at encryption time, equal in length to his secret info list and although it might well be 50+ characters in length, the OP is highly suggestive of wanting to reject keys that are too short - hence I stick by my post. I feel I responded as optimally as I could within a reasonable level of background research.

      update re having to store the key somewhere - this is already consequent from the boundary conditions of the OP. And its precisely what the OTP and the OP for that matter is about - write it on the back of a business card and close the terminal window used to generate the key, so there is only one physical copy, no electronic copies reducing the weakness to one physical item to keep in your physical wallet.

      more update: flipping half the bits with xor is analytically breakable for repeated use on same document where changes are small. modulo solution does not have same weakness.

        If you flip either 0% of bits or 100% of bits, the crypto is easily breakable. (In the 0% case, the ciphertext is bit-by-bit identical to the plaintext!) For numbers very close to 0% or very close to 100%, it's not a lot harder. About 50% seems the optimal number of bits to flip, provided you don't do it by a predictable pattern.

        The base64 encoding would happen after encrypting, and the base64 decoding would happen before decrypting. So although it does make the ciphertext longer, it doesn't affect the required key length, which is still equal to the length of the plaintext.

        My algorithm has the advantage that you could not only reasonably commit a very short key to memory, but you could also commit to memory the script necessary to decrypt it!

        more update: flipping half the bits with xor is analytically breakable for repeated use on same document where changes are small. modulo solution does not have same weakness.

        ... but both you and tobyink were discussing a one-time pad. AFAIK, repetition is a common way to break encryption schemes and it's a substantial part of how the Enigma machine was broken. Although I'm not an expert and open to being proven wrong, I'd be willing to bet the modulo solution is breakable in a similar way to XOR if the pad is re-used.

        A reply falls below the community's threshold of quality. You may see it by logging in.
        XOR only changes those bits that are different = about 50% of them.

        Sorry, but I don't understand this point. Are you suggesting that flipping more bits will make it more secure? What would be an optimal number of bits to flip?