Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Chris M. Thomasson 8/19/2016
- # Reverse Iteration Fractal Cipher (RIFC) w/ HMAC
- # This program is free software: you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation, either version 3 of the License, or
- # (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
- import math;
- import random;
- import hmac;
- import copy;
- # Complex Absolute Value
- def cabs(z):
- return math.sqrt(z.real**2 + z.imag**2);
- # Complex Argument
- def carg(z):
- return math.atan2(z.imag, z.real);
- # Complex Argument Range [0...PI2]
- def cargr(z):
- a = math.atan2(z.imag, z.real);
- if (a < 0): a += math.pi * 2;
- return a;
- # Get n from a power
- def npow(p):
- return int(math.ceil(math.fabs(p)));
- # Complex Roots
- def croots(z, p):
- l = cabs(z);
- s = l**(1.0 / p);
- a = carg(z) / p;
- n = npow(p);
- astep = (math.pi * 2.0) / p;
- result = [];
- for i in range(n):
- r = complex(math.cos(a + astep * i) * s,
- math.sin(a + astep * i) * s);
- result.append(r);
- return result;
- # Find Root
- def froot(z, r):
- n = 0;
- for i in r:
- d = z - i;
- l = math.sqrt(d.real**2 + d.imag**2);
- if l < 0.000001: return n;
- n = n + 1;
- return -1;
- # Convert base ten 10 to nits, pad to n
- def base_10_to_nits_pad(v, b, n):
- nits = "";
- r = 0;
- for i in range(n):
- d = math.floor(v / b);
- r = v - (d * b);
- nits = nits + str(r);
- v = d;
- nits = nits[::-1];
- return nits;
- # Convert base ten 10 to nits
- def base_10_to_nits(v, b):
- nits = "";
- r = 0;
- while 1:
- d = math.floor(v / b);
- r = v - (d * b);
- nits = nits + str(r);
- v = d;
- if (d == 0): break;
- nits = nits[::-1];
- return nits;
- # Convert nits to base 10
- def nits_to_base_10(nits, b):
- p = len(nits) - 1;
- r = 0;
- for nit in nits:
- r = r + int(nit)*b**p;
- p = p - 1;
- return r;
- # Generate n random nits in range [0...(b-1)]
- def gen_rand_nits(n, b):
- nits = "";
- for i in range(n):
- nits = nits + str(random.randint(0, b - 1));
- return nits;
- # RIFC Secret Key
- class ct_rifc_skey:
- def __init__(self, z, c, p, r_n, n_n, hmkey):
- self.z = z;
- self.c = copy.copy(c);
- self.p = copy.copy(p);
- self.r_n = r_n;
- self.n_n = n_n;
- self.hmack = copy.copy(hmkey);
- def __repr__(self):
- 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);
- def __str__(self): return self.__repr__();
- class ct_rifc_encrypt:
- def __init__(self, skey):
- self.skey = skey; # mutable reference
- def __repr__(self):
- return "(skey:%s)" % (self.skey);
- def __str__(self): return self.__repr__();
- def process(self, z, c, p, ptxt):
- i = 0;
- for nit in ptxt:
- r = croots(z - c, p);
- z = r[int(nit)];
- print("encrypt_process:z[%s]:(%s):(%s)" % (i, nit, z));
- i = i + 1;
- return z;
- class ct_rifc_decrypt:
- def __init__(self, skey):
- self.skey = skey; # mutable reference
- def __repr__(self):
- return "(skey:%s)" % (self.skey);
- def __str__(self): return self.__repr__();
- def process(self, z, c, p, n):
- ptxt = "";
- for i in range(n):
- f = z**p + c;
- r = croots(f - c, p);
- nit = froot(z, r);
- ptxt = ptxt + str(nit);
- print("decrypt_process:z[%s]:(%s):(%s)" % (n - i - 1, nit, z));
- z = f;
- i = i + 1;
- ptxt = ptxt[::-1]; # reverse nits
- return [ptxt, z];
- class ct_rifc_nitblock:
- def __init__(self, z, ptxt, ptxt_nits, ptxt_n_nits, rand_nits):
- self.z = z;
- self.ptxt = ptxt;
- self.ptxt_nits = ptxt_nits;
- self.ptxt_n_nits = ptxt_n_nits;
- self.rand_nits = rand_nits;
- def __repr__(self):
- 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);
- def __str__(self): return self.__repr__();
- def ct_rifc_nitblock_from_number(fskey, n):
- ptxt_nits = base_10_to_nits(n, fskey.p[0]);
- ptxt_n_nits = base_10_to_nits_pad(len(ptxt_nits), fskey.p[1], fskey.n_n);
- rand_nits = gen_rand_nits(fskey.r_n, fskey.p[2]);
- return ct_rifc_nitblock(fskey.z, n, ptxt_nits, ptxt_n_nits, rand_nits);
- class ct_rifc_block:
- def __init__(self, fskey):
- self.fskey = fskey;
- def __repr__(self):
- return "(fskey:%s)" % (self.fskey);
- def __str__(self): return self.__repr__();
- def encrypt(self, nblk):
- fencrypt = ct_rifc_encrypt(self.fskey);
- print("\nBlock Encryption Process");
- print("___________________________________________________");
- print("nblk:%s" % (nblk));
- print("--------------------------------------");
- print("\nplaintext");
- print("--------------------------------------");
- z = self.fskey.z;
- z = fencrypt.process(z, fskey.c[0], fskey.p[0], nblk.ptxt_nits);
- print("\nlength of plaintext");
- print("--------------------------------------");
- z = fencrypt.process(z, fskey.c[1], fskey.p[1], nblk.ptxt_n_nits);
- print("\nrandom plaintext");
- print("--------------------------------------");
- z = fencrypt.process(z, fskey.c[2], fskey.p[2], nblk.rand_nits);
- print("___________________________________________________\n");
- cpassert = hmac.new(fskey.hmack.encode());
- cpassert.update(str(z).encode());
- cphash = cpassert.hexdigest();
- return [z, cphash];
- def decrypt(self, zblk):
- z = zblk[0];
- dcpassert = hmac.new(self.fskey.hmack.encode());
- dcpassert.update(str(z).encode());
- dcphash = dcpassert.hexdigest();
- # Detect HMAC level threat...
- if not hmac.compare_digest(zblk[1], dcphash):
- print("\n ***************< (!! HMAC DATA CORRUPTED FOR BOB !!) >***************\n");
- nblk = ct_rifc_nitblock(z, "0xDEADBEEF", "0xDEADBEEF", "0xDEADBEEF", "0xDEADBEEF");
- return nblk;
- fdecrypt = ct_rifc_decrypt(self.fskey);
- print("\nBlock Decryption Process");
- print("___________________________________________________");
- print("\nrandom plaintext");
- print("--------------------------------------");
- z = fdecrypt.process(z, self.fskey.c[2], self.fskey.p[2], self.fskey.r_n);
- rand_nits = z[0];
- print("\nlength of plaintext");
- print("--------------------------------------");
- z = fdecrypt.process(z[1], self.fskey.c[1], self.fskey.p[1], self.fskey.n_n);
- dp_n = nits_to_base_10(z[0], self.fskey.p[1]);
- ptxt_n_nits = z[0];
- print("\nplaintext");
- print("--------------------------------------");
- z = fdecrypt.process(z[1], self.fskey.c[0], self.fskey.p[0], dp_n);
- ptxt_nits = z[0];
- print("___________________________________________________\n");
- nblk = ct_rifc_nitblock(z[1], nits_to_base_10(ptxt_nits, self.fskey.p[0]), ptxt_nits, ptxt_n_nits, rand_nits);
- return nblk;
- # Main Block Cipher Test
- fskey = ct_rifc_skey((0+0j), [(-.75+.09j), (-.55-.43j), (.1+.8j)], [3, 4, 2], 4, 3, "hmac_skey_123");
- rifc_block = ct_rifc_block(fskey);
- print("rifc_block:%s\n\n" % (rifc_block));
- ptxt = 123443210;
- print("plaintext:%s" % (ptxt));
- ptxt_nblk = ct_rifc_nitblock_from_number(fskey, ptxt);
- print("*******************************************************");
- cipherpoint = rifc_block.encrypt(ptxt_nblk);
- print("\ncipherpoint:%s\n" % (cipherpoint));
- # Eve can try to mess with the cipherpoint[0], but HMAC to the rescue!
- cipherpoint[0] = cipherpoint[0] + (.00000000+.000000000j);
- dp_ptxt_nblk = rifc_block.decrypt(cipherpoint);
- print("dp_ptxt_nblk:%s\n\n" % (dp_ptxt_nblk));
- print("*******************************************************");
- print("\n\n___________________________________________________");
- print("decrypted plaintext:%s" % (dp_ptxt_nblk.ptxt));
- if (ptxt != dp_ptxt_nblk.ptxt):
- print("Plaintext Corrupted, adjust secret key or block length params and try again.");
Advertisement
Add Comment
Please, Sign In to add comment