diff --git a/Annex/Export.hs b/Annex/Export.hs index 47a6a75249..5b40dda5c9 100644 --- a/Annex/Export.hs +++ b/Annex/Export.hs @@ -37,7 +37,7 @@ exportKey sha = mk <$> catKey sha mk (Just k) = AnnexKey k mk Nothing = GitKey $ Key { keyName = encodeBS $ Git.fromRef sha - , keyVariety = SHA1Key (HasExt False) mempty + , keyVariety = SHA1Key (HasExt False) , keySize = Nothing , keyMtime = Nothing , keyChunkSize = Nothing diff --git a/Backend/Hash.hs b/Backend/Hash.hs index b8977301b3..abf52ab3ed 100644 --- a/Backend/Hash.hs +++ b/Backend/Hash.hs @@ -74,15 +74,15 @@ genBackendE hash = (genBackend hash) } hashKeyVariety :: Hash -> HasExt -> KeyVariety -hashKeyVariety MD5Hash he = MD5Key he mempty -hashKeyVariety SHA1Hash he = SHA1Key he mempty -hashKeyVariety (SHA2Hash size) he = SHA2Key size he mempty -hashKeyVariety (SHA3Hash size) he = SHA3Key size he mempty -hashKeyVariety (SkeinHash size) he = SKEINKey size he mempty +hashKeyVariety MD5Hash he = MD5Key he +hashKeyVariety SHA1Hash he = SHA1Key he +hashKeyVariety (SHA2Hash size) he = SHA2Key size he +hashKeyVariety (SHA3Hash size) he = SHA3Key size he +hashKeyVariety (SkeinHash size) he = SKEINKey size he #if MIN_VERSION_cryptonite(0,23,0) -hashKeyVariety (Blake2bHash size) he = Blake2bKey size he mempty -hashKeyVariety (Blake2sHash size) he = Blake2sKey size he mempty -hashKeyVariety (Blake2spHash size) he = Blake2spKey size he mempty +hashKeyVariety (Blake2bHash size) he = Blake2bKey size he +hashKeyVariety (Blake2sHash size) he = Blake2sKey size he +hashKeyVariety (Blake2spHash size) he = Blake2spKey size he #endif {- A key is a hash of its contents. -} diff --git a/Types/Key.hs b/Types/Key.hs index df0e042606..9b7456b762 100644 --- a/Types/Key.hs +++ b/Types/Key.hs @@ -29,20 +29,16 @@ data Key = Key newtype AssociatedFile = AssociatedFile (Maybe FilePath) deriving (Show, Eq, Ord) -{- There are several different varieties of keys. - - - - The trailing ByteString can either be empty, or contain a cached - - formatting of the KeyVariety, in the form generated by formatKeyVariety. - -} +{- There are several different varieties of keys. -} data KeyVariety - = SHA2Key HashSize HasExt S.ByteString - | SHA3Key HashSize HasExt S.ByteString - | SKEINKey HashSize HasExt S.ByteString - | Blake2bKey HashSize HasExt S.ByteString - | Blake2sKey HashSize HasExt S.ByteString - | Blake2spKey HashSize HasExt S.ByteString - | SHA1Key HasExt S.ByteString - | MD5Key HasExt S.ByteString + = SHA2Key HashSize HasExt + | SHA3Key HashSize HasExt + | SKEINKey HashSize HasExt + | Blake2bKey HashSize HasExt + | Blake2sKey HashSize HasExt + | Blake2spKey HashSize HasExt + | SHA1Key HasExt + | MD5Key HasExt | WORMKey | URLKey -- Some repositories may contain keys of other varieties, @@ -59,38 +55,38 @@ newtype HashSize = HashSize Int deriving (Eq, Ord, Read, Show) hasExt :: KeyVariety -> Bool -hasExt (SHA2Key _ (HasExt b) _) = b -hasExt (SHA3Key _ (HasExt b) _) = b -hasExt (SKEINKey _ (HasExt b) _) = b -hasExt (Blake2bKey _ (HasExt b) _) = b -hasExt (Blake2sKey _ (HasExt b) _) = b -hasExt (Blake2spKey _ (HasExt b) _) = b -hasExt (SHA1Key (HasExt b) _) = b -hasExt (MD5Key (HasExt b) _) = b +hasExt (SHA2Key _ (HasExt b)) = b +hasExt (SHA3Key _ (HasExt b)) = b +hasExt (SKEINKey _ (HasExt b)) = b +hasExt (Blake2bKey _ (HasExt b)) = b +hasExt (Blake2sKey _ (HasExt b)) = b +hasExt (Blake2spKey _ (HasExt b)) = b +hasExt (SHA1Key (HasExt b)) = b +hasExt (MD5Key (HasExt b)) = b hasExt WORMKey = False hasExt URLKey = False hasExt (OtherKey s) = (snd <$> S8.unsnoc s) == Just 'E' sameExceptExt :: KeyVariety -> KeyVariety -> Bool -sameExceptExt (SHA2Key sz1 _ _) (SHA2Key sz2 _ _) = sz1 == sz2 -sameExceptExt (SHA3Key sz1 _ _) (SHA3Key sz2 _ _) = sz1 == sz2 -sameExceptExt (SKEINKey sz1 _ _) (SKEINKey sz2 _ _) = sz1 == sz2 -sameExceptExt (Blake2bKey sz1 _ _) (Blake2bKey sz2 _ _) = sz1 == sz2 -sameExceptExt (Blake2sKey sz1 _ _) (Blake2sKey sz2 _ _) = sz1 == sz2 -sameExceptExt (Blake2spKey sz1 _ _) (Blake2spKey sz2 _ _) = sz1 == sz2 -sameExceptExt (SHA1Key _ _) (SHA1Key _ _) = True -sameExceptExt (MD5Key _ _) (MD5Key _ _) = True +sameExceptExt (SHA2Key sz1 _) (SHA2Key sz2 _) = sz1 == sz2 +sameExceptExt (SHA3Key sz1 _) (SHA3Key sz2 _) = sz1 == sz2 +sameExceptExt (SKEINKey sz1 _) (SKEINKey sz2 _) = sz1 == sz2 +sameExceptExt (Blake2bKey sz1 _) (Blake2bKey sz2 _) = sz1 == sz2 +sameExceptExt (Blake2sKey sz1 _) (Blake2sKey sz2 _) = sz1 == sz2 +sameExceptExt (Blake2spKey sz1 _) (Blake2spKey sz2 _) = sz1 == sz2 +sameExceptExt (SHA1Key _) (SHA1Key _) = True +sameExceptExt (MD5Key _) (MD5Key _) = True sameExceptExt _ _ = False {- Is the Key variety cryptographically secure, such that no two differing - file contents can be mapped to the same Key? -} cryptographicallySecure :: KeyVariety -> Bool -cryptographicallySecure (SHA2Key _ _ _) = True -cryptographicallySecure (SHA3Key _ _ _) = True -cryptographicallySecure (SKEINKey _ _ _) = True -cryptographicallySecure (Blake2bKey _ _ _) = True -cryptographicallySecure (Blake2sKey _ _ _) = True -cryptographicallySecure (Blake2spKey _ _ _) = True +cryptographicallySecure (SHA2Key _ _) = True +cryptographicallySecure (SHA3Key _ _) = True +cryptographicallySecure (SKEINKey _ _) = True +cryptographicallySecure (Blake2bKey _ _) = True +cryptographicallySecure (Blake2sKey _ _) = True +cryptographicallySecure (Blake2spKey _ _) = True cryptographicallySecure _ = False {- Is the Key variety backed by a hash, which allows verifying content? @@ -98,86 +94,91 @@ cryptographicallySecure _ = False - attacks. -} isVerifiable :: KeyVariety -> Bool -isVerifiable (SHA2Key _ _ _) = True -isVerifiable (SHA3Key _ _ _) = True -isVerifiable (SKEINKey _ _ _) = True -isVerifiable (Blake2bKey _ _ _) = True -isVerifiable (Blake2sKey _ _ _) = True -isVerifiable (Blake2spKey _ _ _) = True -isVerifiable (SHA1Key _ _) = True -isVerifiable (MD5Key _ _) = True +isVerifiable (SHA2Key _ _) = True +isVerifiable (SHA3Key _ _) = True +isVerifiable (SKEINKey _ _) = True +isVerifiable (Blake2bKey _ _) = True +isVerifiable (Blake2sKey _ _) = True +isVerifiable (Blake2spKey _ _) = True +isVerifiable (SHA1Key _) = True +isVerifiable (MD5Key _) = True isVerifiable WORMKey = False isVerifiable URLKey = False isVerifiable (OtherKey _) = False formatKeyVariety :: KeyVariety -> S.ByteString formatKeyVariety v = case v of - SHA2Key sz e f -> f ! adde e (addsz sz "SHA") - SHA3Key sz e f -> f ! adde e (addsz sz "SHA3_") - SKEINKey sz e f -> f ! adde e (addsz sz "SKEIN") - Blake2bKey sz e f -> f ! adde e (addsz sz "BLAKE2B") - Blake2sKey sz e f -> f ! adde e (addsz sz "BLAKE2S") - Blake2spKey sz e f -> f ! adde e (addsz sz "BLAKE2SP") - SHA1Key e f -> f ! adde e "SHA1" - MD5Key e f -> f ! adde e "MD5" + SHA2Key sz e -> adde e (addsz sz "SHA") + SHA3Key sz e -> adde e (addsz sz "SHA3_") + SKEINKey sz e -> adde e (addsz sz "SKEIN") + Blake2bKey sz e -> adde e (addsz sz "BLAKE2B") + Blake2sKey sz e -> adde e (addsz sz "BLAKE2S") + Blake2spKey sz e -> adde e (addsz sz "BLAKE2SP") + SHA1Key e -> adde e "SHA1" + MD5Key e -> adde e "MD5" WORMKey -> "WORM" URLKey -> "URL" OtherKey s -> s where adde (HasExt False) s = s adde (HasExt True) s = s <> "E" - addsz (HashSize n) s = s <> S8.pack (show n) - - f ! s = if S.null f then s else f + addsz (HashSize n) s = s <> case n of + 256 -> "256" + 512 -> "512" + 224 -> "224" + 384 -> "384" + 160 -> "160" + -- This is relatively slow, which is why the common hash + -- sizes are hardcoded above. + _ -> S8.pack (show n) parseKeyVariety :: S.ByteString -> KeyVariety -parseKeyVariety b - | b == "SHA256" = SHA2Key (HashSize 256) (HasExt False) b - | b == "SHA256E" = SHA2Key (HashSize 256) (HasExt True) b - | b == "SHA512" = SHA2Key (HashSize 512) (HasExt False) b - | b == "SHA512E" = SHA2Key (HashSize 512) (HasExt True) b - | b == "SHA224" = SHA2Key (HashSize 224) (HasExt False) b - | b == "SHA224E" = SHA2Key (HashSize 224) (HasExt True) b - | b == "SHA384" = SHA2Key (HashSize 384) (HasExt False) b - | b == "SHA384E" = SHA2Key (HashSize 384) (HasExt True) b - | b == "SHA3_512" = SHA3Key (HashSize 512) (HasExt False) b - | b == "SHA3_512E" = SHA3Key (HashSize 512) (HasExt True) b - | b == "SHA3_384" = SHA3Key (HashSize 384) (HasExt False) b - | b == "SHA3_384E" = SHA3Key (HashSize 384) (HasExt True) b - | b == "SHA3_256" = SHA3Key (HashSize 256) (HasExt False) b - | b == "SHA3_256E" = SHA3Key (HashSize 256) (HasExt True) b - | b == "SHA3_224" = SHA3Key (HashSize 224) (HasExt False) b - | b == "SHA3_224E" = SHA3Key (HashSize 224) (HasExt True) b - | b == "SKEIN512" = SKEINKey (HashSize 512) (HasExt False) b - | b == "SKEIN512E" = SKEINKey (HashSize 512) (HasExt True) b - | b == "SKEIN256" = SKEINKey (HashSize 256) (HasExt False) b - | b == "SKEIN256E" = SKEINKey (HashSize 256) (HasExt True) b +parseKeyVariety "SHA256" = SHA2Key (HashSize 256) (HasExt False) +parseKeyVariety "SHA256E" = SHA2Key (HashSize 256) (HasExt True) +parseKeyVariety "SHA512" = SHA2Key (HashSize 512) (HasExt False) +parseKeyVariety "SHA512E" = SHA2Key (HashSize 512) (HasExt True) +parseKeyVariety "SHA224" = SHA2Key (HashSize 224) (HasExt False) +parseKeyVariety "SHA224E" = SHA2Key (HashSize 224) (HasExt True) +parseKeyVariety "SHA384" = SHA2Key (HashSize 384) (HasExt False) +parseKeyVariety "SHA384E" = SHA2Key (HashSize 384) (HasExt True) +parseKeyVariety "SHA3_512" = SHA3Key (HashSize 512) (HasExt False) +parseKeyVariety "SHA3_512E" = SHA3Key (HashSize 512) (HasExt True) +parseKeyVariety "SHA3_384" = SHA3Key (HashSize 384) (HasExt False) +parseKeyVariety "SHA3_384E" = SHA3Key (HashSize 384) (HasExt True) +parseKeyVariety "SHA3_256" = SHA3Key (HashSize 256) (HasExt False) +parseKeyVariety "SHA3_256E" = SHA3Key (HashSize 256) (HasExt True) +parseKeyVariety "SHA3_224" = SHA3Key (HashSize 224) (HasExt False) +parseKeyVariety "SHA3_224E" = SHA3Key (HashSize 224) (HasExt True) +parseKeyVariety "SKEIN512" = SKEINKey (HashSize 512) (HasExt False) +parseKeyVariety "SKEIN512E" = SKEINKey (HashSize 512) (HasExt True) +parseKeyVariety "SKEIN256" = SKEINKey (HashSize 256) (HasExt False) +parseKeyVariety "SKEIN256E" = SKEINKey (HashSize 256) (HasExt True) #if MIN_VERSION_cryptonite(0,23,0) - | b == "BLAKE2B160" = Blake2bKey (HashSize 160) (HasExt False) b - | b == "BLAKE2B160E" = Blake2bKey (HashSize 160) (HasExt True) b - | b == "BLAKE2B224" = Blake2bKey (HashSize 224) (HasExt False) b - | b == "BLAKE2B224E" = Blake2bKey (HashSize 224) (HasExt True) b - | b == "BLAKE2B256" = Blake2bKey (HashSize 256) (HasExt False) b - | b == "BLAKE2B256E" = Blake2bKey (HashSize 256) (HasExt True) b - | b == "BLAKE2B384" = Blake2bKey (HashSize 384) (HasExt False) b - | b == "BLAKE2B384E" = Blake2bKey (HashSize 384) (HasExt True) b - | b == "BLAKE2B512" = Blake2bKey (HashSize 512) (HasExt False) b - | b == "BLAKE2B512E" = Blake2bKey (HashSize 512) (HasExt True) b - | b == "BLAKE2S160" = Blake2sKey (HashSize 160) (HasExt False) b - | b == "BLAKE2S160E" = Blake2sKey (HashSize 160) (HasExt True) b - | b == "BLAKE2S224" = Blake2sKey (HashSize 224) (HasExt False) b - | b == "BLAKE2S224E" = Blake2sKey (HashSize 224) (HasExt True) b - | b == "BLAKE2S256" = Blake2sKey (HashSize 256) (HasExt False) b - | b == "BLAKE2S256E" = Blake2sKey (HashSize 256) (HasExt True) b - | b == "BLAKE2SP224" = Blake2spKey (HashSize 224) (HasExt False) b - | b == "BLAKE2SP224E" = Blake2spKey (HashSize 224) (HasExt True) b - | b == "BLAKE2SP256" = Blake2spKey (HashSize 256) (HasExt False) b - | b == "BLAKE2SP256E" = Blake2spKey (HashSize 256) (HasExt True) b +parseKeyVariety "BLAKE2B160" = Blake2bKey (HashSize 160) (HasExt False) +parseKeyVariety "BLAKE2B160E" = Blake2bKey (HashSize 160) (HasExt True) +parseKeyVariety "BLAKE2B224" = Blake2bKey (HashSize 224) (HasExt False) +parseKeyVariety "BLAKE2B224E" = Blake2bKey (HashSize 224) (HasExt True) +parseKeyVariety "BLAKE2B256" = Blake2bKey (HashSize 256) (HasExt False) +parseKeyVariety "BLAKE2B256E" = Blake2bKey (HashSize 256) (HasExt True) +parseKeyVariety "BLAKE2B384" = Blake2bKey (HashSize 384) (HasExt False) +parseKeyVariety "BLAKE2B384E" = Blake2bKey (HashSize 384) (HasExt True) +parseKeyVariety "BLAKE2B512" = Blake2bKey (HashSize 512) (HasExt False) +parseKeyVariety "BLAKE2B512E" = Blake2bKey (HashSize 512) (HasExt True) +parseKeyVariety "BLAKE2S160" = Blake2sKey (HashSize 160) (HasExt False) +parseKeyVariety "BLAKE2S160E" = Blake2sKey (HashSize 160) (HasExt True) +parseKeyVariety "BLAKE2S224" = Blake2sKey (HashSize 224) (HasExt False) +parseKeyVariety "BLAKE2S224E" = Blake2sKey (HashSize 224) (HasExt True) +parseKeyVariety "BLAKE2S256" = Blake2sKey (HashSize 256) (HasExt False) +parseKeyVariety "BLAKE2S256E" = Blake2sKey (HashSize 256) (HasExt True) +parseKeyVariety "BLAKE2SP224" = Blake2spKey (HashSize 224) (HasExt False) +parseKeyVariety "BLAKE2SP224E" = Blake2spKey (HashSize 224) (HasExt True) +parseKeyVariety "BLAKE2SP256" = Blake2spKey (HashSize 256) (HasExt False) +parseKeyVariety "BLAKE2SP256E" = Blake2spKey (HashSize 256) (HasExt True) #endif - | b == "SHA1" = SHA1Key (HasExt False) b - | b == "SHA1E" = SHA1Key (HasExt True) b - | b == "MD5" = MD5Key (HasExt False) b - | b == "MD5E" = MD5Key (HasExt True) b - | b == "WORM" = WORMKey - | b == "URL" = URLKey - | otherwise = OtherKey b +parseKeyVariety "SHA1" = SHA1Key (HasExt False) +parseKeyVariety "SHA1E" = SHA1Key (HasExt True) +parseKeyVariety "MD5" = MD5Key (HasExt False) +parseKeyVariety "MD5E" = MD5Key (HasExt True) +parseKeyVariety "WORM" = WORMKey +parseKeyVariety "URL" = URLKey +parseKeyVariety b = OtherKey b