Chris_M_Thomasson

Experimental HMAC Based Encryption ver (0.0.3) (no IV test)

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