Forráskód Böngészése

implement GMAC based on GHASH, use GHASH, faster compression, comments

note: zlib level 0 is even faster, but crashes one RemoteArchiver unittest, huh!?
Thomas Waldmann 10 éve
szülő
commit
8a36478287
2 módosított fájl, 27 hozzáadás és 12 törlés
  1. 26 11
      attic/key.py
  2. 1 1
      attic/testsuite/key.py

+ 26 - 11
attic/key.py

@@ -97,6 +97,24 @@ class SHA512_256(sha512_256):
         super().__init__(data)
         super().__init__(data)
 
 
 
 
+class GHASH:
+    TYPE = 2
+
+    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 MAC if you have a key")
+        self.key = b'\0' * 32
+        self.data = data
+
+    def digest(self):
+        mac_cipher = AES(mode=AES_GCM_MODE, is_encrypt=True, key=self.key, iv=b'\0' * 16)
+        # GMAC = aes-gcm with all data as AAD, no data as to-be-encrypted data
+        mac_cipher.add(bytes(self.data))
+        tag, _ = mac_cipher.compute_tag_and_encrypt(b'')
+        return tag
+
+
 class HMAC_SHA256(HMAC):
 class HMAC_SHA256(HMAC):
     TYPE = 10
     TYPE = 10
 
 
@@ -115,24 +133,18 @@ class HMAC_SHA512_256(HMAC):
         super().__init__(key, data, sha512_256)
         super().__init__(key, data, sha512_256)
 
 
 
 
-class GMAC:
+class GMAC(GHASH):
     TYPE = 20
     TYPE = 20
 
 
     def __init__(self, key, data):
     def __init__(self, key, data):
+        super().__init__(None, data)
         if key is None:
         if key is None:
             raise Exception("do not use GMAC if you don't have a key")
             raise Exception("do not use GMAC if you don't have a key")
         self.key = key
         self.key = key
-        self.data = data
-
-    def digest(self):
-        mac_cipher = AES(mode=AES_GCM_MODE, is_encrypt=True, key=self.key, iv=b'\0' * 16)
-        # GMAC = aes-gcm with all data as AAD, no data as to-be-encrypted data
-        mac_cipher.add(bytes(self.data))
-        tag, _ = mac_cipher.compute_tag_and_encrypt(b'')
-        return tag
 
 
 
 
-HASH_DEFAULT = SHA256.TYPE
+# defaults are optimized for speed on modern CPUs with AES hw support
+HASH_DEFAULT = GHASH.TYPE
 MAC_DEFAULT = GMAC.TYPE
 MAC_DEFAULT = GMAC.TYPE
 
 
 
 
@@ -167,7 +179,8 @@ class LzmaCompressor(object):  # uses 10..19 in the mapping
         return lzma.decompress(data)
         return lzma.decompress(data)
 
 
 
 
-COMPR_DEFAULT = ZlibCompressor.TYPE + 6  # zlib level 6
+# default is optimized for speed (and a little compression)
+COMPR_DEFAULT = ZlibCompressor.TYPE + 1 # zlib level 1
 
 
 
 
 # ciphers - AEAD (authenticated encryption with assoc. data) style interface
 # ciphers - AEAD (authenticated encryption with assoc. data) style interface
@@ -244,6 +257,7 @@ class AES_GCM:
         return data
         return data
 
 
 
 
+# cipher default is optimized for speed on modern CPUs with AES hw support
 PLAIN_DEFAULT = PLAIN.TYPE
 PLAIN_DEFAULT = PLAIN.TYPE
 CIPHER_DEFAULT = AES_GCM.TYPE
 CIPHER_DEFAULT = AES_GCM.TYPE
 
 
@@ -558,6 +572,7 @@ maccer_mapping = {
     # simple hashes, not MACs (but MAC-like class __init__ method signature):
     # simple hashes, not MACs (but MAC-like class __init__ method signature):
     SHA256.TYPE: SHA256,
     SHA256.TYPE: SHA256,
     SHA512_256.TYPE: SHA512_256,
     SHA512_256.TYPE: SHA512_256,
+    GHASH.TYPE: GHASH,
     # MACs:
     # MACs:
     HMAC_SHA256.TYPE: HMAC_SHA256,
     HMAC_SHA256.TYPE: HMAC_SHA256,
     HMAC_SHA512_256.TYPE: HMAC_SHA512_256,
     HMAC_SHA512_256.TYPE: HMAC_SHA512_256,

+ 1 - 1
attic/testsuite/key.py

@@ -59,7 +59,7 @@ QQWJNlInT3+yKnQpdqd2ZXJzaW9uAQ==""".strip()
     def test_plaintext(self):
     def test_plaintext(self):
         key = PlaintextKey.create(None, self.MockArgs())
         key = PlaintextKey.create(None, self.MockArgs())
         data = b'foo'
         data = b'foo'
-        self.assert_equal(hexlify(key.id_hash(data)), b'2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae')
+        self.assert_equal(hexlify(key.id_hash(data)), b'4c9137bc0dd3ddb31de4e138a49d7eb300000000000000000000000000000000')
         self.assert_equal(data, key.decrypt(key.id_hash(data), key.encrypt(data)))
         self.assert_equal(data, key.decrypt(key.id_hash(data), key.encrypt(data)))
 
 
     def test_keyfile(self):
     def test_keyfile(self):