Chris_M_Thomasson

# Reverse Iteration Fractal Cipher (RIFC) w/ HMAC>Block mode

Aug 19th, 2016
231
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.81 KB | None | 0 0
  1. # Chris M. Thomasson 8/19/2016
  2. # Reverse Iteration Fractal Cipher (RIFC) w/ HMAC
  3.  
  4. #    This program is free software: you can redistribute it and/or modify
  5. #    it under the terms of the GNU General Public License as published by
  6. #    the Free Software Foundation, either version 3 of the License, or
  7. #    (at your option) any later version.
  8. #
  9. #    This program is distributed in the hope that it will be useful,
  10. #    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. #    GNU General Public License for more details.
  13. #
  14. #   You should have received a copy of the GNU General Public License
  15. #   along with this program.  If not, see <http://www.gnu.org/licenses/>.
  16.  
  17.  
  18. import math;
  19. import random;
  20. import hmac;
  21. import copy;
  22.  
  23.  
  24. # Complex Absolute Value
  25. def cabs(z):
  26.     return math.sqrt(z.real**2 + z.imag**2);
  27.  
  28.  
  29. # Complex Argument
  30. def carg(z):
  31.     return math.atan2(z.imag, z.real);
  32.  
  33.  
  34. # Complex Argument Range [0...PI2]
  35. def cargr(z):
  36.     a = math.atan2(z.imag, z.real);
  37.     if (a < 0): a += math.pi * 2;
  38.     return a;
  39.  
  40.  
  41. # Get n from a power
  42. def npow(p):
  43.     return int(math.ceil(math.fabs(p)));
  44.  
  45.  
  46. # Complex Roots
  47. def croots(z, p):
  48.     l = cabs(z);
  49.     s = l**(1.0 / p);
  50.     a = carg(z) / p;
  51.     n = npow(p);
  52.     astep = (math.pi * 2.0) / p;
  53.     result = [];
  54.  
  55.     for i in range(n):
  56.         r = complex(math.cos(a + astep * i) * s,
  57.                     math.sin(a + astep * i) * s);
  58.         result.append(r);
  59.  
  60.     return result;
  61.  
  62.  
  63. # Find Root
  64. def froot(z, r):
  65.     n = 0;
  66.     for i in r:
  67.         d = z - i;
  68.         l = math.sqrt(d.real**2 + d.imag**2);
  69.         if l < 0.000001: return n;
  70.         n = n + 1;
  71.     return -1;
  72.  
  73. # Convert base ten 10 to nits, pad to n
  74. def base_10_to_nits_pad(v, b, n):
  75.     nits = "";
  76.     r = 0;
  77.     for i in range(n):
  78.         d = math.floor(v / b);
  79.         r = v - (d * b);
  80.         nits = nits + str(r);
  81.         v = d;
  82.     nits = nits[::-1];
  83.     return nits;
  84.  
  85. # Convert base ten 10 to nits
  86. def base_10_to_nits(v, b):
  87.     nits = "";
  88.     r = 0;
  89.     while 1:
  90.         d = math.floor(v / b);
  91.         r = v - (d * b);
  92.         nits = nits + str(r);
  93.         v = d;
  94.         if (d == 0): break;
  95.     nits = nits[::-1];
  96.     return nits;
  97.  
  98.  
  99. # Convert nits to base 10
  100. def nits_to_base_10(nits, b):
  101.     p = len(nits) - 1;
  102.     r = 0;
  103.     for nit in nits:
  104.         r = r + int(nit)*b**p;
  105.         p = p - 1;
  106.     return r;
  107.  
  108.  
  109. # Generate n random nits in range [0...(b-1)]
  110. def gen_rand_nits(n, b):
  111.     nits = "";
  112.     for i in range(n):
  113.         nits = nits + str(random.randint(0, b - 1));
  114.     return nits;
  115.  
  116.  
  117.  
  118.  
  119. # RIFC Secret Key
  120. class ct_rifc_skey:
  121.     def __init__(self, z, c, p, r_n, n_n, hmkey):
  122.         self.z = z;
  123.         self.c = copy.copy(c);
  124.         self.p = copy.copy(p);
  125.         self.r_n = r_n;
  126.         self.n_n = n_n;
  127.         self.hmack = copy.copy(hmkey);
  128.  
  129.     def __repr__(self):
  130.         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);
  131.  
  132.     def __str__(self): return self.__repr__();
  133.  
  134.  
  135. class ct_rifc_encrypt:
  136.     def __init__(self, skey):
  137.         self.skey = skey; # mutable reference
  138.  
  139.     def __repr__(self):
  140.         return "(skey:%s)" % (self.skey);
  141.  
  142.     def __str__(self): return self.__repr__();
  143.  
  144.     def process(self, z, c, p, ptxt):
  145.         i = 0;
  146.         for nit in ptxt:
  147.             r = croots(z - c, p);
  148.             z = r[int(nit)];
  149.             print("encrypt_process:z[%s]:(%s):(%s)" % (i, nit, z));
  150.             i = i + 1;
  151.         return z;
  152.  
  153.  
  154.  
  155. class ct_rifc_decrypt:
  156.     def __init__(self, skey):
  157.         self.skey = skey; # mutable reference
  158.  
  159.     def __repr__(self):
  160.         return "(skey:%s)" % (self.skey);
  161.  
  162.     def __str__(self): return self.__repr__();
  163.  
  164.     def process(self, z, c, p, n):
  165.         ptxt = "";
  166.         for i in range(n):
  167.             f = z**p + c;
  168.             r = croots(f - c, p);
  169.             nit = froot(z, r);
  170.             ptxt = ptxt + str(nit);
  171.             print("decrypt_process:z[%s]:(%s):(%s)" % (n - i - 1, nit, z));
  172.             z = f;
  173.             i = i + 1;
  174.         ptxt = ptxt[::-1]; # reverse nits
  175.         return [ptxt, z];
  176.  
  177.  
  178. class ct_rifc_nitblock:
  179.     def __init__(self, z, ptxt, ptxt_nits, ptxt_n_nits, rand_nits):
  180.         self.z = z;
  181.         self.ptxt = ptxt;
  182.         self.ptxt_nits = ptxt_nits;
  183.         self.ptxt_n_nits = ptxt_n_nits;
  184.         self.rand_nits = rand_nits;
  185.  
  186.     def __repr__(self):
  187.         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);
  188.  
  189.     def __str__(self): return self.__repr__();
  190.  
  191.    
  192. def ct_rifc_nitblock_from_number(fskey, n):
  193.     ptxt_nits = base_10_to_nits(n, fskey.p[0]);
  194.     ptxt_n_nits = base_10_to_nits_pad(len(ptxt_nits), fskey.p[1], fskey.n_n);
  195.     rand_nits = gen_rand_nits(fskey.r_n, fskey.p[2]);
  196.     return ct_rifc_nitblock(fskey.z, n, ptxt_nits, ptxt_n_nits, rand_nits);
  197.  
  198.  
  199. class ct_rifc_block:
  200.     def __init__(self, fskey):
  201.         self.fskey = fskey;
  202.  
  203.     def __repr__(self):
  204.         return "(fskey:%s)" % (self.fskey);
  205.  
  206.     def __str__(self): return self.__repr__();
  207.  
  208.     def encrypt(self, nblk):
  209.         fencrypt = ct_rifc_encrypt(self.fskey);
  210.  
  211.         print("\nBlock Encryption Process");
  212.         print("___________________________________________________");
  213.  
  214.         print("nblk:%s" % (nblk));
  215.         print("--------------------------------------");
  216.  
  217.         print("\nplaintext");
  218.         print("--------------------------------------");
  219.         z = self.fskey.z;
  220.         z = fencrypt.process(z, fskey.c[0], fskey.p[0], nblk.ptxt_nits);
  221.  
  222.         print("\nlength of plaintext");
  223.         print("--------------------------------------");
  224.         z = fencrypt.process(z, fskey.c[1], fskey.p[1], nblk.ptxt_n_nits);
  225.  
  226.         print("\nrandom plaintext");
  227.         print("--------------------------------------");
  228.         z = fencrypt.process(z, fskey.c[2], fskey.p[2], nblk.rand_nits);
  229.  
  230.         print("___________________________________________________\n");
  231.  
  232.         cpassert = hmac.new(fskey.hmack.encode());
  233.         cpassert.update(str(z).encode());
  234.         cphash = cpassert.hexdigest();
  235.  
  236.         return [z, cphash];
  237.  
  238.     def decrypt(self, zblk):
  239.         z = zblk[0];
  240.         dcpassert = hmac.new(self.fskey.hmack.encode());
  241.         dcpassert.update(str(z).encode());
  242.         dcphash = dcpassert.hexdigest();
  243.  
  244.         # Detect HMAC level threat...
  245.         if not hmac.compare_digest(zblk[1], dcphash):
  246.             print("\n   ***************< (!! HMAC DATA CORRUPTED FOR BOB !!) >***************\n");
  247.             nblk = ct_rifc_nitblock(z, "0xDEADBEEF", "0xDEADBEEF", "0xDEADBEEF", "0xDEADBEEF");
  248.             return nblk;
  249.  
  250.         fdecrypt = ct_rifc_decrypt(self.fskey);
  251.  
  252.         print("\nBlock Decryption Process");
  253.         print("___________________________________________________");
  254.  
  255.         print("\nrandom plaintext");
  256.         print("--------------------------------------");
  257.         z = fdecrypt.process(z, self.fskey.c[2], self.fskey.p[2], self.fskey.r_n);
  258.         rand_nits = z[0];
  259.  
  260.         print("\nlength of plaintext");
  261.         print("--------------------------------------");
  262.         z = fdecrypt.process(z[1], self.fskey.c[1], self.fskey.p[1], self.fskey.n_n);
  263.         dp_n = nits_to_base_10(z[0], self.fskey.p[1]);
  264.         ptxt_n_nits = z[0];
  265.  
  266.         print("\nplaintext");
  267.         print("--------------------------------------");
  268.         z = fdecrypt.process(z[1], self.fskey.c[0], self.fskey.p[0], dp_n);
  269.         ptxt_nits = z[0];
  270.  
  271.         print("___________________________________________________\n");
  272.  
  273.         nblk = ct_rifc_nitblock(z[1], nits_to_base_10(ptxt_nits, self.fskey.p[0]), ptxt_nits, ptxt_n_nits, rand_nits);
  274.  
  275.         return nblk;
  276.  
  277.  
  278.  
  279.  
  280. # Main Block Cipher Test
  281. fskey = ct_rifc_skey((0+0j), [(-.75+.09j), (-.55-.43j), (.1+.8j)], [3, 4, 2], 4, 3, "hmac_skey_123");
  282. rifc_block = ct_rifc_block(fskey);
  283. print("rifc_block:%s\n\n" % (rifc_block));
  284.  
  285.  
  286. ptxt = 123443210;
  287.  
  288. print("plaintext:%s" % (ptxt));
  289. ptxt_nblk = ct_rifc_nitblock_from_number(fskey, ptxt);
  290.  
  291.  
  292. print("*******************************************************");
  293. cipherpoint = rifc_block.encrypt(ptxt_nblk);
  294.  
  295. print("\ncipherpoint:%s\n" % (cipherpoint));
  296.  
  297.  
  298. # Eve can try to mess with the cipherpoint[0], but HMAC to the rescue!
  299. cipherpoint[0] = cipherpoint[0] + (.00000000+.000000000j);
  300. dp_ptxt_nblk = rifc_block.decrypt(cipherpoint);
  301.  
  302.  
  303. print("dp_ptxt_nblk:%s\n\n" % (dp_ptxt_nblk));
  304. print("*******************************************************");
  305.  
  306.  
  307. print("\n\n___________________________________________________");
  308. print("decrypted plaintext:%s" % (dp_ptxt_nblk.ptxt));
  309.  
  310.  
  311. if (ptxt != dp_ptxt_nblk.ptxt):
  312.     print("Plaintext Corrupted, adjust secret key or block length params and try again.");
Advertisement
Add Comment
Please, Sign In to add comment