• An attack vector for my experimental HMAC cipher...

    From Chris M. Thomasson@chris.m.thomasson.1@gmail.com to sci.crypt on Sun Nov 23 21:58:43 2025
    From Newsgroup: sci.crypt


    Try this one for my HMAC cipher for fun?
    ________________________________
    #!/usr/bin/env python3
    """
    Chris M. Thomasson HMAC Cipher: Same Plaintext raA Different Ciphertexts
    Tests that encrypting identical plaintext multiple times produces
    radically different ciphertexts
    Uses os.urandom() for true randomness (TRNG from OS)
    """

    import os
    import hashlib
    import hmac


    def ct_rand_bytes_trng(n):
    """Generate n bytes from OS TRNG (true randomness, not
    pseudo-random)"""
    return os.urandom(n).decode('latin-1')


    def ct_bytes_to_hex(data, offset=0, length=None):
    """Convert bytes to hex string"""
    if length is None:
    length = len(data) - offset
    hex_str = ""
    t = "0123456789ABCDEF"
    for i in range(offset, min(offset + length, len(data))):
    c = ord(data[i]) if isinstance(data[i], str) else data[i]
    nibh = (c & 0xF0) >> 4
    nibl = c & 0x0F
    hex_str += t[nibh] + t[nibl] + " "
    if (i + 1 - offset) % 16 == 0 and i != len(data) - 1:
    hex_str += "\n"
    return hex_str


    class ct_secret_key:
    def __init__(self, hmac_key, hash_algo, rand_n):
    self.hmac_key = hmac_key
    self.hash_algo = hash_algo
    self.rand_n = rand_n


    class ct_bin:
    def __init__(self, ctxt):
    self.bytes = ctxt


    def ct_crypt_round(SK, P, M):
    """Single round of encryption/decryption"""
    H = hmac.new(SK.hmac_key.encode(), None, SK.hash_algo)
    H.update(SK.hmac_key[::-1].encode())
    C = ""
    I_P = 0
    I_P_N = len(P.bytes)

    while I_P < I_P_N:
    D = H.digest()
    I_D = 0
    I_D_N = len(D)

    while I_P < I_P_N and I_D < I_D_N:
    C_I_P = ord(P.bytes[I_P]) ^ D[I_D]
    C = C + chr(C_I_P)

    if M == False:
    H.update(P.bytes[I_P].encode())
    H.update(chr(C_I_P).encode())
    else:
    H.update(chr(C_I_P).encode())
    H.update(P.bytes[I_P].encode())

    I_P = I_P + 1
    I_D = I_D + 1

    return ct_bin(C)


    def ct_crypt(SK, P, M):
    """Full encryption/decryption (2 rounds with reversal)"""
    if M == False:
    R = ct_rand_bytes_trng(SK.rand_n) # Use TRNG
    P.bytes = R + P.bytes

    C = ct_crypt_round(SK, P, M)
    C_1 = ct_bin(C.bytes[::-1])
    C = ct_crypt_round(SK, C_1, M)

    if M == True:
    size = len(C.bytes) - SK.rand_n
    C.bytes = C.bytes[SK.rand_n : SK.rand_n + size]

    return C


    def hamming_distance(bytes1, bytes2):
    """Calculate Hamming distance (bit differences) between two byte strings"""
    if len(bytes1) != len(bytes2):
    return -1

    diff_count = 0
    for b1, b2 in zip(bytes1, bytes2):
    val1 = ord(b1) if isinstance(b1, str) else b1
    val2 = ord(b2) if isinstance(b2, str) else b2
    diff_count += bin(val1 ^ val2).count('1')

    return diff_count


    # ==================== MAIN TEST ====================

    print("=" * 80)
    print("HMAC CIPHER: IDENTICAL PLAINTEXT raA RADICALLY DIFFERENT CIPHERTEXTS") print("Using OS TRNG (true randomness)")
    print("=" * 80)

    SK = ct_secret_key(
    "This is the HMAC Key. It should be a crypto secure key! Damn it.",
    hashlib.sha384,
    73
    )

    plaintext = "The quick brown fox jumps over the lazy dog."
    num_encryptions = 10

    print(f"\nPlaintext: {repr(plaintext)} ({len(plaintext)} bytes)") print(f"Encrypting {num_encryptions} times with different TRNG prefixes\n")

    ciphertexts = []

    for i in range(num_encryptions):
    P = ct_bin(plaintext)
    C = ct_crypt(SK, P, False)
    ciphertexts.append(C.bytes)
    print(f"Encryption {i+1}:")
    print(ct_bytes_to_hex(C.bytes, 0, 32))

    print("\n" + "=" * 80)
    print("PAIRWISE COMPARISON: ARE CIPHERTEXTS RADICALLY DIFFERENT?")
    print("=" * 80)

    hamming_distances = []

    for i in range(len(ciphertexts)):
    for j in range(i + 1, len(ciphertexts)):
    ct1 = ciphertexts[i]
    ct2 = ciphertexts[j]

    h_dist = hamming_distance(ct1, ct2)
    hamming_distances.append(h_dist)

    total_bits = len(ct1) * 8
    percentage = 100.0 * h_dist / total_bits

    print(f"CT[{i}] vs CT[{j}]: {h_dist:5} bits different /
    {total_bits} ({percentage:5.1f}%)")

    print("\n" + "=" * 80)
    print("STATISTICS")
    print("=" * 80)

    if hamming_distances:
    avg_hamming = sum(hamming_distances) / len(hamming_distances)
    min_hamming = min(hamming_distances)
    max_hamming = max(hamming_distances)
    total_bits = len(ciphertexts[0]) * 8

    print(f"Average Hamming distance: {avg_hamming:.1f} bits ({100.0 * avg_hamming / total_bits:.1f}%)")
    print(f"Minimum Hamming distance: {min_hamming} bits ({100.0 * min_hamming / total_bits:.1f}%)")
    print(f"Maximum Hamming distance: {max_hamming} bits ({100.0 * max_hamming / total_bits:.1f}%)")
    print(f"Expected for random: ~50% = {total_bits * 0.5:.1f} bits")

    if 45 < 100.0 * avg_hamming / total_bits < 55:
    print("\nrLo EXCELLENT: Same plaintext raA completely different ciphertexts")
    print("rLo TRNG prefix is working as designed")
    else:
    print("\nrLu ANOMALY: Ciphertexts are suspiciously similar or different")

    print("\n" + "=" * 80)
    print("VERIFY DECRYPTION: Each ciphertext decrypts to original plaintext") print("=" * 80)

    all_correct = True
    for i, ct in enumerate(ciphertexts):
    C = ct_bin(ct)
    P = ct_crypt(SK, C, True)
    decrypted = P.bytes

    if decrypted == plaintext:
    print(f"Ciphertext {i+1}: rLo Decrypts correctly")
    else:
    print(f"Ciphertext {i+1}: rLu DECRYPTION FAILED")
    all_correct = False

    if all_correct:
    print("\nrLo All ciphertexts decrypt correctly despite being
    radically different")

    print("\n" + "=" * 80)
    print("CONCLUSION")
    print("=" * 80)
    print("The TRNG prefix ensures that:")
    print(" 1. Every encryption is unique (different 73-byte random prefix)") print(" 2. Initial HMAC state is information-theoretically hidden")
    print(" 3. Same plaintext raA completely uncorrelated ciphertexts")
    print(" 4. No two-ciphertext attack is possible without TRNG collision") print("=" * 80)
    ______________________________________

    :^D Fwiw, I got on an online python 3 site:


    ================================================================================
    HMAC CIPHER: IDENTICAL PLAINTEXT raA RADICALLY DIFFERENT CIPHERTEXTS
    Using OS TRNG (true randomness) ================================================================================

    Plaintext: 'The quick brown fox jumps over the lazy dog.' (44 bytes)
    Encrypting 10 times with different TRNG prefixes

    Encryption 1:
    03 5D 44 21 34 0F 9D 31 0B 27 29 A8 E3 3A 58 86
    59 57 16 7E 86 9A 8C 92 14 2E 68 C6 8A 8C BD A2

    Encryption 2:
    26 40 FB 4B 7B FC B3 4E AE 13 A5 AA CA 09 C5 2F
    6D 96 B1 F8 61 93 60 CD 0B 96 64 DE AB 50 F6 4F

    Encryption 3:
    3B DB EC 80 04 42 64 7D AD 42 90 3D BE 66 41 BC
    CE D6 0B 0C 5F 37 18 58 9D 92 91 19 6E F0 86 80

    Encryption 4:
    1A B5 F6 48 EA C4 F5 8A CE 49 DE BA 5A A0 FD B0
    75 B6 80 A5 BE 9D 5D CA 61 90 0C 90 1F 98 3E D8

    Encryption 5:
    58 83 EE DA 6B EA DB 80 D1 55 A8 7F CA 52 D8 3C
    A3 A6 62 6B E1 8C 96 1F B7 4E D2 16 B4 6D 8D 04

    Encryption 6:
    D4 3B 6C 3D 57 83 A8 68 1F F7 7D 98 09 32 76 CE
    75 B9 32 78 7B ED D2 86 65 53 BA CD 8C 69 F4 98

    Encryption 7:
    24 41 2E 3D AF 1D 82 50 E4 33 49 9A 01 C1 A9 3C
    F5 04 EC D9 97 F7 ED 09 19 08 A9 04 4E 97 AA D1

    Encryption 8:
    70 6B 44 51 BB 07 B8 20 B0 F2 84 F8 14 22 C7 62
    59 E6 3A 0E 53 F2 21 D4 44 25 9F 10 99 A9 1D E1

    Encryption 9:
    C2 A0 88 AE 8A D5 7A 30 9D DE E6 A0 68 9A 66 17
    51 3F 53 41 8D 7C CA 84 B7 4E 3B 05 83 82 F1 5F

    Encryption 10:
    73 02 D8 51 60 2E 35 B7 77 8E 3F 80 2F 7A 32 9E
    25 D8 65 44 A3 3E 83 F2 B7 32 63 45 81 40 7F 9A


    ================================================================================
    PAIRWISE COMPARISON: ARE CIPHERTEXTS RADICALLY DIFFERENT? ================================================================================
    CT[0] vs CT[1]: 465 bits different / 936 ( 49.7%)
    CT[0] vs CT[2]: 463 bits different / 936 ( 49.5%)
    CT[0] vs CT[3]: 482 bits different / 936 ( 51.5%)
    CT[0] vs CT[4]: 475 bits different / 936 ( 50.7%)
    CT[0] vs CT[5]: 440 bits different / 936 ( 47.0%)
    CT[0] vs CT[6]: 452 bits different / 936 ( 48.3%)
    CT[0] vs CT[7]: 449 bits different / 936 ( 48.0%)
    CT[0] vs CT[8]: 458 bits different / 936 ( 48.9%)
    CT[0] vs CT[9]: 463 bits different / 936 ( 49.5%)
    CT[1] vs CT[2]: 474 bits different / 936 ( 50.6%)
    CT[1] vs CT[3]: 455 bits different / 936 ( 48.6%)
    CT[1] vs CT[4]: 458 bits different / 936 ( 48.9%)
    CT[1] vs CT[5]: 457 bits different / 936 ( 48.8%)
    CT[1] vs CT[6]: 461 bits different / 936 ( 49.3%)
    CT[1] vs CT[7]: 482 bits different / 936 ( 51.5%)
    CT[1] vs CT[8]: 451 bits different / 936 ( 48.2%)
    CT[1] vs CT[9]: 466 bits different / 936 ( 49.8%)
    CT[2] vs CT[3]: 445 bits different / 936 ( 47.5%)
    CT[2] vs CT[4]: 450 bits different / 936 ( 48.1%)
    CT[2] vs CT[5]: 481 bits different / 936 ( 51.4%)
    CT[2] vs CT[6]: 493 bits different / 936 ( 52.7%)
    CT[2] vs CT[7]: 456 bits different / 936 ( 48.7%)
    CT[2] vs CT[8]: 495 bits different / 936 ( 52.9%)
    CT[2] vs CT[9]: 490 bits different / 936 ( 52.4%)
    CT[3] vs CT[4]: 471 bits different / 936 ( 50.3%)
    CT[3] vs CT[5]: 498 bits different / 936 ( 53.2%)
    CT[3] vs CT[6]: 478 bits different / 936 ( 51.1%)
    CT[3] vs CT[7]: 493 bits different / 936 ( 52.7%)
    CT[3] vs CT[8]: 458 bits different / 936 ( 48.9%)
    CT[3] vs CT[9]: 473 bits different / 936 ( 50.5%)
    CT[4] vs CT[5]: 461 bits different / 936 ( 49.3%)
    CT[4] vs CT[6]: 453 bits different / 936 ( 48.4%)
    CT[4] vs CT[7]: 460 bits different / 936 ( 49.1%)
    CT[4] vs CT[8]: 471 bits different / 936 ( 50.3%)
    CT[4] vs CT[9]: 472 bits different / 936 ( 50.4%)
    CT[5] vs CT[6]: 446 bits different / 936 ( 47.6%)
    CT[5] vs CT[7]: 447 bits different / 936 ( 47.8%)
    CT[5] vs CT[8]: 452 bits different / 936 ( 48.3%)
    CT[5] vs CT[9]: 449 bits different / 936 ( 48.0%)
    CT[6] vs CT[7]: 463 bits different / 936 ( 49.5%)
    CT[6] vs CT[8]: 466 bits different / 936 ( 49.8%)
    CT[6] vs CT[9]: 491 bits different / 936 ( 52.5%)
    CT[7] vs CT[8]: 483 bits different / 936 ( 51.6%)
    CT[7] vs CT[9]: 476 bits different / 936 ( 50.9%)
    CT[8] vs CT[9]: 433 bits different / 936 ( 46.3%)

    ================================================================================
    STATISTICS ================================================================================
    Average Hamming distance: 465.7 bits (49.8%)
    Minimum Hamming distance: 433 bits (46.3%)
    Maximum Hamming distance: 498 bits (53.2%)
    Expected for random: ~50% = 468.0 bits

    rLo EXCELLENT: Same plaintext raA completely different ciphertexts
    rLo TRNG prefix is working as designed

    ================================================================================
    VERIFY DECRYPTION: Each ciphertext decrypts to original plaintext ================================================================================
    Ciphertext 1: rLo Decrypts correctly
    Ciphertext 2: rLo Decrypts correctly
    Ciphertext 3: rLo Decrypts correctly
    Ciphertext 4: rLo Decrypts correctly
    Ciphertext 5: rLo Decrypts correctly
    Ciphertext 6: rLo Decrypts correctly
    Ciphertext 7: rLo Decrypts correctly
    Ciphertext 8: rLo Decrypts correctly
    Ciphertext 9: rLo Decrypts correctly
    Ciphertext 10: rLo Decrypts correctly

    rLo All ciphertexts decrypt correctly despite being radically different

    ================================================================================
    CONCLUSION ================================================================================
    The TRNG prefix ensures that:
    1. Every encryption is unique (different 73-byte random prefix)
    2. Initial HMAC state is information-theoretically hidden
    3. Same plaintext raA completely uncorrelated ciphertexts
    4. No two-ciphertext attack is possible without TRNG collision ================================================================================


    ** 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 Nov 23 22:14:00 2025
    From Newsgroup: sci.crypt

    On 11/23/2025 9:58 PM, Chris M. Thomasson wrote:
    [...]

    if you run it, it only shows 32 bytes for a ciphertext even though there
    is 73 TRNG bytes prepended. God damn ai... ;^D rofl... Try this one




    #!/usr/bin/env python3
    """
    Chris M. Thomasson HMAC Cipher: Same Plaintext raA Different Ciphertexts
    Tests that encrypting identical plaintext multiple times produces
    radically different ciphertexts
    Uses os.urandom() for true randomness (TRNG from OS)
    """

    import os
    import hashlib
    import hmac


    def ct_rand_bytes_trng(n):
    """Generate n bytes from OS TRNG (true randomness, not
    pseudo-random)"""
    return os.urandom(n).decode('latin-1')


    def ct_bytes_to_hex(data, offset=0, length=None):
    """Convert bytes to hex string"""
    if length is None:
    length = len(data) - offset
    hex_str = ""
    t = "0123456789ABCDEF"
    for i in range(offset, min(offset + length, len(data))):
    c = ord(data[i]) if isinstance(data[i], str) else data[i]
    nibh = (c & 0xF0) >> 4
    nibl = c & 0x0F
    hex_str += t[nibh] + t[nibl] + " "
    if (i + 1 - offset) % 16 == 0 and i != len(data) - 1:
    hex_str += "\n"
    return hex_str


    class ct_secret_key:
    def __init__(self, hmac_key, hash_algo, rand_n):
    self.hmac_key = hmac_key
    self.hash_algo = hash_algo
    self.rand_n = rand_n


    class ct_bin:
    def __init__(self, ctxt):
    self.bytes = ctxt


    def ct_crypt_round(SK, P, M):
    """Single round of encryption/decryption"""
    H = hmac.new(SK.hmac_key.encode(), None, SK.hash_algo)
    H.update(SK.hmac_key[::-1].encode())
    C = ""
    I_P = 0
    I_P_N = len(P.bytes)

    while I_P < I_P_N:
    D = H.digest()
    I_D = 0
    I_D_N = len(D)

    while I_P < I_P_N and I_D < I_D_N:
    C_I_P = ord(P.bytes[I_P]) ^ D[I_D]
    C = C + chr(C_I_P)

    if M == False:
    H.update(P.bytes[I_P].encode())
    H.update(chr(C_I_P).encode())
    else:
    H.update(chr(C_I_P).encode())
    H.update(P.bytes[I_P].encode())

    I_P = I_P + 1
    I_D = I_D + 1

    return ct_bin(C)


    def ct_crypt(SK, P, M):
    """Full encryption/decryption (2 rounds with reversal)"""
    if M == False:
    R = ct_rand_bytes_trng(SK.rand_n) # Use TRNG
    P.bytes = R + P.bytes

    C = ct_crypt_round(SK, P, M)
    C_1 = ct_bin(C.bytes[::-1])
    C = ct_crypt_round(SK, C_1, M)

    if M == True:
    size = len(C.bytes) - SK.rand_n
    C.bytes = C.bytes[SK.rand_n : SK.rand_n + size]

    return C


    def hamming_distance(bytes1, bytes2):
    """Calculate Hamming distance (bit differences) between two byte strings"""
    if len(bytes1) != len(bytes2):
    return -1

    diff_count = 0
    for b1, b2 in zip(bytes1, bytes2):
    val1 = ord(b1) if isinstance(b1, str) else b1
    val2 = ord(b2) if isinstance(b2, str) else b2
    diff_count += bin(val1 ^ val2).count('1')

    return diff_count


    # ==================== MAIN TEST ====================

    print("=" * 80)
    print("HMAC CIPHER: IDENTICAL PLAINTEXT raA RADICALLY DIFFERENT CIPHERTEXTS") print("Using OS TRNG (true randomness)")
    print("=" * 80)

    SK = ct_secret_key(
    "This is the HMAC Key. It should be a crypto secure key! Damn it.",
    hashlib.sha384,
    73
    )

    plaintext = "The quick brown fox jumps over the lazy dog."
    num_encryptions = 10

    print(f"\nPlaintext: {repr(plaintext)} ({len(plaintext)} bytes)") print(f"Encrypting {num_encryptions} times with different TRNG prefixes\n")

    ciphertexts = []

    for i in range(num_encryptions):
    P = ct_bin(plaintext)
    C = ct_crypt(SK, P, False)
    ciphertexts.append(C.bytes)
    print(f"Encryption {i+1} ({len(C.bytes)} bytes):")
    print(ct_bytes_to_hex(C.bytes, 0, len(C.bytes)))

    print("\n" + "=" * 80)
    print("PAIRWISE COMPARISON: ARE CIPHERTEXTS RADICALLY DIFFERENT?")
    print("=" * 80)

    hamming_distances = []

    for i in range(len(ciphertexts)):
    for j in range(i + 1, len(ciphertexts)):
    ct1 = ciphertexts[i]
    ct2 = ciphertexts[j]

    h_dist = hamming_distance(ct1, ct2)
    hamming_distances.append(h_dist)

    total_bits = len(ct1) * 8
    percentage = 100.0 * h_dist / total_bits

    print(f"CT[{i}] vs CT[{j}]: {h_dist:5} bits different /
    {total_bits} ({percentage:5.1f}%)")

    print("\n" + "=" * 80)
    print("STATISTICS")
    print("=" * 80)

    if hamming_distances:
    avg_hamming = sum(hamming_distances) / len(hamming_distances)
    min_hamming = min(hamming_distances)
    max_hamming = max(hamming_distances)
    total_bits = len(ciphertexts[0]) * 8

    print(f"Average Hamming distance: {avg_hamming:.1f} bits ({100.0 * avg_hamming / total_bits:.1f}%)")
    print(f"Minimum Hamming distance: {min_hamming} bits ({100.0 * min_hamming / total_bits:.1f}%)")
    print(f"Maximum Hamming distance: {max_hamming} bits ({100.0 * max_hamming / total_bits:.1f}%)")
    print(f"Expected for random: ~50% = {total_bits * 0.5:.1f} bits")

    if 45 < 100.0 * avg_hamming / total_bits < 55:
    print("\nrLo EXCELLENT: Same plaintext raA completely different ciphertexts")
    print("rLo TRNG prefix is working as designed")
    else:
    print("\nrLu ANOMALY: Ciphertexts are suspiciously similar or different")

    print("\n" + "=" * 80)
    print("VERIFY DECRYPTION: Each ciphertext decrypts to original plaintext") print("=" * 80)

    all_correct = True
    for i, ct in enumerate(ciphertexts):
    C = ct_bin(ct)
    P = ct_crypt(SK, C, True)
    decrypted = P.bytes

    if decrypted == plaintext:
    print(f"Ciphertext {i+1}: rLo Decrypts correctly")
    else:
    print(f"Ciphertext {i+1}: rLu DECRYPTION FAILED")
    all_correct = False

    if all_correct:
    print("\nrLo All ciphertexts decrypt correctly despite being
    radically different")

    print("\n" + "=" * 80)
    print("CONCLUSION")
    print("=" * 80)
    print("The TRNG prefix ensures that:")
    print(" 1. Every encryption is unique (different 73-byte random prefix)") print(" 2. Initial HMAC state is information-theoretically hidden")
    print(" 3. Same plaintext raA completely uncorrelated ciphertexts")
    print(" 4. No two-ciphertext attack is possible without TRNG collision") print("=" * 80)




    I get:


    ================================================================================
    HMAC CIPHER: IDENTICAL PLAINTEXT raA RADICALLY DIFFERENT CIPHERTEXTS
    Using OS TRNG (true randomness) ================================================================================

    Plaintext: 'The quick brown fox jumps over the lazy dog.' (44 bytes)
    Encrypting 10 times with different TRNG prefixes

    Encryption 1 (117 bytes):
    B8 28 8E 25 11 B8 61 46 BB B9 FF EF 80 D0 E5 07
    58 CC E2 A8 70 64 98 1D 7F C5 B3 56 FB E1 7B 9C
    2D 78 80 52 A1 A3 47 05 85 96 6E 51 01 A0 20 EF
    FE 36 DF 7A 77 FF 5B 4D 3B 72 38 52 CF 51 3E 69
    4E CB BF 0D D1 40 72 F2 76 59 E4 D2 B4 86 56 FC
    74 32 20 1E E8 92 F5 1F 1E 7C 9A 0E 8E F9 04 28
    66 5A 65 0C 2E 16 53 8D 99 2A 77 12 75 FA D6 C5
    86 27 77 7A F0
    Encryption 2 (117 bytes):
    1E 41 C0 24 2A A9 F0 86 88 3C 97 06 A8 36 0E 83
    CA 4D 8A 4A 03 CD 68 3D 47 5D 01 30 AE 51 A1 33
    62 C1 E1 73 C7 B8 20 8C E1 82 6A 55 AB 06 5D BA
    E6 0E 58 3C D4 52 C6 74 7B 6C 7E 07 56 25 6E 83
    A4 94 3B FD 1C 88 25 15 DB 86 C7 C5 B2 44 1D 3B
    9C 06 78 45 8A F3 3D 50 0D B9 E6 0F FC B6 E7 3C
    15 95 8D 28 7D FA 69 BA 66 B1 42 FC 57 6B E7 A1
    B2 05 CF 5A BC
    Encryption 3 (117 bytes):
    AD 80 21 7F AD C1 21 02 36 F3 B5 75 82 3D 33 F8
    72 DB BB D6 BF 1F 25 A6 22 03 77 F4 45 DF 7C 7A
    E6 D3 13 7A E2 A3 BD 49 9A E7 93 C5 D2 4F 7D B4
    62 58 D8 81 C0 D5 22 77 7D E7 E7 E3 43 3A 06 E9
    C3 16 DE 27 7F 3F 06 0A 8B D0 A9 A7 81 E3 73 16
    3A B5 BA 3D 5D 68 81 A5 59 76 A0 44 45 FF 09 77
    1E 38 B4 95 88 58 B5 3A F4 DF 55 D3 74 F1 2A BF
    6E 33 42 04 64
    Encryption 4 (117 bytes):
    35 E6 7E 87 2C F4 96 2B D9 2E 1C 3B 82 BD DB 9B
    97 3E B1 6D 06 6B 0D AB 80 8C 81 53 94 2D EB 71
    7C 0A B9 84 2B E7 81 49 90 A5 4A 72 E0 3B 6E 69
    ED FB E2 F8 4C 91 F7 51 1F B2 69 6F FA 1A F5 C0
    1D 80 5C 8C A8 01 14 89 A4 32 1E 45 5B 7C D2 B4
    5D 25 BB AD B3 8D BA 94 DC A0 87 3B 55 5D E3 56
    D9 3B F5 69 BD 41 33 3A 37 6E 3D 7D C2 E6 D2 C8
    7C 30 8E 7C 72
    Encryption 5 (117 bytes):
    A0 E9 05 9D BF 83 EE D8 38 E0 B5 90 EF E1 66 C3
    BA E2 C4 71 09 AD DC D6 73 2B 39 EC 81 47 F3 84
    FD 36 9A 09 45 45 68 16 68 72 77 18 2F 2C 4C 51
    13 9A BC 8C 08 D4 95 24 25 28 33 F8 16 C7 AF B7
    42 09 77 62 63 8E 58 63 21 E4 16 33 75 3D E5 BE
    E4 F7 F3 75 09 33 67 59 B7 F1 3A F6 81 1F C8 43
    39 7B EE 53 1A A1 15 F7 16 62 A7 63 C4 D1 08 5B
    68 43 60 3D 72
    Encryption 6 (117 bytes):
    08 71 A9 C2 B6 B5 E7 67 5D DC A9 22 5C E7 30 FE
    6E 17 07 71 CB 7B 35 4D 32 1C 16 A8 1F 6C C7 63
    41 5C 27 95 01 C7 56 E6 28 2E 8C E2 01 D5 87 AE
    B8 0C B0 D1 FC 23 F1 40 EE C2 71 E2 91 F5 50 36
    59 CB 73 71 91 9E 0F 39 65 62 A2 B0 F5 47 6F 91
    B1 9B B7 ED 0A 14 79 86 F5 36 99 7E F6 EA 4E FE
    DD 8F D9 59 1B 47 7B A7 17 CA 7E BC 25 31 C8 75
    66 8D CF 76 A8
    Encryption 7 (117 bytes):
    4E 35 6F C0 A3 9A 91 AD B0 F2 17 6B 92 F8 A4 FC
    F3 C6 D2 04 AA 1D 72 14 D8 B5 06 46 C2 D8 41 3A
    F2 08 3E 28 4C FA 08 8D BA 3F 82 38 4C AA 83 A7
    47 86 A7 6E 19 DC 65 E1 70 69 20 E9 89 F2 88 CB
    10 60 3E FE 03 7F 79 DF 02 C7 F1 06 C4 13 5E D9
    6E CE A7 04 D8 74 38 75 8F A5 BA A2 E6 EC F7 ED
    58 2B 0B F0 B0 26 08 6E DA D3 EF 38 31 E2 97 6F
    1E FE 66 C4 AB
    Encryption 8 (117 bytes):
    DE 2D 51 68 24 5A 42 34 F9 4C 67 8F 4A 9B 2A 16
    A8 9A BD 6F D5 5B CD 6C AC 34 0C 61 6B 02 68 D8
    AD DD 3F D7 49 3D F8 66 F3 D4 5B 1E 95 B3 73 40
    8D 02 3C EB DE F7 C7 7C 7D 14 E6 D7 C2 27 10 B6
    89 01 B8 34 16 BF D8 E3 FB 7E 01 FE 0B 0B 07 5C
    45 96 CF 26 C5 A4 39 50 51 14 5D F8 FE F2 3D F1
    B3 8D 0A 43 C6 52 6E F8 53 B6 AA 8A 75 2B C8 B0
    30 18 9D A0 C0
    Encryption 9 (117 bytes):
    DC F1 4F FC 05 97 5A 13 6D 28 25 9B D7 DE 51 AE
    E5 D1 89 5A 1F 92 26 DB 76 34 20 93 5F C4 E2 53
    BD FD CF 70 93 04 BA DC 5F BD 1B 8E 0A 83 EB 57
    F6 98 4B 61 F4 C8 3C 85 92 75 A0 D9 D9 E0 11 BF
    04 FB 4C B2 3D DB 4D DA 8D F3 07 1D 4B D3 6D 61
    C3 10 16 C7 54 A9 A1 9A 25 67 BA A9 DB C4 C2 AC
    8B E9 BF CE 7A 83 1B 92 E2 A2 30 B0 47 28 97 9C
    35 0C C0 5C 02
    Encryption 10 (117 bytes):
    9F 7B 3D CF 94 F9 E9 24 E3 31 ED 87 8C C7 CB 77
    B3 39 C4 39 F4 56 0E E5 99 90 B7 CB 92 71 19 A3
    78 EC 1E 43 97 59 DD 32 A8 08 BB 7A 90 7B DA E1
    89 71 53 8D 37 1A F7 4B A2 58 B3 8E 25 97 6B DA
    F5 A3 6F 6D FF 3C 06 5E 13 31 41 F6 F5 17 38 81
    3C 4F 15 51 21 D3 46 46 8C 1C 3C 87 A4 A4 1E 5A
    3E 99 68 EA 40 4D DB 79 06 89 4D FA 72 B1 0E 3F
    9F 13 E3 5E A8

    ================================================================================
    PAIRWISE COMPARISON: ARE CIPHERTEXTS RADICALLY DIFFERENT? ================================================================================
    CT[0] vs CT[1]: 435 bits different / 936 ( 46.5%)
    CT[0] vs CT[2]: 494 bits different / 936 ( 52.8%)
    CT[0] vs CT[3]: 480 bits different / 936 ( 51.3%)
    CT[0] vs CT[4]: 478 bits different / 936 ( 51.1%)
    CT[0] vs CT[5]: 470 bits different / 936 ( 50.2%)
    CT[0] vs CT[6]: 458 bits different / 936 ( 48.9%)
    CT[0] vs CT[7]: 487 bits different / 936 ( 52.0%)
    CT[0] vs CT[8]: 493 bits different / 936 ( 52.7%)
    CT[0] vs CT[9]: 448 bits different / 936 ( 47.9%)
    CT[1] vs CT[2]: 473 bits different / 936 ( 50.5%)
    CT[1] vs CT[3]: 463 bits different / 936 ( 49.5%)
    CT[1] vs CT[4]: 499 bits different / 936 ( 53.3%)
    CT[1] vs CT[5]: 465 bits different / 936 ( 49.7%)
    CT[1] vs CT[6]: 467 bits different / 936 ( 49.9%)
    CT[1] vs CT[7]: 448 bits different / 936 ( 47.9%)
    CT[1] vs CT[8]: 470 bits different / 936 ( 50.2%)
    CT[1] vs CT[9]: 465 bits different / 936 ( 49.7%)
    CT[2] vs CT[3]: 456 bits different / 936 ( 48.7%)
    CT[2] vs CT[4]: 464 bits different / 936 ( 49.6%)
    CT[2] vs CT[5]: 482 bits different / 936 ( 51.5%)
    CT[2] vs CT[6]: 468 bits different / 936 ( 50.0%)
    CT[2] vs CT[7]: 479 bits different / 936 ( 51.2%)
    CT[2] vs CT[8]: 473 bits different / 936 ( 50.5%)
    CT[2] vs CT[9]: 478 bits different / 936 ( 51.1%)
    CT[3] vs CT[4]: 486 bits different / 936 ( 51.9%)
    CT[3] vs CT[5]: 460 bits different / 936 ( 49.1%)
    CT[3] vs CT[6]: 484 bits different / 936 ( 51.7%)
    CT[3] vs CT[7]: 483 bits different / 936 ( 51.6%)
    CT[3] vs CT[8]: 471 bits different / 936 ( 50.3%)
    CT[3] vs CT[9]: 484 bits different / 936 ( 51.7%)
    CT[4] vs CT[5]: 462 bits different / 936 ( 49.4%)
    CT[4] vs CT[6]: 470 bits different / 936 ( 50.2%)
    CT[4] vs CT[7]: 487 bits different / 936 ( 52.0%)
    CT[4] vs CT[8]: 481 bits different / 936 ( 51.4%)
    CT[4] vs CT[9]: 468 bits different / 936 ( 50.0%)
    CT[5] vs CT[6]: 464 bits different / 936 ( 49.6%)
    CT[5] vs CT[7]: 449 bits different / 936 ( 48.0%)
    CT[5] vs CT[8]: 447 bits different / 936 ( 47.8%)
    CT[5] vs CT[9]: 436 bits different / 936 ( 46.6%)
    CT[6] vs CT[7]: 475 bits different / 936 ( 50.7%)
    CT[6] vs CT[8]: 459 bits different / 936 ( 49.0%)
    CT[6] vs CT[9]: 464 bits different / 936 ( 49.6%)
    CT[7] vs CT[8]: 446 bits different / 936 ( 47.6%)
    CT[7] vs CT[9]: 483 bits different / 936 ( 51.6%)
    CT[8] vs CT[9]: 499 bits different / 936 ( 53.3%)

    ================================================================================
    STATISTICS ================================================================================
    Average Hamming distance: 470.0 bits (50.2%)
    Minimum Hamming distance: 435 bits (46.5%)
    Maximum Hamming distance: 499 bits (53.3%)
    Expected for random: ~50% = 468.0 bits

    rLo EXCELLENT: Same plaintext raA completely different ciphertexts
    rLo TRNG prefix is working as designed

    ================================================================================
    VERIFY DECRYPTION: Each ciphertext decrypts to original plaintext ================================================================================
    Ciphertext 1: rLo Decrypts correctly
    Ciphertext 2: rLo Decrypts correctly
    Ciphertext 3: rLo Decrypts correctly
    Ciphertext 4: rLo Decrypts correctly
    Ciphertext 5: rLo Decrypts correctly
    Ciphertext 6: rLo Decrypts correctly
    Ciphertext 7: rLo Decrypts correctly
    Ciphertext 8: rLo Decrypts correctly
    Ciphertext 9: rLo Decrypts correctly
    Ciphertext 10: rLo Decrypts correctly

    rLo All ciphertexts decrypt correctly despite being radically different

    ================================================================================
    CONCLUSION ================================================================================
    The TRNG prefix ensures that:
    1. Every encryption is unique (different 73-byte random prefix)
    2. Initial HMAC state is information-theoretically hidden
    3. Same plaintext raA completely uncorrelated ciphertexts
    4. No two-ciphertext attack is possible without TRNG collision ================================================================================

    --- Synchronet 3.21a-Linux NewsLink 1.2