Skip to content

Instantly share code, notes, and snippets.

@benjojo
Created January 5, 2014 14:55
Show Gist options
  • Save benjojo/8269148 to your computer and use it in GitHub Desktop.
Save benjojo/8269148 to your computer and use it in GitHub Desktop.
#!/usr/bin/python
# Python 3.0+ and 2.5+
# fractal encryption
import os
import hashlib
import math
import random
import sys
import pickle
import argparse
random.seed()
MAX_KEYSIZE = 10000000.0
XRANGE = 2.5
YRANGE = -2.0
NKEYS = 100
KEY_LEN = 100
STEPS = 100
try:
from functools import reduce
except:
pass
def open_file(name, mode = "r"):
return [file(name, mode), os.stat(name).st_size]
def integer_hash(string):
return int(hashlib.md5(string).hexdigest(), 16)
def split_hash(num):
return int(num % MAX_KEYSIZE)
def make_keys(count, length, f):
res = []
for i in range(0, count):
rpos = random.randint(0, f[1] - length)
res.append([rpos, length, split_hash(integer_hash(read_chunk(f[0], rpos, length)))])
print "generated %i secret key index hashes" % count
return res
def load_key(key, f):
return [key[0], key[1], split_hash(integer_hash(read_chunk(f[0], key[0], key[1])))]
def read_chunk(f, offset, size):
f.seek(offset)
return f.read(size)
keypos = 0
def mandelbrot(keys, a):
global keypos
keypos = keypos + 1
if(keypos > NKEYS-1):
keypos = 0
value = reduce(lambda z, _: z*z + a, range(10 + (keys[keypos][2] % 40)), 0)
if(value.real < 2 and value.real > -2):
return abs(value)
else:
return 0
def step(start, step, iterations): return (start + (i * step) for i in range(iterations))
def make_values(keys, xr = [-2.0, 2.5], yr = [1.0, -2.0], xitr = 1000, yitr = 1000):
valid = bytearray()
rows = (((mandelbrot(keys, complex(x, y)))
for x in step(xr[0], xr[1]/xitr, xitr))
for y in step(yr[0], yr[1]/yitr, yitr))
for row in rows:
for value in row:
if( value < 2 and value > 0.001):
valid.append(chr(int((value*1000)%256)))
print "fractal hash gen length %i bytes" % (len(valid))
return valid
def make_fractal_params_with_key(keys):
global NKEYS, MAX_KEYSIZE
XR = keys[0]
YR = keys[1]
XRM = ((XR[0][2]/MAX_KEYSIZE)*2.5)
YRM = ((YR[0][2]/MAX_KEYSIZE)*2.0)
XRE = ((float(XR[1][2])/float(MAX_KEYSIZE))*(2.5 - XRM))
YRE = -1.0 * ((float(YR[1][2])/float(MAX_KEYSIZE))*(2.0 -YRM))
XRM = -2.0 + XRM
YRM = 1.0 - YRM
return [XRM,XRE,YRM,YRE, XR, YR]
def filter_key(key):
return [key[0], key[1]]
def make_fractal_params(keys):
global NKEYS, MAX_KEYSIZE
XR = [random.randint(0, NKEYS-1), random.randint(0, NKEYS-1)]
YR = [random.randint(0, NKEYS-1), random.randint(0, NKEYS-1)]
XRM = ((keys[XR[0]][2]/MAX_KEYSIZE)*2.5)
YRM = ((keys[YR[0]][2]/MAX_KEYSIZE)*2.0)
XRE = ((float(keys[XR[1]][2])/float(MAX_KEYSIZE))*(2.5 - XRM))
YRE = -1.0 * ((float(keys[YR[1]][2])/float(MAX_KEYSIZE))*(2.0 -YRM))
XRM = -2.0 + XRM
YRM = 1.0 - YRM
return [XRM,XRE,YRM,YRE, [filter_key(keys[XR[0]]), filter_key(keys[XR[1]])], [filter_key(keys[YR[0]]), filter_key(keys[YR[1]])]]
def make_hash_chunk(keys, params, length):
ENC_HASH = bytearray()
count = 0
while(len(ENC_HASH) < length):
param = make_fractal_params(keys)
params.append(param)
ENC_HASH.extend(make_values(keys, [param[0], param[1]], [param[2], param[3]], STEPS, STEPS))
count = count + 1
return ENC_HASH
def encrypt_file(keys, inputfile, outputfile, keyfile):
PARAMS = []
IF = open_file(inputfile)
OF = open_file(outputfile, "w")
KF = open_file(keyfile, "w")
ichunk = bytearray()
ochunk = bytearray()
enc_hash = bytearray()
ichunk.extend(IF[0].read(5000))
while(len(ichunk)):
if(len(enc_hash) < 5000):
enc_hash.extend(make_hash_chunk(keys, PARAMS, 5000))
for x in range(0, len(ichunk)):
OF[0].write(chr(ichunk[0] ^ enc_hash[0]))
ichunk.__delitem__(0)
enc_hash.__delitem__(0)
ichunk.extend(IF[0].read(5000))
OF[0].close()
keyfiledata = []
for param in PARAMS:
keyfiledata.append([param[4], param[5]])
filterkeys = []
for key in keys:
filterkeys.append(filter_key(key))
KF[0].write(pickle.dumps([keyfiledata, filterkeys]))
KF[0].close()
def decrypt_file(inputfile, outputfile, keyfile, secretkey):
IF = open_file(inputfile)
OF = open_file(outputfile, "w")
KF = open_file(keyfile, "r")
SKF = open_file(secretkey, "r")
ichunk = bytearray()
ochunk = bytearray()
enc_hash = bytearray()
keys = []
load = pickle.loads(KF[0].read(KF[1]))
for key in load[0]:
keys.append(key)
PARAMS = []
for key in keys:
PARAMS.append(make_fractal_params_with_key([[load_key(key[0][0], SKF), load_key(key[0][1], SKF)],
[load_key(key[1][0], SKF), load_key(key[1][1], SKF)]]))
KEYS = []
for key in load[1]:
KEYS.append(load_key(key, SKF))
for param in PARAMS:
enc_hash.extend(make_values(KEYS, [param[0], param[1]], [param[2], param[3]], STEPS, STEPS))
ichunk.extend(IF[0].read(5000))
while(len(ichunk)):
for x in range(0, len(ichunk)):
OF[0].write(chr(ichunk[0] ^ enc_hash[0]))
ichunk.__delitem__(0)
enc_hash.__delitem__(0)
ichunk.extend(IF[0].read(5000))
OF[0].close()
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('-d', action='store_true', help='decrypt')
parser.add_argument('-e', action='store_true', help='encrypt')
parser.add_argument('--inp', nargs=1, required=True, help='input file')
parser.add_argument('--out', nargs=1, required=True, help='ouput file')
parser.add_argument('--kf', nargs=1, required=True, help='secret key file')
parser.add_argument('--kof', nargs=1, help='public key file')
args = parser.parse_args()
if args.e:
KEYFILE = args.kf[0]
INFILE = args.inp[0]
OUTFILE = args.out[0]
OUTPUTKEYFILE = args.kof[0]
keys = make_keys(NKEYS, KEY_LEN, open_file(KEYFILE))
encrypt_file(keys, INFILE, OUTFILE, OUTPUTKEYFILE)
if args.d:
KEYFILE = args.kf[0]
INFILE = args.inp[0]
OUTFILE = args.out[0]
OUTPUTKEYFILE = args.kof[0]
decrypt_file(INFILE, OUTFILE, OUTPUTKEYFILE, KEYFILE)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment