Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Chris M. Thomasson 2/5/2018
- # Experimental HMAC Cipher (no IV, var HMAC hash algo test...)
- import random;
- import hashlib;
- import hmac;
- # Some 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) and i != n - 1):
- hex = hex + "\r\n";
- return hex;
- # Generate n random bytes
- # These can be from a truly random, non-repeatable source.
- def ct_rand_bytes(n):
- rb = "";
- for i in range(n):
- rb = rb + chr(random.randint(0, 255));
- return rb;
- # Generate n of the same byte
- def ct_bytes(n, b):
- rb = "";
- for i in range(n):
- rb = rb + chr(b);
- return rb;
- # The Secret Key
- #____________________________________________________________
- class ct_secret_key:
- def __init__(self, hmac_pword, pbyte_pword, pbyte, crand_inject_bytes, rounds, hash_algo):
- self.hmac_pword = hmac_pword;
- self.pbyte_pword = pbyte_pword;
- self.pbyte = pbyte;
- self.crand_inject_bytes = crand_inject_bytes;
- self.rounds = rounds;
- self.hash_algo = hash_algo;
- def __repr__(self):
- return "hmac_pword:%s\npbyte_pword:%s\npbyte:%s\ncrand_inject_bytes:%s\nrounds:%s\nhash_algo:%s" % (self.hmac_pword, self.pbyte_pword, self.pbyte, self.crand_inject_bytes, self.rounds, self.hash_algo);
- def __str__(self): return self.__repr__();
- # The Plaintext
- #____________________________________________________________
- class ct_plaintext:
- def __init__(self, ptxt):
- self.bytes = ptxt;
- def __repr__(self):
- return "bytes:%s" % (ct_bytes_to_hex(self.bytes, 0));
- def __str__(self): return self.__repr__();
- # The Ciphertext
- #____________________________________________________________
- class ct_ciphertext:
- def __init__(self, ctxt):
- self.bytes = ctxt;
- def __repr__(self):
- return "bytes:%s" % (ct_bytes_to_hex(self.bytes, 0));
- def __str__(self): return self.__repr__();
- # Encrypt Round
- #____________________________________________________________
- def ct_encrypt_round(skey, ptxt):
- ctxt = "";
- n = len(ptxt.bytes);
- pbyte_len = len(skey.pbyte_pword);
- pbyte = ord(skey.pbyte_pword[skey.pbyte % pbyte_len]);
- # Initialize HMAC for this session
- h_initial_inject = ct_bytes(32, (pbyte_len + pbyte) % 256);
- h = hmac.new(h_initial_inject.encode(), skey.hmac_pword.encode(), skey.hash_algo);
- h.update((skey.pbyte_pword + h_initial_inject).encode());
- i = 0;
- while (i < n):
- # Grab HMAC buffer
- hbytes = h.digest();
- hn = len(hbytes);
- hi = 0;
- while (i < n and hi < hn):
- p = ord(ptxt.bytes[i]);
- c = p ^ hbytes[hi];
- c = c ^ pbyte;
- pbyte = c ^ ord(skey.pbyte_pword[i % pbyte_len]);
- h.update(ptxt.bytes[i].encode());
- h.update(chr(c).encode());
- ctxt = ctxt + chr(c);
- i = i + 1;
- hi = hi + 1;
- return ct_ciphertext(ctxt);
- # Decrypt Round
- #____________________________________________________________
- def ct_decrypt_round(skey, ctxt):
- ptxt = "";
- n = len(ctxt.bytes);
- pbyte_len = len(skey.pbyte_pword);
- pbyte = ord(skey.pbyte_pword[skey.pbyte % pbyte_len]);
- # Initialize HMAC for this session
- h_initial_inject = ct_bytes(32, (pbyte_len + pbyte) % 256);
- h = hmac.new(h_initial_inject.encode(), skey.hmac_pword.encode(), skey.hash_algo);
- h.update((skey.pbyte_pword + h_initial_inject).encode());
- i = 0;
- while (i < n):
- hbytes = h.digest();
- hn = len(hbytes);
- hi = 0;
- while (i < n and hi < hn):
- c = ord(ctxt.bytes[i]);
- p = c ^ hbytes[hi];
- p = p ^ pbyte;
- pbyte = c ^ ord(skey.pbyte_pword[i % pbyte_len]);
- h.update(chr(p).encode());
- h.update(chr(c).encode());
- ptxt = ptxt + chr(p);
- i = i + 1;
- hi = hi + 1;
- return ct_plaintext(ptxt);
- # Inject/Eject
- #____________________________________________________________
- def ct_inject(skey, ptxt):
- # n bytes of random injection
- crand_inject = ct_rand_bytes(skey.crand_inject_bytes);
- # quick hack to prepend the random injection
- return crand_inject + ptxt.bytes;
- def ct_eject(skey, ptxt):
- # remove the random injection
- size = len(ptxt.bytes) - skey.crand_inject_bytes;
- return ptxt.bytes[skey.crand_inject_bytes : skey.crand_inject_bytes + size];
- # Encrypt/Decrypt
- #____________________________________________________________
- def ct_encrypt(skey, ptxt):
- ptxt.bytes = ct_inject(skey, ptxt);
- for i in range(skey.rounds):
- ctxt = ct_encrypt_round(skey, ptxt);
- ptxt.bytes = ctxt.bytes[::-1];
- ctxt = ct_encrypt_round(skey, ptxt);
- return ctxt;
- def ct_decrypt(skey, ctxt):
- for i in range(skey.rounds):
- ptxt = ct_decrypt_round(skey, ctxt);
- ctxt.bytes = ptxt.bytes[::-1];
- ptxt = ct_decrypt_round(skey, ctxt);
- ptxt.bytes = ct_eject(skey, ptxt);
- return ptxt;
- # Main Program
- #____________________________________________________________
- print("Experimental HMAC Encryption (no IV, var HMAC hash algo test...)");
- print("Chris M. Thomasson 2/5/2018");
- print("==============================================================\n\n");
- # Alice and Bob_II's secret key
- # make sure injection bytes are >= HMAC hash algo digest size...
- skey = ct_secret_key(
- "This is the actuall Secret HMAC Key! BTW, this should be longer...",
- "Yet Another Password Used With the Previous Byte...",
- 103, # Previous byte seed
- 64, # Truly Random Injection Bytes
- 5, # Rounds
- hashlib.sha384 # Our HMAC hash algo
- );
- print("Secret Key:\n"
- "______________________________\n"
- "%s\n\n" % (skey)
- );
- # Our plaintext
- ptxt_bytes = "Wow! ;^)\n\nWell, this cipher just might be fairly secure wrt HMAC?";
- ptxt = ct_plaintext(ptxt_bytes);
- print("Original Plaintext:\n"
- "______________________________\n"
- "%s\n\n" % (ptxt)
- );
- # Encrypt the plaintext
- ctxt = ct_encrypt(skey, ptxt);
- print("Ciphertext:\n"
- "______________________________\n"
- "%s\n\n" % (ctxt)
- );
- # Decrypt the ciphertext
- # eve can try a different hash wrt modifying the secret key
- # got gonna work... ;^)
- #skey.hash_algo = hashlib.sha512;
- ptxt_decrypt = ct_decrypt(skey, ctxt);
- print("Decrypted Plaintext:\n"
- "______________________________\n"
- "%s\n\n" % (ptxt_decrypt)
- );
- #print("\n\n__________________\n%s\n__________________\n\n" % (ptxt_decrypt.bytes));
- # Check the data...
- if (ptxt_bytes != ptxt_decrypt.bytes):
- print("DATA CORRUPTED!!!!!");
Advertisement
Add Comment
Please, Sign In to add comment