Ver código fonte

simplify / dedup hashers and maccers

Thomas Waldmann 10 anos atrás
pai
commit
14a20516d3
1 arquivos alterados com 45 adições e 77 exclusões
  1. 45 77
      attic/key.py

+ 45 - 77
attic/key.py

@@ -62,25 +62,19 @@ class sha512_256(object):  # note: can't subclass sha512
         return new
 
 
-class HMAC(hmac.HMAC):
-    """Workaround a bug in Python < 3.4 Where HMAC does not accept memoryviews
-    """
-    def update(self, msg):
-        self.inner.update(msg)
-
-
 # HASH / MAC stuff below all has a mac-like interface, so it can be used in the same way.
 # special case: hashes do not use keys (and thus, do not sign/authenticate)
 
-class SHA256(object):  # note: can't subclass sha256
-    TYPE = 0
-    digest_size = 32
+class HASH:  # note: we can't subclass sha1/sha256/sha512
+    TYPE = 0  # override in subclass
+    digest_size = 0  # override in subclass
+    hash_func = None  # override in subclass
 
     def __init__(self, key, data=b''):
         # signature is like for a MAC, we ignore the key as this is a simple hash
         if key is not None:
             raise Exception("use a HMAC if you have a key")
-        self.h = sha256(data)
+        self.h = self.hash_func(data)
 
     def update(self, data):
         self.h.update(data)
@@ -92,126 +86,100 @@ class SHA256(object):  # note: can't subclass sha256
         return self.h.hexdigest()
 
 
-class SHA512_256(sha512_256):
-    """sha512, but digest truncated to 256bit - faster than sha256 on 64bit platforms"""
-    TYPE = 1
+class SHA256(HASH):
+    TYPE = 0
     digest_size = 32
+    hash_func = sha256
 
-    def __init__(self, key, data):
-        # signature is like for a MAC, we ignore the key as this is a simple hash
-        if key is not None:
-            raise Exception("use a HMAC if you have a key")
-        super().__init__(data)
+
+class SHA512_256(HASH):
+    TYPE = 1
+    digest_size = 32
+    hash_func = sha512_256
 
 
 class GHASH:
     TYPE = 2
     digest_size = 16
 
-    def __init__(self, key, data):
+    def __init__(self, key, data=b''):
         # signature is like for a MAC, we ignore the key as this is a simple hash
         if key is not None:
             raise Exception("use a MAC if you have a key")
-        self.key = b'\0' * 32
-        self.data = data
+        self.mac_cipher = AES(mode=AES_GCM_MODE, is_encrypt=True, key=b'\0' * 32, iv=b'\0' * 16)
+        if data:
+            self.update(data)
 
-    def digest(self):
-        mac_cipher = AES(mode=AES_GCM_MODE, is_encrypt=True, key=self.key, iv=b'\0' * 16)
+    def update(self, data):
         # GMAC = aes-gcm with all data as AAD, no data as to-be-encrypted data
-        mac_cipher.add(bytes(self.data))
-        hash, _ = mac_cipher.compute_mac_and_encrypt(b'')
+        self.mac_cipher.add(bytes(data))
+
+    def digest(self):
+        hash, _ = self.mac_cipher.compute_mac_and_encrypt(b'')
         return hash
 
 
-class SHA1(object):  # note: can't subclass sha1
+class SHA1(HASH):
     TYPE = 3
     digest_size = 20
-
-    def __init__(self, key, data=b''):
-        # signature is like for a MAC, we ignore the key as this is a simple hash
-        if key is not None:
-            raise Exception("use a HMAC if you have a key")
-        self.h = sha1(data)
-
-    def update(self, data):
-        self.h.update(data)
-
-    def digest(self):
-        return self.h.digest()
-
-    def hexdigest(self):
-        return self.h.hexdigest()
+    hash_func = sha1
 
 
-class SHA512(object):  # note: can't subclass sha512
+class SHA512(HASH):
     TYPE = 4
     digest_size = 64
+    hash_func = sha512
 
-    def __init__(self, key, data=b''):
-        # signature is like for a MAC, we ignore the key as this is a simple hash
-        if key is not None:
-            raise Exception("use a HMAC if you have a key")
-        self.h = sha512(data)
 
-    def update(self, data):
-        self.h.update(data)
+class HMAC(hmac.HMAC):
+    TYPE = 0  # override in subclass
+    digest_size = 0  # override in subclass
+    hash_func = None  # override in subclass
 
-    def digest(self):
-        return self.h.digest()
+    def __init__(self, key, data):
+        if key is None:
+            raise Exception("do not use HMAC if you don't have a key")
+        super().__init__(key, data, self.hash_func)
 
-    def hexdigest(self):
-        return self.h.hexdigest()
+    def update(self, msg):
+        # Workaround a bug in Python < 3.4 Where HMAC does not accept memoryviews
+        self.inner.update(msg)
 
 
 class HMAC_SHA256(HMAC):
     TYPE = 10
     digest_size = 32
-
-    def __init__(self, key, data):
-        if key is None:
-            raise Exception("do not use HMAC if you don't have a key")
-        super().__init__(key, data, sha256)
+    hash_func = sha256
 
 
 class HMAC_SHA512_256(HMAC):
     TYPE = 11
     digest_size = 32
-
-    def __init__(self, key, data):
-        if key is None:
-            raise Exception("do not use HMAC if you don't have a key")
-        super().__init__(key, data, sha512_256)
+    hash_func = sha512_256
 
 
 class HMAC_SHA1(HMAC):
     TYPE = 13
     digest_size = 20
-
-    def __init__(self, key, data):
-        if key is None:
-            raise Exception("do not use HMAC if you don't have a key")
-        super().__init__(key, data, sha1)
+    hash_func = sha1
 
 
 class HMAC_SHA512(HMAC):
     TYPE = 14
     digest_size = 64
-
-    def __init__(self, key, data):
-        if key is None:
-            raise Exception("do not use HMAC if you don't have a key")
-        super().__init__(key, data, sha512)
+    hash_func = sha512
 
 
 class GMAC(GHASH):
     TYPE = 20
     digest_size = 16
 
-    def __init__(self, key, data):
-        super().__init__(None, data)
+    def __init__(self, key, data=b''):
         if key is None:
             raise Exception("do not use GMAC if you don't have a key")
-        self.key = key
+        self.mac_cipher = AES(mode=AES_GCM_MODE, is_encrypt=True, key=key, iv=b'\0' * 16)
+        if data:
+            self.update(data)
 
 
 # defaults are optimized for speed on modern CPUs with AES hw support