Advertisement
Chris_M_Thomasson

Experimental HMAC Cipher, Educational Version (0.0.0)

May 2nd, 2018
308
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.39 KB | None | 0 0
  1. # Chris M. Thomasson Copyright 2018 (c)
  2. # Experimental HMAC Cipher
  3. # HACKED version for educational purposes ONLY!!!!
  4. # hack version (0.0.0)
  5. #____________________________________________________________
  6.  
  7.  
  8. # Our external libs
  9. #____________________________________________________________
  10. import random;
  11. import hashlib;
  12. import hmac;
  13.  
  14.  
  15. # Some Utilities
  16. #____________________________________________________________
  17. def ct_bytes_to_hex(origin, offset):
  18.     hex = "";
  19.     n = len(origin);
  20.     t = "0123456789ABCDEF";
  21.     for i in range(offset, n):
  22.         c = ord(origin[i]);
  23.         nibl = c & 0x0F;
  24.         nibh = (c & 0xF0) >> 4;
  25.         hex = hex + t[nibh];
  26.         hex = hex + t[nibl];
  27.         hex = hex + " ";
  28.         if (not ((i + 1) % 16) and i != n - 1):
  29.             hex = hex + "\r\n";
  30.     return hex;
  31.  
  32.  
  33. # Generate n random bytes
  34. # These need should ideally be from a truly random, non-repeatable
  35. # source. TRNG!
  36.  
  37. # The hacked version of this creates the same bytes on every call.
  38. # This is only for this demonstration. Period! Damn it.
  39. def ct_rand_bytes_hacked(n):
  40.     rb = "";
  41.     for i in range(n):
  42.         #rb = rb + chr(random.randint(0, 255));
  43.         rb = rb + chr(i);
  44.     return rb;
  45.  
  46.  
  47. # The Secret Key
  48. # Contains all the parts of the secret key
  49. #____________________________________________________________
  50. class ct_secret_key:
  51.     def __init__(self, hmac_key, hash_algo, rand_n):
  52.         self.hmac_key = hmac_key;
  53.         self.hash_algo = hash_algo;
  54.         self.rand_n = rand_n;
  55.  
  56.     def __repr__(self):
  57.         return "hmac_key:%s\nhash_algo:%s\nrand_n:%s" % (ct_bytes_to_hex(self.hmac_key, 0), self.hash_algo, self.rand_n);
  58.  
  59.     def __str__(self): return self.__repr__();
  60.  
  61.  
  62. # The Ciphertext or Plaintext
  63. # It holds the bytes of a ciphertext or a plaintext
  64. #____________________________________________________________
  65. class ct_bin:
  66.     def __init__(self, ctxt):
  67.         self.bytes = ctxt;
  68.     def __repr__(self):
  69.         return "%s" % (ct_bytes_to_hex(self.bytes, 0));
  70.  
  71.     def __str__(self): return self.__repr__();
  72.  
  73.  
  74. # The Crypt Round Function
  75. #____________________________________________________________
  76. def ct_crypt_round(SK, P, M):
  77.     H = hmac.new(SK.hmac_key.encode(), None, SK.hash_algo);
  78.     H.update(SK.hmac_key[::-1].encode());
  79.     C = "";
  80.     I_P = 0;
  81.     I_P_N = len(P.bytes);
  82.  
  83.     digest_n = 0;
  84.     while (I_P < I_P_N):
  85.         D = H.digest();
  86.         I_D = 0;
  87.         I_D_N = len(D);
  88.  
  89.         print("digest[%s]:(%s)\n" % (digest_n, H.hexdigest()));
  90.         digest_n = digest_n + 1;
  91.  
  92.         while (I_P < I_P_N and I_D < I_D_N):
  93.             C_I_P = ord(P.bytes[I_P]) ^ D[I_D];
  94.             C = C + chr(C_I_P);
  95.             if (M == False):
  96.                 H.update(P.bytes[I_P].encode());
  97.                 H.update(chr(C_I_P).encode());
  98.             else:
  99.                 H.update(chr(C_I_P).encode());
  100.                 H.update(P.bytes[I_P].encode());
  101.             I_P = I_P + 1;
  102.             I_D = I_D + 1;
  103.     return ct_bin(C);
  104.  
  105.  
  106. # The Crypt Function
  107. #____________________________________________________________
  108. def ct_crypt(SK, P, M):
  109.     if (M == False):
  110.         R = ct_rand_bytes_hacked(SK.rand_n);
  111.         print("prepended random bytes\n----------------------------");
  112.         print("%s" % ct_bytes_to_hex(R, 0));
  113.         print("----------------------------\n");
  114.         P.bytes = R + P.bytes;
  115.  
  116.         print("plaintext after random bytes are prepended\n----------------------------");
  117.         print("%s" % P);
  118.         print("----------------------------\n");
  119.  
  120.     print("round 0\n----------------------------");
  121.     C = ct_crypt_round(SK, P, M);
  122.     print("----------------------------\n");
  123.  
  124.     C_1 = ct_bin(C.bytes[::-1]);
  125.     print("round 1\n----------------------------");
  126.     C = ct_crypt_round(SK, C_1, M);
  127.     print("----------------------------\n");
  128.  
  129.     if (M == True):
  130.         print("\nciphertext BEFORE random bytes are removed\n----------------------------");
  131.         print("%s" % C);
  132.         print("----------------------------\n");
  133.  
  134.         size = len(C.bytes) - SK.rand_n;
  135.         C.bytes = C.bytes[SK.rand_n : SK.rand_n + size];
  136.     return C;
  137.  
  138.  
  139. # The Main Program
  140. #____________________________________________________________
  141.  
  142. # Alice and Bob's Secret Key
  143. #____________________
  144. SK = ct_secret_key(
  145.     "This is the HMAC Key. It should be a crypto secure key! Damn it.",
  146.     hashlib.sha384, # The hash function. It should be a crypto secure hash.
  147.     48 # The number of bytes. The should be generated by a TRNG
  148. );
  149. print("%s" % (SK));
  150.  
  151. # Alice's Plaintext
  152. #____________________
  153. Original_Plaintext = "ABCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDE";
  154. A_P = ct_bin(Original_Plaintext);
  155. print(
  156.     "\n\nAlice's Plaintext Bytes:"
  157.     "\n____________________\n%s\n" % (A_P)
  158. );
  159.  
  160. # Encrypt
  161. #____________________
  162. print("\n\nENCRYPT\n________________________________________\n");
  163. C = ct_crypt(SK, A_P, False);
  164. print("________________________________________\n\n");
  165. print(
  166.     "\n\nCiphertext Bytes:"
  167.     "\n____________________\n%s\n" % (C)
  168. );
  169.  
  170. # Decrypt
  171. #____________________
  172. print("\n\nDECRYPT\n________________________________________\n");
  173. B_P = ct_crypt(SK, C, True);
  174. print("________________________________________\n\n");
  175. print(
  176.     "\n\nBob's Plaintext Bytes:"
  177.     "\n____________________\n%s\n" % (B_P)
  178. );
  179.  
  180.  
  181. if (B_P.bytes != Original_Plaintext):
  182.   print("DATA CORRUPTED!");
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement