# Chris M. Thomasson 8/24/2016 # Funny Fractal Encryption pre-alpha (0.0.0.0) import math; import random; import hmac; # Some Conversion Utilities #____________________________________________________________ def ct_bytes_to_hex(origin, offset): hex = ""; n = len(origin); t = "0123456789ABCDEF"; for i in range(offset, n): c = ord(origin[i]); nibl = c & 0x0F; nibh = (c & 0xF0) >> 4; hex = hex + t[nibh]; hex = hex + t[nibl]; hex = hex + " "; if (not ((i + 1) % 16)): hex = hex + "\r\n"; return hex; def ct_hex_to_bytes(origin, offset): bytes = ""; n = len(origin); t = "0123456789ABCDEF"; i = offset + 1; while (i < n): nibh = 0; nibl = 0; try: nibh = t.index(origin[i - 1]); nibl = t.index(origin[i]); except ValueError: i = i + 1; continue; if (nibh > -1 and nibl > -1): c = nibh * 16 + nibl; bytes = bytes + chr(c); i = i + 2; return bytes; # Some Math Utilities #____________________________________________________________ # Cantor pair def ct_cpair(n): return int(((n[0] + n[1]) * ((n[0] + n[1]) + 1)) / 2) + n[1]; def ct_cpairi(n): n0 = 8 * n + 1; x = int((math.sqrt(n0) - 1) / 2); y = n - int(((x + 1) * x) / 2); return (x - 1, y); # Complex Absolute Value def ct_cabs(z): return math.sqrt(z.real**2 + z.imag**2); def ct_range_number(n): while (n > 10000000000): n /= 1723.13327; return n; def ct_obtain_number_fwd(n): rn = math.modf(ct_range_number(math.fabs(n))); v0 = rn[0] * 10000000000; rn = math.modf(v0); v1 = rn[0] * 10000000000; v2 = int(math.fabs(math.floor(v1))); return v2; def ct_ffe_gen_rand_axes(dims): d = dims[1] - dims[0]; return (-random.random() * d, random.random() * d, -random.random() * d, random.random() * d); def ct_ffe_axes_combine(a0, a1): return (-(math.fabs(a0[0] * a1[0] * 7.13263) % 3.0), (math.fabs(a0[1] * a1[1] * 7.13263) % 3.0), -(math.fabs(a0[2] * a1[2] * 7.13263) % 3.0), (math.fabs(a0[3] * a1[3] * 7.13263) % 3.0)); def ct_ffe_gen_rand_bytes(n): rtxt = ""; for i in range(n): rtxt = rtxt + chr(random.randint(0, 255)); return rtxt; # Funny Fractal Encryption, low-level #____________________________________________________________ # Forward Iterate def ct_ffe_fwd_iterate(z, c, p, s, e, n): for i in range(n): if (z.real == 0 and z.imag == 0): z += (0.00000001+0.0000000013); f = i % 2; z = z**p[f] + c[f]; z = z * s; d = ct_cabs(z); if (d > e): return (z, i); return (z, n); def ct_ffe_cipher(a, c, p, s, e, n, ptxt, encrypt): ctxt = ""; n = len(ptxt); dims = math.ceil(math.sqrt(n)); pn = int(math.ceil(math.fabs(p[0]))); xstep = (a[1] - a[0]) / dims; ystep = (a[3] - a[2]) / dims; for i in range(n): x = i % dims; y = int(i / dims); z = complex(a[0] + x * xstep, a[3] - y * ystep); fwd = ct_ffe_fwd_iterate(z, c, p, s, e, n); fwd_mod_0 = ct_obtain_number_fwd(fwd[0].real * (fwd[1] + 1)); fwd_mod_1 = ct_obtain_number_fwd(fwd[0].imag * (fwd[1] + 1)); fwd_mod = ct_cpair((fwd_mod_0, fwd_mod_1)) * ((fwd_mod_0 + fwd_mod_1) % 65536); cmod = fwd_mod % 256; pchr = ord(ptxt[i]); if (encrypt): cchr = (pchr + cmod) % 256; else: cchr = pchr - cmod; if (cchr < 0): cchr = int(math.fabs((pchr + 256) - cmod)); ctxt = ctxt + chr(cchr); return ctxt; # Random Encryption #____________________________________________________________ def ct_rand_encrypt(ptxt): n = len(ptxt); ctxt = ""; rtxt = ct_ffe_gen_rand_bytes(n); for i in range(n): pchr = ord(ptxt[i]); cmod = ord(rtxt[i]); cchr = (pchr + cmod) % 256; ctxt = ctxt + chr(cchr); return ctxt + rtxt; def ct_rand_decrypt(ctxt): n = int(len(ctxt) / 2); ptxt = ""; for i in range(n): pchr = ord(ctxt[i]); cmod = ord(ctxt[i + n]); cchr = pchr - cmod; if (cchr < 0): cchr = int(math.fabs((pchr + 256) - cmod)); ptxt = ptxt + chr(cchr); return ptxt; # Funny Fractal Encryption, high-level #____________________________________________________________ def ct_ffe_encrypt(axes, adims, hmack, c, p, s, e, n, ptxt): ffe_raxes = ct_ffe_gen_rand_axes(adims); ffe_axes = ct_ffe_axes_combine(axes, ffe_raxes); rand_ctxt = ct_rand_encrypt(ptxt); ffe_ctxt = ct_ffe_cipher(ffe_axes, c, p, s, e, n, rand_ctxt, True); ffe_hmac = hmac.new(hmack.encode()); for i in ffe_ctxt: ffe_hmac.update(str(i).encode()); ffe_hmac_hex = ffe_hmac.hexdigest(); return [ffe_raxes, ffe_hmac_hex, ffe_ctxt]; def ct_ffe_decrypt(axes, hmack, c, p, s, e, n, ctxt): ffe_hmac = hmac.new(hmack.encode()); for i in ctxt[2]: ffe_hmac.update(str(i).encode()); ffe_hmac_hex = ffe_hmac.hexdigest(); if (not hmac.compare_digest(ctxt[1], ffe_hmac_hex)): print("\n\n************** HMAC VIOLATION ***************\n\n"); return "Bob is 0xDEADBEEF!"; ffe_axes = ct_ffe_axes_combine(axes, ctxt[0]); ffe_dtxt = ct_ffe_cipher(ffe_axes, c, p, s, e, n, ctxt[2], False); ptxt = ct_rand_decrypt(ffe_dtxt); return ptxt; # The Main Program #____________________________________________________________ print("Funny Fractal Encryption, pre-alpha 0.0.0.0"); print("by Chris M. Thomasson"); print("==========================================================\n\n"); # The Secret Key axes = (-0.75, .09, -.5, .3); adims = (-1.25, 1.25); hmack = "hmac_secret_key"; c = ((-.75+.09j), (.0 + 1j)); p = (2.13, 3.14); s = 1.0; e = 2.0; n = 103; # The Plaintext ptxt = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; #ptxt = "Hello there, welcome to Funny Fractal Encryption!\nBy: Chris M. Thomasson"; print("\nOriginal Plaintext, len:%s" % (len(ptxt))); print("________________________________________"); print("%s" % (ptxt)); print("----------------------------------------"); print("%s" % (ct_bytes_to_hex(ptxt, 0))); # Encryption ctxt = ct_ffe_encrypt(axes, adims, hmack, c, p, s, e, n, ptxt); print("\n\nCiphertext:"); print("________________________________________"); print("(%s, %s)\n(%s, %s)" % (ctxt[0][0], ctxt[0][1], ctxt[0][2], ctxt[0][3])); print("----------------------------------------"); print("%s" % (ctxt[1])); print("----------------------------------------"); print("%s" % (ct_bytes_to_hex(ctxt[2], 0))); # Decryption dtxt = ct_ffe_decrypt(axes, hmack, c, p, s, e, n, ctxt); print("\nDecrypted Plaintext, len:%s" % (len(dtxt))); print("________________________________________"); try: print("%s" % (dtxt)); except: print(""); print("----------------------------------------"); print("%s" % (ct_bytes_to_hex(dtxt, 0))); if (ptxt != dtxt): print("Data Corrupted!"); #eof