Chris_M_Thomasson

Experimental HMAC Based Encryption ver (0.0.3)

Feb 1st, 2018
321
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.57 KB | None | 0 0
  1. # Chris M. Thomasson 2/1/2018
  2. # Experimental HMAC Cipher
  3.  
  4. import random;
  5. import hmac;
  6.  
  7.  
  8. # Some Utilities
  9. #____________________________________________________________
  10. def ct_bytes_to_hex(origin, offset):
  11.     hex = "";
  12.     n = len(origin);
  13.     t = "0123456789ABCDEF";
  14.  
  15.     for i in range(offset, n):
  16.         c = ord(origin[i]);
  17.  
  18.         nibl = c & 0x0F;
  19.         nibh = (c & 0xF0) >> 4;
  20.  
  21.         hex = hex + t[nibh];
  22.         hex = hex + t[nibl];
  23.  
  24.         hex = hex + " ";
  25.  
  26.         if (not ((i + 1) % 16) and i != n - 1):
  27.             hex = hex + "\r\n";
  28.  
  29.     return hex;
  30.  
  31.  
  32. # Generate n random bytes
  33. # These can be from a truly random, non-repeatable source.
  34. def ct_rand_bytes(n):
  35.     rb = "";
  36.     for i in range(n):
  37.         rb = rb + chr(random.randint(0, 255));
  38.     return rb;
  39.  
  40.  
  41. # The Secret Key
  42. #____________________________________________________________
  43. class ct_secret_key:
  44.     def __init__(self, hmac_pword, pbyte_pword, pbyte, crand_iv_bytes, crand_inject_bytes, rounds):
  45.         self.hmac_pword = hmac_pword;
  46.         self.pbyte_pword = pbyte_pword;
  47.         self.pbyte = pbyte;
  48.         self.crand_iv_bytes = crand_iv_bytes;
  49.         self.crand_inject_bytes = crand_inject_bytes;
  50.         self.rounds = rounds;
  51.  
  52.     def __repr__(self):
  53.         return "hmac_pword:%s\npbyte_pword:%s\npbyte:%s\ncrand_iv_bytes:%s\ncrand_inject_bytes:%s\nrounds:%s" % (self.hmac_pword, self.pbyte_pword, self.pbyte, self.crand_iv_bytes, self.crand_inject_bytes, self.rounds);
  54.  
  55.     def __str__(self): return self.__repr__();
  56.  
  57.  
  58. # The Plaintext
  59. #____________________________________________________________
  60. class ct_plaintext:
  61.     def __init__(self, ptxt):
  62.         self.bytes = ptxt;
  63.  
  64.     def __repr__(self):
  65.         return "bytes:%s" % (ct_bytes_to_hex(self.bytes, 0));
  66.  
  67.     def __str__(self): return self.__repr__();
  68.  
  69.  
  70. # The Ciphertext
  71. #____________________________________________________________
  72. class ct_ciphertext:
  73.     def __init__(self, crand, ctxt):
  74.         self.crand = crand;
  75.         self.bytes = ctxt;
  76.  
  77.     def __repr__(self):
  78.         return "iv:%s\nbytes:%s" % (ct_bytes_to_hex(self.crand, 0), ct_bytes_to_hex(self.bytes, 0));
  79.  
  80.     def __str__(self): return self.__repr__();
  81.  
  82.  
  83. # Encrypt Round
  84. #____________________________________________________________
  85. def ct_encrypt_round(skey, crand, ptxt):
  86.     ctxt = "";
  87.     n = len(ptxt.bytes);
  88.     pbyte_len = len(skey.pbyte_pword);
  89.  
  90.     h = hmac.new((crand + skey.hmac_pword).encode());
  91.     h.update((skey.hmac_pword + crand).encode());
  92.  
  93.     i = 0;
  94.     pbyte = ord(skey.pbyte_pword[skey.pbyte % pbyte_len]);
  95.     while (i < n):
  96.         # Grab HMAC buffer
  97.         hbytes = h.digest();
  98.         hn = len(hbytes);
  99.         hi = 0;
  100.  
  101.         while (i < n and hi < hn):
  102.             p = ord(ptxt.bytes[i]);
  103.             c = p ^ hbytes[hi];
  104.             c = c ^ pbyte;
  105.             pbyte = c ^ ord(skey.pbyte_pword[i % pbyte_len]);
  106.             h.update(ptxt.bytes[i].encode());
  107.             h.update(chr(c).encode());
  108.             ctxt = ctxt + chr(c);
  109.             i = i + 1;
  110.             hi = hi + 1;
  111.  
  112.     return ct_ciphertext(crand, ctxt);
  113.  
  114.  
  115. # Decrypt Round
  116. #____________________________________________________________
  117. def ct_decrypt_round(skey, ctxt):
  118.     ptxt = "";
  119.     n = len(ctxt.bytes);
  120.     pbyte_len = len(skey.pbyte_pword);
  121.  
  122.     # Initialize HMAC for this session
  123.     h = hmac.new((ctxt.crand + skey.hmac_pword).encode());
  124.     h.update((skey.hmac_pword + ctxt.crand).encode());
  125.  
  126.     i = 0;
  127.     pbyte = ord(skey.pbyte_pword[skey.pbyte % pbyte_len]);
  128.  
  129.     while (i < n):
  130.         hbytes = h.digest();
  131.         hn = len(hbytes);
  132.         hi = 0;
  133.  
  134.         while (i < n and hi < hn):
  135.             c = ord(ctxt.bytes[i]);
  136.             p = c ^ hbytes[hi];
  137.             p = p ^ pbyte;
  138.             pbyte = c ^ ord(skey.pbyte_pword[i % pbyte_len]);
  139.             h.update(chr(p).encode());
  140.             h.update(chr(c).encode());
  141.             ptxt = ptxt + chr(p);
  142.             i = i + 1;
  143.             hi = hi + 1;
  144.  
  145.     return ct_plaintext(ptxt);
  146.  
  147.  
  148. # Inject/Eject
  149. #____________________________________________________________
  150. def ct_inject(skey, ptxt):
  151.     # n bytes of random injection
  152.     crand_inject = ct_rand_bytes(skey.crand_inject_bytes);
  153.     # quick hack to prepend the random injection
  154.     return crand_inject + ptxt.bytes;
  155.  
  156. def ct_eject(skey, ptxt):
  157.     # remove the random injection
  158.     size = len(ptxt.bytes) - skey.crand_inject_bytes;
  159.     return ptxt.bytes[skey.crand_inject_bytes : skey.crand_inject_bytes + size];
  160.  
  161.  
  162. # Encrypt/Decrypt
  163. #____________________________________________________________
  164. def ct_encrypt(skey, ptxt):
  165.     crand_iv = ct_rand_bytes(skey.crand_iv_bytes); # n bytes of random iv
  166.  
  167.     ptxt.bytes = ct_inject(skey, ptxt);
  168.  
  169.     for i in range(skey.rounds):
  170.         ctxt = ct_encrypt_round(skey, crand_iv, ptxt);
  171.         ptxt.bytes = ctxt.bytes[::-1];
  172.         ctxt = ct_encrypt_round(skey, crand_iv, ptxt);
  173.  
  174.     return ctxt;
  175.  
  176. def ct_decrypt(skey, ctxt):
  177.     for i in range(skey.rounds):
  178.         ptxt = ct_decrypt_round(skey, ctxt);
  179.         ctxt.bytes = ptxt.bytes[::-1];
  180.         ptxt = ct_decrypt_round(skey, ctxt);
  181.  
  182.     ptxt.bytes = ct_eject(skey, ptxt);
  183.  
  184.     return ptxt;
  185.  
  186.  
  187.  
  188. # Main Program
  189. #____________________________________________________________
  190. print("Experimental HMAC Encryption");
  191. print("Chris M. Thomasson 2/1/2018");
  192. print("==============================================================\n\n");
  193.  
  194.  
  195. # Alice and Bob_II's secret key
  196. skey = ct_secret_key(
  197.     "This is the actuall Secret HMAC Key! BTW, this should be longer...",
  198.     "Yet Another Password Used With the Previous Byte...",
  199.     103, # Previous byte seed
  200.     32,  # Truly Random IV Bytes
  201.     13,  # Truly Random Injection Bytes
  202.     10   # Rounds
  203. );
  204.  
  205. print("Secret Key:\n"
  206.     "______________________________\n"
  207.     "%s\n\n" % (skey)
  208. );
  209.  
  210.  
  211. # Our plaintext
  212. ptxt_bytes = "Wow! ;^)\n\nWell, just cipher just might be fairly secure wrt HMAC?";
  213.  
  214. ptxt = ct_plaintext(ptxt_bytes);
  215.  
  216. print("Original Plaintext:\n"
  217.     "______________________________\n"
  218.     "%s\n\n" % (ptxt)
  219. );
  220.  
  221.  
  222.  
  223. # Encrypt the plaintext
  224. ctxt = ct_encrypt(skey, ptxt);
  225.  
  226. print("Ciphertext:\n"
  227.     "______________________________\n"
  228.     "%s\n\n" % (ctxt)
  229. );
  230.  
  231.  
  232.  
  233. # Decrypt the ciphertext
  234. ptxt_decrypt = ct_decrypt(skey, ctxt);
  235.  
  236. print("Decrypted Plaintext:\n"
  237.     "______________________________\n"
  238.     "%s\n\n" % (ptxt_decrypt)
  239. );
  240.  
  241. #print("\n\n__________________\n%s\n__________________\n\n" % (ptxt_decrypt.bytes));
  242.  
  243.  
  244. # Check the data...
  245. if (ptxt_bytes != ptxt_decrypt.bytes):
  246.     print("DATA CORRUPTED!!!!!");
Advertisement
Add Comment
Please, Sign In to add comment