• ai rewrite...

    From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to sci.crypt on Sun Jan 4 21:23:31 2026
    From Newsgroup: sci.crypt

    For some reason, the AI wanted to rewrite my python code from:

    http://funwithfractals.atspace.cc/ct_cipher

    Here is what it dumped out:

    _________________________________
    import hashlib
    import hmac
    import os

    # 1. Improved Hex Utility
    # ____________________________________________________________
    def ct_bytes_to_hex(data):
    # Returns a clean hex string with 16-byte rows
    return '\n'.join(data[i:i+16].hex(' ') for i in range(0, len(data), 16)).upper()

    # 2. Key Class (Handles Raw Bytes)
    # ____________________________________________________________
    class ct_secret_key:
    def __init__(self, hmac_key, hash_algo, rand_n):
    self.hmac_key = hmac_key if isinstance(hmac_key, bytes) else hmac_key.encode()
    self.hash_algo = hash_algo
    self.rand_n = rand_n

    def __repr__(self):
    return f"hmac_key: {self.hmac_key.hex()[:16]}...\nhash_algo: {self.hash_algo().name}\nrand_n: {self.rand_n}"

    # 3. The Crypt Round Function (Raw Byte Logic)
    # ____________________________________________________________
    def ct_crypt_round(SK, data_in, decrypt_mode):
    # Initialize HMAC with the secret key
    H = hmac.new(SK.hmac_key, None, SK.hash_algo)

    # Sync with your C logic: Update with reversed key
    H.update(SK.hmac_key[::-1])

    output = bytearray()
    p_idx = 0
    p_len = len(data_in)

    while p_idx < p_len:
    # Generate the keystream block (D)
    D = H.digest()
    d_idx = 0
    d_len = len(D)

    while p_idx < p_len and d_idx < d_len:
    p_byte = data_in[p_idx]
    c_byte = p_byte ^ D[d_idx]
    output.append(c_byte)

    # State Update (Feedback Loop)
    if not decrypt_mode:
    # Encrypt: update(Plaintext, Ciphertext)
    H.update(bytes([p_byte, c_byte]))
    else:
    # Decrypt: update(Ciphertext, Plaintext)
    H.update(bytes([c_byte, p_byte]))

    p_idx += 1
    d_idx += 1

    return bytes(output)

    # 4. The Main Crypt Wrapper
    # ____________________________________________________________
    def ct_crypt(SK, data_in, decrypt_mode):
    processed_data = data_in

    if not decrypt_mode:
    # Prepend TRNG bytes
    # Using os.urandom for actual TRNG-like entropy
    prefix = os.urandom(SK.rand_n)
    processed_data = prefix + processed_data

    # Round 1
    C = ct_crypt_round(SK, processed_data, decrypt_mode)

    # Reverse (Matching your C: ct_reverse)
    C_rev = C[::-1]

    # Round 2
    final = ct_crypt_round(SK, C_rev, decrypt_mode)

    if decrypt_mode:
    # Strip the random prefix bytes
    final = final[SK.rand_n:]

    return final

    # ____________________________________________________________
    # EXECUTION
    # ____________________________________________________________

    # Your 64-byte TRNG Key
    trng_64_bytes = os.urandom(64)

    SK = ct_secret_key(
    trng_64_bytes,
    hashlib.sha512, # Upgraded to SHA-512 as discussed
    73
    )

    plaintext = b"ABCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDE"

    # Encrypt
    ciphertext = ct_crypt(SK, plaintext, False)
    print(f"Ciphertext Hex:\n{ct_bytes_to_hex(ciphertext)}")

    # Decrypt
    decrypted = ct_crypt(SK, ciphertext, True)
    print(f"\nDecrypted String: {decrypted.decode()}")

    assert decrypted == plaintext

    _________________________________
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to sci.crypt on Sun Jan 4 22:12:36 2026
    From Newsgroup: sci.crypt

    On 1/4/2026 9:23 PM, Chris M. Thomasson wrote:
    For some reason, the AI wanted to rewrite my python code from:
    [...]

    It wrote a freq analysis test:

    import hashlib
    import hmac
    import os
    from collections import Counter

    # -----------------------------------------------------------
    # Your rewritten cipher (unchanged)
    # -----------------------------------------------------------

    def ct_bytes_to_hex(data):
    return '\n'.join(data[i:i+16].hex(' ') for i in range(0, len(data), 16)).upper()

    class ct_secret_key:
    def __init__(self, hmac_key, hash_algo, rand_n):
    self.hmac_key = hmac_key if isinstance(hmac_key, bytes) else hmac_key.encode()
    self.hash_algo = hash_algo
    self.rand_n = rand_n

    def ct_crypt_round(SK, data_in, decrypt_mode):
    H = hmac.new(SK.hmac_key, None, SK.hash_algo)
    H.update(SK.hmac_key[::-1])

    output = bytearray()
    p_idx = 0
    p_len = len(data_in)

    while p_idx < p_len:
    D = H.digest()
    d_idx = 0
    d_len = len(D)

    while p_idx < p_len and d_idx < d_len:
    p_byte = data_in[p_idx]
    c_byte = p_byte ^ D[d_idx]
    output.append(c_byte)

    if not decrypt_mode:
    H.update(bytes([p_byte, c_byte]))
    else:
    H.update(bytes([c_byte, p_byte]))

    p_idx += 1
    d_idx += 1

    return bytes(output)

    def ct_crypt(SK, data_in, decrypt_mode):
    processed_data = data_in

    if not decrypt_mode:
    prefix = os.urandom(SK.rand_n)
    processed_data = prefix + processed_data

    C = ct_crypt_round(SK, processed_data, decrypt_mode)
    C_rev = C[::-1]
    final = ct_crypt_round(SK, C_rev, decrypt_mode)

    if decrypt_mode:
    final = final[SK.rand_n:]

    return final

    # -----------------------------------------------------------
    # Frequency Analysis Test
    # -----------------------------------------------------------

    # Fixed key for reproducibility
    key_material = b"K" * 64

    SK = ct_secret_key(
    key_material,
    hashlib.sha512,
    73
    )

    # 100,000 bytes of ASCII 'A'
    plaintext = b"A" * 100_000

    print("Encrypting 100,000 identical bytes...")

    ciphertext = ct_crypt(SK, plaintext, False)

    # Count byte frequencies
    freq = Counter(ciphertext)

    print("\nTop 20 most common ciphertext bytes:")
    for byte, count in freq.most_common(20):
    print(f"0x{byte:02X}: {count}")

    print("\nTotal unique byte values:", len(freq))


    I got:

    Encrypting 100,000 identical bytes...

    Top 20 most common ciphertext bytes:
    0xE4: 465
    0x25: 447
    0xAF: 445
    0xA4: 437
    0x93: 433
    0x7E: 430
    0xEF: 430
    0xE1: 429
    0x55: 429
    0x96: 428
    0xCA: 428
    0x41: 426
    0xA7: 424
    0x9B: 424
    0x8C: 423
    0xED: 423
    0x67: 422
    0x6F: 422
    0x1C: 420
    0xF9: 419

    Total unique byte values: 256


    ** Process exited - Return Code: 0 **



    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to sci.crypt on Sun Jan 4 22:13:57 2026
    From Newsgroup: sci.crypt

    On 1/4/2026 9:23 PM, Chris M. Thomasson wrote:
    For some reason, the AI wanted to rewrite my python code from:

    http://funwithfractals.atspace.cc/ct_cipher

    Here is what it dumped out:

    [...]

    It wrote a test that tries to alter a single bit of ciphertext:

    import hashlib
    import hmac
    import os

    # 1. Improved Hex Utility
    # ____________________________________________________________
    def ct_bytes_to_hex(data):
    return '\n'.join(data[i:i+16].hex(' ') for i in range(0, len(data), 16)).upper()

    # 2. Key Class (Handles Raw Bytes)
    # ____________________________________________________________
    class ct_secret_key:
    def __init__(self, hmac_key, hash_algo, rand_n):
    self.hmac_key = hmac_key if isinstance(hmac_key, bytes) else hmac_key.encode()
    self.hash_algo = hash_algo
    self.rand_n = rand_n

    # 3. The Crypt Round Function (Raw Byte Logic)
    # ____________________________________________________________
    def ct_crypt_round(SK, data_in, decrypt_mode):
    H = hmac.new(SK.hmac_key, None, SK.hash_algo)
    H.update(SK.hmac_key[::-1])

    output = bytearray()
    p_idx = 0
    p_len = len(data_in)

    while p_idx < p_len:
    D = H.digest()
    d_idx = 0
    d_len = len(D)

    while p_idx < p_len and d_idx < d_len:
    p_byte = data_in[p_idx]
    c_byte = p_byte ^ D[d_idx]
    output.append(c_byte)

    if not decrypt_mode:
    H.update(bytes([p_byte, c_byte]))
    else:
    H.update(bytes([c_byte, p_byte]))

    p_idx += 1
    d_idx += 1

    return bytes(output)

    # 4. The Main Crypt Wrapper
    # ____________________________________________________________
    def ct_crypt(SK, data_in, decrypt_mode):
    processed_data = data_in

    if not decrypt_mode:
    prefix = os.urandom(SK.rand_n)
    processed_data = prefix + processed_data

    C = ct_crypt_round(SK, processed_data, decrypt_mode)
    C_rev = C[::-1]
    final = ct_crypt_round(SK, C_rev, decrypt_mode)

    if decrypt_mode:
    final = final[SK.rand_n:]

    return final

    # ____________________________________________________________
    # BIT-FLIP AVALANCHE DEMO
    # ____________________________________________________________

    # Fixed key for reproducibility
    key_material = b"K" * 64

    SK = ct_secret_key(
    key_material,
    hashlib.sha512,
    73
    )

    plaintext = b"ABCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDE"

    print("Original plaintext:")
    print(plaintext)

    # Encrypt
    ciphertext = ct_crypt(SK, plaintext, False)
    print("\nCiphertext (hex):")
    print(ct_bytes_to_hex(ciphertext))

    # Flip a single bit in the ciphertext
    tampered = bytearray(ciphertext)
    flip_index = len(tampered) // 2
    tampered[flip_index] ^= 0x01
    tampered = bytes(tampered)

    print("\nTampered ciphertext (hex):")
    print(ct_bytes_to_hex(tampered))

    # Decrypt both
    decrypted_ok = ct_crypt(SK, ciphertext, True)
    decrypted_bad = ct_crypt(SK, tampered, True)

    print("\nDecrypted (original ciphertext):")
    print(decrypted_ok)

    print("\nDecrypted (tampered ciphertext):")
    print(decrypted_bad)

    print("\nMatches original plaintext:", decrypted_ok == plaintext) print("Tampered equals original:", decrypted_bad == plaintext)




    I got:

    Original plaintext:
    b'ABCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDE'

    Ciphertext (hex):
    90 DD AA 68 72 29 4E 3E 69 EF 24 11 55 1E AD 5D
    C2 AA 26 6B 7A 99 91 C1 0C F2 64 33 FA 70 BC 9E
    C2 2E 2F F8 59 F7 C7 03 BD 80 09 DA 47 AB 91 A3
    E8 8F 3A A3 BB B5 7F CB 2A CD 78 E4 8D E9 F0 1D
    F2 74 01 B8 44 DA B0 06 0D AA 76 06 19 7E 54 68
    66 10 92 D1 19 38 04 FF 68 BE 75 99 86 A5 20 40
    A2 8B 79 77 B1 F0 D4 41 07 3A 5C 51 8E 36 EF A1
    20 19 5B 4B 72 D5 69 13 85 D8 2C 0B 45 01 30 84
    1D

    Tampered ciphertext (hex):
    90 DD AA 68 72 29 4E 3E 69 EF 24 11 55 1E AD 5D
    C2 AA 26 6B 7A 99 91 C1 0C F2 64 33 FA 70 BC 9E
    C2 2E 2F F8 59 F7 C7 03 BD 80 09 DA 47 AB 91 A3
    E8 8F 3A A3 BB B5 7F CB 2A CD 78 E4 8D E9 F0 1D
    F3 74 01 B8 44 DA B0 06 0D AA 76 06 19 7E 54 68
    66 10 92 D1 19 38 04 FF 68 BE 75 99 86 A5 20 40
    A2 8B 79 77 B1 F0 D4 41 07 3A 5C 51 8E 36 EF A1
    20 19 5B 4B 72 D5 69 13 85 D8 2C 0B 45 01 30 84
    1D

    Decrypted (original ciphertext): b'ABCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDE'

    Decrypted (tampered ciphertext):
    b'\xf0w\xa3:\x04|\x08lw\xfc\xed L\xb5\x0f\xd3\xdb\xe2\x95\xa3^\x89\x7f\xad.\xaf\xdc\xf9\xf0\x81&\xca\xb172v\xcb\xbc\xc1X\x99\x9b\xe3Y+\xfb3B/!\x97\xfd\xb6\xb3\x9bP'

    Matches original plaintext: True
    Tampered equals original: False
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to sci.crypt on Sun Jan 4 22:28:07 2026
    From Newsgroup: sci.crypt

    On 1/4/2026 9:23 PM, Chris M. Thomasson wrote:
    For some reason, the AI wanted to rewrite my python code from:

    http://funwithfractals.atspace.cc/ct_cipher

    Here is what it dumped out:

    _________________________________
    [...]

    Here is a plaintextrCadifferential probe:

    import hashlib
    import hmac
    import os

    # -----------------------------------------------------------
    # Your rewritten cipher (unchanged)
    # -----------------------------------------------------------

    def ct_bytes_to_hex(data):
    return '\n'.join(data[i:i+16].hex(' ') for i in range(0, len(data), 16)).upper()

    class ct_secret_key:
    def __init__(self, hmac_key, hash_algo, rand_n):
    self.hmac_key = hmac_key if isinstance(hmac_key, bytes) else hmac_key.encode()
    self.hash_algo = hash_algo
    self.rand_n = rand_n

    def ct_crypt_round(SK, data_in, decrypt_mode):
    H = hmac.new(SK.hmac_key, None, SK.hash_algo)
    H.update(SK.hmac_key[::-1])

    output = bytearray()
    p_idx = 0
    p_len = len(data_in)

    while p_idx < p_len:
    D = H.digest()
    d_idx = 0
    d_len = len(D)

    while p_idx < p_len and d_idx < d_len:
    p_byte = data_in[p_idx]
    c_byte = p_byte ^ D[d_idx]
    output.append(c_byte)

    if not decrypt_mode:
    H.update(bytes([p_byte, c_byte]))
    else:
    H.update(bytes([c_byte, p_byte]))

    p_idx += 1
    d_idx += 1

    return bytes(output)

    def ct_crypt(SK, data_in, decrypt_mode):
    processed_data = data_in

    if not decrypt_mode:
    prefix = os.urandom(SK.rand_n)
    processed_data = prefix + processed_data

    C = ct_crypt_round(SK, processed_data, decrypt_mode)
    C_rev = C[::-1]
    final = ct_crypt_round(SK, C_rev, decrypt_mode)

    if decrypt_mode:
    final = final[SK.rand_n:]

    return final

    # -----------------------------------------------------------
    # Plaintext differential test
    # -----------------------------------------------------------

    # Fixed key for reproducibility
    key_material = b"K" * 64
    SK = ct_secret_key(key_material, hashlib.sha512, 73)

    # Two plaintexts differing by 1 byte at the end
    P1 = b"A" * 2000
    P2 = b"A" * 1999 + b"B"

    print("Encrypting two plaintexts that differ by 1 byte...")

    C1 = ct_crypt(SK, P1, False)
    C2 = ct_crypt(SK, P2, False)

    # Derive effective keystreams: keystream = ciphertext XOR plaintext
    keystream1 = bytes([p ^ c for p, c in zip(P1, C1)])
    keystream2 = bytes([p ^ c for p, c in zip(P2, C2)])

    # Compare keystreams
    matches = sum(a == b for a, b in zip(keystream1, keystream2))

    print("\nPlaintext 1 last 16 bytes:")
    print(P1[-16:])

    print("\nPlaintext 2 last 16 bytes:")
    print(P2[-16:])

    print("\nKeystream 1 first 64 bytes:")
    print(ct_bytes_to_hex(keystream1[:64]))

    print("\nKeystream 2 first 64 bytes:")
    print(ct_bytes_to_hex(keystream2[:64]))

    print("\nNumber of matching keystream bytes:", matches)
    print("Total bytes compared:", len(keystream1))
    print("Keystreams identical?", keystream1 == keystream2)



    I get:

    Encrypting two plaintexts that differ by 1 byte...

    Plaintext 1 last 16 bytes:
    b'AAAAAAAAAAAAAAAA'

    Plaintext 2 last 16 bytes:
    b'AAAAAAAAAAAAAAAB'

    Keystream 1 first 64 bytes:
    2F 0A 83 AC 3C A9 6F 2A 0B A5 1D D1 AB 50 E6 14
    3C CB ED FD D3 61 DE DA DC 32 9B 60 78 34 30 46
    E6 8F 8D FF DD 40 69 C9 0D AB 39 1F 57 56 C8 BB
    66 8F BF D3 8F 32 7C 21 33 12 0F 84 7F AF 27 3C

    Keystream 2 first 64 bytes:
    67 C2 0D DE 73 6F 2F AA F9 32 58 26 B2 4D 2E 79
    05 29 43 B0 C8 B1 E1 03 07 77 CD EE 97 C5 A5 4D
    85 E4 11 F8 57 B9 36 E7 31 63 51 35 20 EF C3 B1
    44 6C 34 3A 76 5D 35 EF B7 60 0A B5 FB AE 0E B5

    Number of matching keystream bytes: 8
    Total bytes compared: 2000
    Keystreams identical? False

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to sci.crypt on Sun Jan 4 22:23:30 2026
    From Newsgroup: sci.crypt

    On 1/4/2026 9:23 PM, Chris M. Thomasson wrote:
    For some reason, the AI wanted to rewrite my python code from:

    http://funwithfractals.atspace.cc/ct_cipher

    Here is what it dumped out:
    [...]

    It made a known plaintext attack:


    import hashlib
    import hmac
    import os

    # -----------------------------------------------------------
    # Your rewritten cipher (unchanged)
    # -----------------------------------------------------------

    def ct_bytes_to_hex(data):
    return '\n'.join(data[i:i+16].hex(' ') for i in range(0, len(data), 16)).upper()

    class ct_secret_key:
    def __init__(self, hmac_key, hash_algo, rand_n):
    self.hmac_key = hmac_key if isinstance(hmac_key, bytes) else hmac_key.encode()
    self.hash_algo = hash_algo
    self.rand_n = rand_n

    def ct_crypt_round(SK, data_in, decrypt_mode):
    H = hmac.new(SK.hmac_key, None, SK.hash_algo)
    H.update(SK.hmac_key[::-1])

    output = bytearray()
    p_idx = 0
    p_len = len(data_in)

    while p_idx < p_len:
    D = H.digest()
    d_idx = 0
    d_len = len(D)

    while p_idx < p_len and d_idx < d_len:
    p_byte = data_in[p_idx]
    c_byte = p_byte ^ D[d_idx]
    output.append(c_byte)

    if not decrypt_mode:
    H.update(bytes([p_byte, c_byte]))
    else:
    H.update(bytes([c_byte, p_byte]))

    p_idx += 1
    d_idx += 1

    return bytes(output)

    def ct_crypt(SK, data_in, decrypt_mode):
    processed_data = data_in

    if not decrypt_mode:
    prefix = os.urandom(SK.rand_n)
    processed_data = prefix + processed_data

    C = ct_crypt_round(SK, processed_data, decrypt_mode)
    C_rev = C[::-1]
    final = ct_crypt_round(SK, C_rev, decrypt_mode)

    if decrypt_mode:
    final = final[SK.rand_n:]

    return final

    # -----------------------------------------------------------
    # Known-Plaintext Attack Demonstration
    # -----------------------------------------------------------

    # Fixed key for reproducibility
    key_material = b"K" * 64

    SK = ct_secret_key(
    key_material,
    hashlib.sha512,
    73
    )

    plaintext = b"A" * 2000 # known plaintext

    print("Encrypting the same plaintext twice...")

    cipher1 = ct_crypt(SK, plaintext, False)
    cipher2 = ct_crypt(SK, plaintext, False)

    # Compute "effective keystreams"
    # (This is what an attacker would try to derive)
    keystream1 = bytes([p ^ c for p, c in zip(plaintext, cipher1)])
    keystream2 = bytes([p ^ c for p, c in zip(plaintext, cipher2)])

    # Compare the two keystreams
    same_prefix = sum(a == b for a, b in zip(keystream1, keystream2))

    print("\nKeystream 1 first 64 bytes:")
    print(ct_bytes_to_hex(keystream1[:64]))

    print("\nKeystream 2 first 64 bytes:")
    print(ct_bytes_to_hex(keystream2[:64]))

    print("\nNumber of matching keystream bytes:", same_prefix)
    print("Total bytes compared:", len(keystream1))

    print("\nKeystreams identical?", keystream1 == keystream2)




    I got:


    Encrypting the same plaintext twice...

    Keystream 1 first 64 bytes:
    67 74 9A A4 FF 24 89 03 7F BA 06 99 BC 54 DC F0
    EB 9B AD F1 18 50 0F CE A8 45 F2 8F EE 45 95 57
    77 4C C0 43 08 9E 2B E9 79 B4 48 12 B0 AE A5 B0
    90 CE EA 35 22 36 06 2C 70 A8 F3 DF 76 9E 17 87

    Keystream 2 first 64 bytes:
    43 40 72 D2 98 BB A3 24 64 7B D6 9F 5B 0B 84 2C
    31 8D A6 3C 92 A7 92 4D 41 1A D5 11 20 5B 67 A0
    2D 64 37 4B 43 E7 D3 C1 8E AB C5 16 65 E8 4B A9
    38 F4 CB E7 9A 31 26 3E 21 6F FE B0 99 82 AA 56

    Number of matching keystream bytes: 6
    Total bytes compared: 2000

    Keystreams identical? False


    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to sci.crypt on Sun Jan 4 22:25:34 2026
    From Newsgroup: sci.crypt

    On 1/4/2026 9:23 PM, Chris M. Thomasson wrote:
    For some reason, the AI wanted to rewrite my python code from:

    http://funwithfractals.atspace.cc/ct_cipher

    Here is what it dumped out:

    _________________________________

    [...]


    It wrote a relatedrCakey style attack:

    import hashlib
    import hmac
    import os

    # -----------------------------------------------------------
    # Your rewritten cipher (unchanged)
    # -----------------------------------------------------------

    def ct_bytes_to_hex(data):
    return '\n'.join(data[i:i+16].hex(' ') for i in range(0, len(data), 16)).upper()

    class ct_secret_key:
    def __init__(self, hmac_key, hash_algo, rand_n):
    self.hmac_key = hmac_key if isinstance(hmac_key, bytes) else hmac_key.encode()
    self.hash_algo = hash_algo
    self.rand_n = rand_n

    def ct_crypt_round(SK, data_in, decrypt_mode):
    H = hmac.new(SK.hmac_key, None, SK.hash_algo)
    H.update(SK.hmac_key[::-1])

    output = bytearray()
    p_idx = 0
    p_len = len(data_in)

    while p_idx < p_len:
    D = H.digest()
    d_idx = 0
    d_len = len(D)

    while p_idx < p_len and d_idx < d_len:
    p_byte = data_in[p_idx]
    c_byte = p_byte ^ D[d_idx]
    output.append(c_byte)

    if not decrypt_mode:
    H.update(bytes([p_byte, c_byte]))
    else:
    H.update(bytes([c_byte, p_byte]))

    p_idx += 1
    d_idx += 1

    return bytes(output)

    def ct_crypt(SK, data_in, decrypt_mode):
    processed_data = data_in

    if not decrypt_mode:
    prefix = os.urandom(SK.rand_n)
    processed_data = prefix + processed_data

    C = ct_crypt_round(SK, processed_data, decrypt_mode)
    C_rev = C[::-1]
    final = ct_crypt_round(SK, C_rev, decrypt_mode)

    if decrypt_mode:
    final = final[SK.rand_n:]

    return final

    # -----------------------------------------------------------
    # Related-key style test
    # -----------------------------------------------------------

    # Base key
    base_key = bytearray(b"K" * 64)

    # Related key: flip one bit in the key
    related_key = bytearray(base_key)
    related_key[10] ^= 0x01 # flip one bit in byte 10

    SK1 = ct_secret_key(bytes(base_key), hashlib.sha512, 73)
    SK2 = ct_secret_key(bytes(related_key), hashlib.sha512, 73)

    plaintext = b"A" * 2000

    print("Encrypting with two nearly identical keys...")

    cipher1 = ct_crypt(SK1, plaintext, False)
    cipher2 = ct_crypt(SK2, plaintext, False)

    # Derive effective keystreams for both keys
    keystream1 = bytes([p ^ c for p, c in zip(plaintext, cipher1)])
    keystream2 = bytes([p ^ c for p, c in zip(plaintext, cipher2)])

    # Count matches between the two keystreams
    matches = sum(a == b for a, b in zip(keystream1, keystream2))

    print("\nKey 1 (first 16 bytes):")
    print(ct_bytes_to_hex(bytes(base_key[:16])))

    print("\nKey 2 (first 16 bytes, 1 bit flipped):") print(ct_bytes_to_hex(bytes(related_key[:16])))

    print("\nKeystream 1 first 64 bytes:")
    print(ct_bytes_to_hex(keystream1[:64]))

    print("\nKeystream 2 first 64 bytes:")
    print(ct_bytes_to_hex(keystream2[:64]))

    print("\nNumber of matching keystream bytes:", matches)
    print("Total bytes compared:", len(keystream1))
    print("Keystreams identical?", keystream1 == keystream2)



    I got:

    Encrypting with two nearly identical keys...

    Key 1 (first 16 bytes):
    4B 4B 4B 4B 4B 4B 4B 4B 4B 4B 4B 4B 4B 4B 4B 4B

    Key 2 (first 16 bytes, 1 bit flipped):
    4B 4B 4B 4B 4B 4B 4B 4B 4B 4B 4A 4B 4B 4B 4B 4B

    Keystream 1 first 64 bytes:
    DD 31 4E B2 6B 7C B5 9E 32 64 AC 4F A1 EA 5A F2
    F2 8A E2 05 12 BB A5 F0 94 9D EB 8E B3 E7 04 B4
    B9 38 7B D0 E5 31 68 DB 0B D7 6C 0E 13 6F FF 4F
    68 2A 3B 75 BD 8C B0 B9 4B 13 12 25 13 EF 58 0E

    Keystream 2 first 64 bytes:
    B9 E4 9E 34 BA 22 C7 97 2F B7 84 B5 99 A5 7E A8
    AF 9D 08 08 76 BB F9 F8 D0 07 37 24 2F 0F B0 C2
    48 47 89 40 89 6E 1B CD 66 19 72 88 87 F8 59 FA
    F5 16 25 84 A9 7F 9B 4D B2 B8 DA B2 DD 76 D0 EA

    Number of matching keystream bytes: 7
    Total bytes compared: 2000
    Keystreams identical? False

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to sci.crypt on Sun Jan 4 22:50:23 2026
    From Newsgroup: sci.crypt

    On 1/4/2026 9:23 PM, Chris M. Thomasson wrote:
    For some reason, the AI wanted to rewrite my python code from:

    http://funwithfractals.atspace.cc/ct_cipher

    Here is what it dumped out:

    _________________________________
    [...]

    It wrote some randomness tests:

    import hashlib
    import hmac
    import os
    import random
    import math

    # -----------------------------------------------------------
    # Your cipher (good mode)
    # -----------------------------------------------------------

    class ct_secret_key:
    def __init__(self, hmac_key, hash_algo, rand_n):
    self.hmac_key = hmac_key if isinstance(hmac_key, bytes) else hmac_key.encode()
    self.hash_algo = hash_algo
    self.rand_n = rand_n

    def ct_crypt_round(SK, data_in, decrypt_mode):
    H = hmac.new(SK.hmac_key, None, SK.hash_algo)
    H.update(SK.hmac_key[::-1])

    output = bytearray()
    p_idx = 0
    p_len = len(data_in)

    while p_idx < p_len:
    D = H.digest()
    d_idx = 0
    d_len = len(D)

    while p_idx < p_len and d_idx < d_len:
    p_byte = data_in[p_idx]
    c_byte = p_byte ^ D[d_idx]
    output.append(c_byte)

    if not decrypt_mode:
    H.update(bytes([p_byte, c_byte]))
    else:
    H.update(bytes([c_byte, p_byte]))

    p_idx += 1
    d_idx += 1

    return bytes(output)

    def ct_crypt(SK, data_in, decrypt_mode):
    processed_data = data_in

    if not decrypt_mode:
    prefix = os.urandom(SK.rand_n)
    processed_data = prefix + processed_data

    C = ct_crypt_round(SK, processed_data, decrypt_mode)
    C_rev = C[::-1]
    final = ct_crypt_round(SK, C_rev, decrypt_mode)

    if decrypt_mode:
    final = final[SK.rand_n:]

    return final

    # -----------------------------------------------------------
    # Randomness tests
    # -----------------------------------------------------------

    def monobit_test(data):
    bits = sum(bin(byte).count("1") for byte in data)
    total_bits = len(data) * 8
    proportion = bits / total_bits
    return proportion

    def byte_frequency_test(data):
    freq = [0] * 256
    for b in data:
    freq[b] += 1
    return freq

    def chi_square_test(freq, sample_size):
    expected = sample_size / 256
    chi = sum((f - expected)**2 / expected for f in freq)
    return chi

    def serial_correlation(data):
    n = len(data)
    if n < 2:
    return 0
    sum_prod = sum(data[i] * data[(i+1) % n] for i in range(n))
    sum_x = sum(data)
    sum_x2 = sum(x*x for x in data)
    return (n * sum_prod - sum_x * sum_x) / (n * sum_x2 - sum_x * sum_x)

    # -----------------------------------------------------------
    # Generate large ciphertext sample
    # -----------------------------------------------------------

    hash_algo = hashlib.sha512
    digest_size = hash_algo().digest_size
    rand_n = digest_size

    key_material = os.urandom(64)
    SK = ct_secret_key(key_material, hash_algo, rand_n)

    # 10 MB of random plaintext
    plaintext = os.urandom(10_000_000)

    ciphertext = ct_crypt(SK, plaintext, False)

    print("Generated ciphertext size:", len(ciphertext))

    # -----------------------------------------------------------
    # Run tests
    # -----------------------------------------------------------

    mono = monobit_test(ciphertext)
    freq = byte_frequency_test(ciphertext)
    chi = chi_square_test(freq, len(ciphertext))
    corr = serial_correlation(ciphertext)

    print("\n--- Randomness Test Results ---")
    print("Monobit proportion of 1s:", mono)
    print("Expected ~0.5")

    print("\nChi-square statistic:", chi)
    print("Expected ~256 (-# sqrt(512)) for uniform distribution")

    print("\nSerial correlation:", corr)
    print("Expected ~0 for random data")

    print("\nTop 10 byte frequencies:")
    for i, f in sorted(enumerate(freq), key=lambda x: -x[1])[:10]:
    print(f"Byte {i:3d}: {f}")





    I got:

    Generated ciphertext size: 10000064

    --- Randomness Test Results ---
    Monobit proportion of 1s: 0.5000167248929607
    Expected ~0.5

    Chi-square statistic: 307.90289982144117
    Expected ~256 (-# sqrt(512)) for uniform distribution

    Serial correlation: 0.00013767201034324043
    Expected ~0 for random data

    Top 10 byte frequencies:
    Byte 67: 39927
    Byte 22: 39733
    Byte 247: 39640
    Byte 29: 39575
    Byte 28: 39566
    Byte 39: 39496
    Byte 233: 39486
    Byte 47: 39478
    Byte 240: 39472
    Byte 155: 39466



    --- Synchronet 3.21a-Linux NewsLink 1.2