• Flexible-size block ciphers with unbalanced Feistel networks

    From Leo@21:1/5 to All on Thu Feb 1 21:58:23 2024
    Hey sci.crypt,

    I wanted an encrypted and authenticated "secret box" like thing. Instead
    of the usual IV + encrypted blob + MAC combination, I wanted to explore
    the problem space and have a little fun.

    I used an unbalanced Feistel network, with one part being a single byte.
    For this, I needed a round function that can take the rest of the block
    along with a key, and reduce it into a single byte. I go through the
    entire block and perform N rounds of Feistel for an N-byte block.

    A standard Merkle-Damgard hash works well for this, but there are a ton of options that can work for this purpose. Perhaps something to explore in
    the future.

    "Regular" solutions are really malleable. Depending on the block cipher
    mode, it is quite easy to modify the ciphertext to affect the plaintext in predictable ways. This goes from flipping bits while only breaking a
    single block all the way to being able to make arbitrary modifications as
    long as you know the plaintext. This causes MACs to have a massive
    importance.

    With this mode, any change to the ciphertext affects the entire plaintext
    in a random way. It sort of An ASCII message ceases to be meaningful text,
    a JSON message ceases to be valid JSON etc. Depending on the security
    target, a MAC can be completely left out. Or a fixed string somewhere can
    be used in place of a MAC, like every valid block starting/ending with 0xCAFEBABE to have the same effect as a 32-bit MAC.

    Have any of you used a similar construction anywhere? I'd be curious to
    know what you think, I had a lot of fun playing around with this, and it
    even ended up having some convenient properties.

    I'm putting a small example in Python with SHA-256 as the round function.

    import hashlib

    def sha256(x: bytes) -> int: return hashlib.sha256(x).digest()[0]

    def encrypt(buf: bytes, key: bytes) -> bytes:
    key = len(key).to_bytes(8, 'little') + key

    for _ in range(len(buf)):
    left, right = buf[0], buf[1:]
    new_right = sha256(key + right) ^ left
    buf = right + bytes([new_right])

    return buf

    def decrypt(buf: bytes, key: bytes) -> bytes:
    key = len(key).to_bytes(8, 'little') + key

    for _ in range(len(buf)):
    left, right = buf[:-1], buf[-1]
    new_left = sha256(key + left) ^ right
    buf = bytes([new_left]) + left

    return buf

    while True:
    action = input("'encrypt' or 'decrypt'? ")
    if action not in ('encrypt', 'decrypt'): continue
    key = input("key: ").encode("utf-8")
    buf = input("data: ")

    if action == 'encrypt':
    buf = buf.encode("utf-8")
    print(encrypt(buf, key).hex())
    elif action == 'decrypt':
    buf = bytes.fromhex(buf)
    print(decrypt(buf, key))


    --
    Leo

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Leo@21:1/5 to Leo on Thu Feb 1 22:50:53 2024
    On Thu, 1 Feb 2024 21:58:23 -0000 (UTC), Leo wrote:

    "Regular" solutions are really malleable. Depending on the block cipher
    mode, it is quite easy to modify the ciphertext to affect the plaintext
    in predictable ways. This goes from flipping bits while only breaking a single block all the way to being able to make arbitrary modifications
    as long as you know the plaintext. This causes MACs to have a massive importance.

    With this mode, any change to the ciphertext affects the entire
    plaintext in a random way. It sort of

    Oops, looks like I forgot to finish my sentence there.

    I mean to say, "It sort of behaves like an All-or-nothing transform".

    --
    Leo

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Leo@21:1/5 to Chris M. Thomasson on Thu Feb 1 22:49:22 2024
    On Thu, 1 Feb 2024 14:10:48 -0800, Chris M. Thomasson wrote:

    Nice! I need to study this some more for sure. Thanks Leo! :^)

    Fwiw, I am kind of busy right now... Basically, it kind of reminds me
    of one of my experimental HMAC ciphers. Altering a single byte of the
    ciphertext causes a radically different plaintext to be generated,
    random? Humm... A radically different ciphertext is generated on every
    encryption of the exact same cipher text:

    http://funwithfractals.atspace.cc/ct_cipher/

    Fwiw, here in an online example using the default key to encrypt.

    HMAC would fit into this cipher very naturally too. Instead of sha256(key
    + data), you'd do hmacsha256(key, data).

    The online version has an option of sha-256 and sha-512 in the secret
    key. You should be able to click on the link, and see the decrypted
    message since it uses the default key.

    Fwiw, as of now, it does not use a final MAC...

    I am wondering if a proper MAC is even with these kinds of constructions.
    Have you run any tests on how many random bit flips / modifications you
    need in order to have something that is all ASCII? I think especially with things with humans in the loop (like messaging or emails), it will be very obvious if someone is tampering with the message.

    It sure seems to be fairly, "secure"... Although it has not been
    properly peer reviewed yet. So, experimental is shall remain... ;^)

    It's possible to mess up, of course, but using HMAC-SHA256 is a very safe
    bet. You can be pretty much 100% sure that any vulnerabilities or problems
    will arise from your own code or protocol instead of the core primitive.
    This is very useful, much less code to comb over and usually much simpler
    code too.

    And especially HMACs are very forgiving, pretty hard to misuse those.

    When someone posts on sci.crypt with a completely custom construction it's
    more likely to be broken by someone here. Can't say the same about people re-using SHA-256.

    Also, try altering a single bit of the password and/or ciphertext, or changing the hash function, then clicking decrypt. The plaintext will be radically different.

    Yep, this is what made me want the entire message in one "block" too.
    Block ciphers have excellent avalanche/garbling with unintended
    modifications, but it's usually only for a single block. So if you have
    your entire message and nonce/IV in a single block, everything has this
    useful property.

    --
    Leo

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Richard Harnden@21:1/5 to Chris M. Thomasson on Fri Feb 2 16:42:06 2024
    On 01/02/2024 22:06, Chris M. Thomasson wrote:
    On 2/1/2024 1:58 PM, Leo wrote:
    Hey sci.crypt,

    I wanted an encrypted and authenticated "secret box" like thing. Instead
    of the usual IV + encrypted blob + MAC combination, I wanted to explore
    the problem space and have a little fun.

    Fwiw, [...]

    Chris: please stop trying to turn every thread into 'look at my highly experimental hmac cipher wotsit'

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)