Chris_M_Thomasson

Experimental HMAC Based Encryption ver (0.0.4) var hmac test

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