Advertisement
Chris_M_Thomasson

Reverse Iteration Fractal Cipher (RIFC), pre-alpha v:0.0.0

Aug 20th, 2016
234
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 13.49 KB | None | 0 0
  1. # Chris M. Thomasson 8/20/2016
  2. # Reverse Iteration Fractal Cipher (RIFC)
  3. # Pre-Alpha Version: 0.0.0
  4.  
  5. #    This program is free software: you can redistribute it and/or modify
  6. #    it under the terms of the GNU General Public License as published by
  7. #    the Free Software Foundation, either version 3 of the License, or
  8. #    (at your option) any later version.
  9. #
  10. #    This program is distributed in the hope that it will be useful,
  11. #    but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. #    GNU General Public License for more details.
  14. #
  15. #   You should have received a copy of the GNU General Public License
  16. #   along with this program.  If not, see <http://www.gnu.org/licenses/>.
  17.  
  18.  
  19. import math;
  20. import random;
  21. import hmac;
  22. import copy;
  23. import os;
  24.  
  25.  
  26.  
  27. # RIFC General Complex Math Utilities
  28. #____________________________________________________________
  29.  
  30. # Complex Absolute Value
  31. def ct_cabs(z):
  32.     return math.sqrt(z.real**2 + z.imag**2);
  33.  
  34.  
  35. # Complex Argument
  36. def ct_carg(z):
  37.     return math.atan2(z.imag, z.real);
  38.  
  39.  
  40. # Complex Argument Range [0...PI2]
  41. def ct_cargr(z):
  42.     a = math.atan2(z.imag, z.real);
  43.     if (a < 0): a += math.pi * 2;
  44.     return a;
  45.  
  46.  
  47. # Get n from a power
  48. def ct_npow(p):
  49.     return int(math.ceil(math.fabs(p)));
  50.  
  51.  
  52. # Complex Roots
  53. def ct_croots(z, p):
  54.     l = ct_cabs(z);
  55.     s = l**(1.0 / p);
  56.     a = ct_carg(z) / p;
  57.     n = ct_npow(p);
  58.     astep = (math.pi * 2.0) / p;
  59.     result = [];
  60.  
  61.     for i in range(n):
  62.         r = complex(math.cos(a + astep * i) * s,
  63.                     math.sin(a + astep * i) * s);
  64.         result.append(r);
  65.  
  66.     return result;
  67.  
  68.  
  69. # Find Root
  70. def ct_froot(z, r):
  71.     n = 0;
  72.     for i in r:
  73.         d = z - i;
  74.         l = math.sqrt(d.real**2 + d.imag**2);
  75.         if l < 0.000001: return n;
  76.         n = n + 1;
  77.     return -1;
  78.  
  79.  
  80.  
  81. # RIFC Number Conversions and Nit Utilities
  82. #____________________________________________________________
  83.  
  84. # Convert base ten 10 to nits, pad to n
  85. def ct_base_10_to_nits_pad(v, b, n):
  86.     nits = "";
  87.     r = 0;
  88.     for i in range(n):
  89.         d = math.floor(v / b);
  90.         r = v - (d * b);
  91.         nits = nits + str(r);
  92.         v = d;
  93.     nits = nits[::-1];
  94.     return nits;
  95.  
  96. # Convert base ten 10 to nits
  97. def ct_base_10_to_nits(v, b):
  98.     nits = "";
  99.     r = 0;
  100.     while 1:
  101.         d = math.floor(v / b);
  102.         r = v - (d * b);
  103.         nits = nits + str(r);
  104.         v = d;
  105.         if (d == 0): break;
  106.     nits = nits[::-1];
  107.     return nits;
  108.  
  109.  
  110. # Convert nits to base 10
  111. def ct_nits_to_base_10(nits, b):
  112.     p = len(nits) - 1;
  113.     r = 0;
  114.     for nit in nits:
  115.         r = r + int(nit)*b**p;
  116.         p = p - 1;
  117.     return r;
  118.  
  119.  
  120. # Generate n random nits in range [0...(b-1)]
  121. def ct_gen_rand_nits(n, b):
  122.     nits = "";
  123.     for i in range(n):
  124.         nits = nits + str(random.randint(0, b - 1));
  125.     return nits;
  126.  
  127. def ct_number_from_ptxt_bytes_n(ptxt, o, n):
  128.     r = 0;
  129.     imax = len(ptxt);
  130.     p = 0;
  131.     for i in range(o, n + 1):
  132.         b = ord(ptxt[i]);
  133.         a = b * 256**p;
  134.         r = r + a;
  135.         #print("ni[%s]:(b:%s, r:%s)" % (i, b, r));
  136.         p = p + 1;
  137.     return r;
  138.  
  139. def ct_ptxt_bytes_from_number(n):
  140.     r = 0;
  141.     ni = 0;
  142.     ptxt = "";
  143.     while 1:
  144.         d = math.floor(n / 256);
  145.         r = n - (d * 256);
  146.         ptxt = ptxt + chr(r);
  147.         n = d;
  148.         if (d == 0): break;
  149.     return ptxt;
  150.  
  151.  
  152.  
  153.  
  154. # RIFC Secret Key Class
  155. #____________________________________________________________
  156. class ct_rifc_skey:
  157.     def __init__(self, z, c, p, r_n, n_n, hmkey):
  158.         self.z = z;
  159.         self.c = copy.copy(c);
  160.         self.p = copy.copy(p);
  161.         self.r_n = r_n;
  162.         self.n_n = n_n;
  163.         self.hmack = copy.copy(hmkey);
  164.  
  165.     def __repr__(self):
  166.         return "(z:%s, c:%s, p:%s, r_n:%s, n_n:%s, hmack:%s)" % (self.z, self.c, self.p, self.r_n, self.n_n, self.hmack);
  167.  
  168.     def __str__(self): return self.__repr__();
  169.  
  170.  
  171. # RIFC Native Encrypt Class
  172. #____________________________________________________________
  173. class ct_rifc_encrypt:
  174.     def __init__(self, skey):
  175.         self.skey = skey; # mutable reference
  176.  
  177.     def __repr__(self):
  178.         return "(skey:%s)" % (self.skey);
  179.  
  180.     def __str__(self): return self.__repr__();
  181.  
  182.     def process(self, z, c, p, ptxt):
  183.         i = 0;
  184.         for nit in ptxt:
  185.             r = ct_croots(z - c, p);
  186.             z = r[int(nit)];
  187.             #print("encrypt_process:z[%s]:(%s):(%s)" % (i, nit, z));
  188.             i = i + 1;
  189.         return z;
  190.  
  191.  
  192. # RIFC Native Decrypt Class
  193. #____________________________________________________________
  194. class ct_rifc_decrypt:
  195.     def __init__(self, skey):
  196.         self.skey = skey; # mutable reference
  197.  
  198.     def __repr__(self):
  199.         return "(skey:%s)" % (self.skey);
  200.  
  201.     def __str__(self): return self.__repr__();
  202.  
  203.     def process(self, z, c, p, n):
  204.         ptxt = "";
  205.         for i in range(n):
  206.             f = z**p + c;
  207.             r = ct_croots(f - c, p);
  208.             nit = ct_froot(z, r);
  209.             ptxt = ptxt + str(nit);
  210.             #print("decrypt_process:z[%s]:(%s):(%s)" % (n - i - 1, nit, z));
  211.             z = f;
  212.             i = i + 1;
  213.         ptxt = ptxt[::-1]; # reverse nits
  214.         return [ptxt, z];
  215.  
  216.  
  217. # RIFC Block Compatible Nit Class
  218. #____________________________________________________________
  219. class ct_rifc_nitblock:
  220.     def __init__(self, z, ptxt, ptxt_nits, ptxt_n_nits, rand_nits):
  221.         self.z = z;
  222.         self.ptxt = ptxt;
  223.         self.ptxt_nits = ptxt_nits;
  224.         self.ptxt_n_nits = ptxt_n_nits;
  225.         self.rand_nits = rand_nits;
  226.  
  227.     def __repr__(self):
  228.         return "(z:%s, ptxt:%s, ptxt_nits:%s, ptxt_n_nits:%s, rand_nits:%s)" % (self.z, self.ptxt, self.ptxt_nits, self.ptxt_n_nits, self.rand_nits);
  229.  
  230.     def __str__(self): return self.__repr__();
  231.  
  232.    
  233. def ct_rifc_nitblock_from_number(fskey, z, n):
  234.     ptxt_nits = ct_base_10_to_nits(n, ct_npow(fskey.p[0]));
  235.     ptxt_n_nits = ct_base_10_to_nits_pad(len(ptxt_nits), ct_npow(fskey.p[1]), fskey.n_n);
  236.     rand_nits = ct_gen_rand_nits(fskey.r_n, ct_npow(fskey.p[2]));
  237.     return ct_rifc_nitblock(z, n, ptxt_nits, ptxt_n_nits, rand_nits);
  238.  
  239.  
  240.  
  241. # RIFC Block Cipher Class
  242. #____________________________________________________________
  243. class ct_rifc_block:
  244.     def __init__(self, fskey):
  245.         self.fskey = fskey;
  246.  
  247.     def __repr__(self):
  248.         return "(fskey:%s)" % (self.fskey);
  249.  
  250.     def __str__(self): return self.__repr__();
  251.  
  252.     def encrypt(self, nblk):
  253.         fencrypt = ct_rifc_encrypt(self.fskey);
  254.  
  255.         #print("\nBlock Encryption Process");
  256.         #print("___________________________________________________");
  257.  
  258.         #print("nblk:%s" % (nblk));
  259.         #print("--------------------------------------");
  260.  
  261.         #print("\nplaintext");
  262.         #print("--------------------------------------");
  263.         z = nblk.z;
  264.         z = fencrypt.process(z, fskey.c[0], fskey.p[0], nblk.ptxt_nits);
  265.  
  266.         #print("\nlength of plaintext");
  267.         #print("--------------------------------------");
  268.         z = fencrypt.process(z, fskey.c[1], fskey.p[1], nblk.ptxt_n_nits);
  269.  
  270.         #print("\nrandom plaintext");
  271.         #print("--------------------------------------");
  272.         z = fencrypt.process(z, fskey.c[2], fskey.p[2], nblk.rand_nits);
  273.  
  274.         #print("___________________________________________________\n");
  275.  
  276.         #cpassert = hmac.new(fskey.hmack.encode());
  277.         #cpassert.update(str(z).encode());
  278.         #cphash = cpassert.hexdigest();
  279.  
  280.         return z;
  281.  
  282.     def decrypt(self, z):
  283.  
  284.         #dcpassert = hmac.new(self.fskey.hmack.encode());
  285.         #dcpassert.update(str(z).encode());
  286.         #dcphash = dcpassert.hexdigest();
  287.  
  288.         # Detect HMAC level threat...
  289.         #if not hmac.compare_digest(zblk[1], dcphash):
  290.  
  291.         fdecrypt = ct_rifc_decrypt(self.fskey);
  292.  
  293.         #print("\nBlock Decryption Process");
  294.         #print("___________________________________________________");
  295.  
  296.         #print("\nrandom plaintext");
  297.         #print("--------------------------------------");
  298.         z = fdecrypt.process(z, self.fskey.c[2], self.fskey.p[2], self.fskey.r_n);
  299.         rand_nits = z[0];
  300.  
  301.         #print("\nlength of plaintext");
  302.         #print("--------------------------------------");
  303.         z = fdecrypt.process(z[1], self.fskey.c[1], self.fskey.p[1], self.fskey.n_n);
  304.         dp_n = ct_nits_to_base_10(z[0], ct_npow(self.fskey.p[1]));
  305.         ptxt_n_nits = z[0];
  306.  
  307.         #print("\nplaintext");
  308.         #print("--------------------------------------");
  309.         z = fdecrypt.process(z[1], self.fskey.c[0], self.fskey.p[0], dp_n);
  310.         ptxt_nits = z[0];
  311.  
  312.         #print("___________________________________________________\n");
  313.  
  314.         nblk = ct_rifc_nitblock(z[1], ct_nits_to_base_10(ptxt_nits, ct_npow(self.fskey.p[0])), ptxt_nits, ptxt_n_nits, rand_nits);
  315.  
  316.         return nblk;
  317.  
  318.  
  319.  
  320. # RIFC Ciphertext Class
  321. #____________________________________________________________
  322. class ct_rifc_ciphertext:
  323.     def __init__(self, hmhash, ctxt):
  324.         self.hmhash = hmhash;
  325.         self.ctxt = ctxt;
  326.  
  327.     def __repr__(self):
  328.         s = ("(%s)\n" % (self.hmhash));
  329.         for cp in self.ctxt: s = s + ("%s\n" % (cp));
  330.         return s;
  331.  
  332.     def __str__(self): return self.__repr__();
  333.  
  334.     def hmack_assert(self, hmhash_compare):
  335.         return hmac.compare_digest(self.hmhash, hmhash_compare);
  336.  
  337.  
  338.  
  339. # Main RIFC Cipher Class
  340. #____________________________________________________________
  341. class ct_rifc:
  342.     def __init__(self, fskey):
  343.         self.fskey = fskey;
  344.  
  345.     def __repr__(self):
  346.         return "(fskey:%s)" % (self.fskey);
  347.  
  348.     def __str__(self): return self.__repr__();
  349.  
  350.     def encrypt(self, ptxt):
  351.         i = 0;
  352.         n = len(ptxt);
  353.         rnmax = 2;
  354.         nsum = 0;
  355.  
  356.         ciphertext = [];
  357.         hmassert = hmac.new(self.fskey.hmack.encode());
  358.  
  359.         rifc_block = ct_rifc_block(self.fskey);
  360.         z = self.fskey.z;
  361.  
  362.         while (i < n):
  363.             r = random.randint(0, rnmax);
  364.             o = i;
  365.             s = o + r;
  366.             if (s >= n): s = n - 1;
  367.             ptn = ct_number_from_ptxt_bytes_n(ptxt, o, s);
  368.             nblk = ct_rifc_nitblock_from_number(fskey, z, ptn);
  369.             cipherpoint = rifc_block.encrypt(nblk);
  370.             hmassert.update(str(cipherpoint).encode());
  371.             ciphertext.append(cipherpoint);
  372.             z = cipherpoint;
  373.             i = s + 1;
  374.  
  375.         hmhash = hmassert.hexdigest();
  376.  
  377.         return ct_rifc_ciphertext(hmhash, ciphertext);
  378.  
  379.     def decrypt(self, ctxt):
  380.         ptxt = "";
  381.         rifc_block = ct_rifc_block(self.fskey);
  382.  
  383.         hmassert = hmac.new(self.fskey.hmack.encode());
  384.  
  385.         # check HMAC
  386.         for cp in ctxt.ctxt:
  387.             hmassert.update(str(cp).encode());
  388.  
  389.         hmhash = hmassert.hexdigest();
  390.  
  391.         if (not ctxt.hmack_assert(hmhash)):
  392.             print("\n\n************** !! HMAC VOILATION !! ****************\n\n");
  393.             return "Bob is 0xDEADBEEF!!!";
  394.  
  395.         for cp in ctxt.ctxt:
  396.             nblk = rifc_block.decrypt(cp);
  397.             ptxt = ptxt + ct_ptxt_bytes_from_number(nblk.ptxt);
  398.  
  399.         return ptxt;
  400.  
  401.  
  402.  
  403. # Main RIFC Cipher Test
  404. #____________________________________________________________
  405.  
  406.  
  407. # For future use in a ciphertext plotter
  408. def ct_rifc_plot_gen_rand_ptxt(n):
  409.     ptxt = "";
  410.     for i in range(n):
  411.         a = random.randint(32, 126);
  412.         ptxt = ptxt + chr(a);
  413.     return ptxt;
  414.  
  415. # For future use in a ciphertext plotter
  416. def ct_rifc_plot_rand_test(rifc, n):
  417.     for i in range(n):
  418.         ptxt = ct_rifc_plot_gen_rand_ptxt(random.randint(8, 128));
  419.         ciphertext = rifc.encrypt(ptxt);
  420.         dptxt = rifc.decrypt(ciphertext);
  421.         if (ptxt != dptxt):
  422.             print("SHIT ************************ FAILED DECRYPT ********************* SHIT");
  423.             return False;
  424.         print("i:%s\r" % (i), end="");
  425.     print("\r\n\n");
  426.     return True;
  427.  
  428.  
  429.  
  430. print("Chris M. Thomasson 8/20/2016");
  431. print("Reverse Iteration Fractal Cipher (RIFC)");
  432. print("Pre-Alpha Version: 0.0.0");
  433. print("In-Memory Byte Level Version");
  434. print("File based version is on its way");
  435. print("=======================================================\n\n\n");
  436.  
  437. fskey = ct_rifc_skey((-0.74543+0.11301j), [(.677+.2j), (-.21-.751j), (-.0505+.64j)], [4, 3, 5], 2, 3, "hmac_skey_123");
  438. rifc = ct_rifc(fskey);
  439.  
  440. print("rifc:%s\n\n" % (rifc));
  441.  
  442.  
  443. #original_plaintext = "My name is Chris M. Thomasson,\nthis was encrypted using\nmy cipher called (RIFC)!";
  444. original_plaintext = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
  445.  
  446.  
  447. #ct_rifc_plot_rand_test(rifc, 20000);
  448.  
  449.  
  450. print("original_plaintext, length: %s" % (len(original_plaintext)));
  451. print("______________________________________________");
  452. print(original_plaintext);
  453. print("______________________________________________");
  454.  
  455. ciphertext = rifc.encrypt(original_plaintext);
  456. print("\n\nciphertext, length %s" % (len(ciphertext.ctxt)));
  457. print("______________________________________________");
  458. print(ciphertext);
  459. print("______________________________________________\n\n");
  460.  
  461.  
  462. # Eve can try to mess with the ciphertext,
  463. # but Bob will be alerted!  :^D
  464. ciphertext.ctxt[0] = ciphertext.ctxt[0] + (.000000000-.000000000j);
  465.  
  466. decrypted_plaintext = rifc.decrypt(ciphertext);
  467. print("decrypted_plaintext, length: %s" % (len(decrypted_plaintext)));
  468. print("______________________________________________");
  469. print(decrypted_plaintext);
  470. print("______________________________________________\n\n");
  471.  
  472.  
  473. # eof
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement