{-# LANGUAGE TypeApplications #-}
module Tahoe.CHK.Crypto (
sha1,
sha256,
sha256d,
storageIndexLength,
toBytes,
taggedHash,
taggedHash',
taggedPairHash,
taggedPairHash',
blockHash,
blockHash',
storageIndexHash,
ciphertextTag,
ciphertextSegmentHash,
ciphertextSegmentHash',
uriExtensionHash,
convergenceEncryptionTag,
convergenceEncryptionHashLazy,
convergenceSecretLength,
) where
import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as BL
import Crypto.Hash (
Digest,
HashAlgorithm,
hash,
hashDigestSize,
hashlazy,
)
import Data.ByteArray (convert)
import Crypto.Cipher.AES (AES128)
import Crypto.Hash.Algorithms (
SHA1,
SHA256 (SHA256),
)
import Tahoe.CHK.Cipher (Key)
import Tahoe.CHK.SHA256d (Digest' (..), SHA256d, toBytes)
import Tahoe.CHK.Types (Parameters (Parameters), StorageIndex)
import Tahoe.CHK.URIExtension (
URIExtension,
showBytes,
uriExtensionToBytes,
)
import Tahoe.Netstring (
netstring,
)
sha1 :: B.ByteString -> B.ByteString
sha1 :: ByteString -> ByteString
sha1 ByteString
xs = Digest SHA1 -> ByteString
forall a. ByteArrayAccess a => a -> ByteString
toBytes (ByteString -> Digest SHA1
forall ba a.
(ByteArrayAccess ba, HashAlgorithm a) =>
ba -> Digest a
hash ByteString
xs :: Digest SHA1)
sha256 :: B.ByteString -> B.ByteString
sha256 :: ByteString -> ByteString
sha256 ByteString
xs = Digest SHA256 -> ByteString
forall a. ByteArrayAccess a => a -> ByteString
toBytes (ByteString -> Digest SHA256
forall ba a.
(ByteArrayAccess ba, HashAlgorithm a) =>
ba -> Digest a
hash ByteString
xs :: Digest SHA256)
sha256d :: B.ByteString -> B.ByteString
sha256d :: ByteString -> ByteString
sha256d = Digest SHA256d -> ByteString
forall a. ByteArrayAccess a => a -> ByteString
toBytes (Digest SHA256d -> ByteString)
-> (ByteString -> Digest SHA256d) -> ByteString -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ByteString -> Digest SHA256d
forall ba a.
(ByteArrayAccess ba, HashAlgorithm a) =>
ba -> Digest a
hash :: B.ByteString -> Digest SHA256d)
taggedHash :: Int -> B.ByteString -> B.ByteString -> B.ByteString
taggedHash :: Int -> ByteString -> ByteString -> ByteString
taggedHash Int
size ByteString
tag ByteString
bytes = Int -> ByteString -> ByteString
B.take Int
size (ByteString -> ByteString)
-> (Digest' SHA256d -> ByteString) -> Digest' SHA256d -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Digest' SHA256d -> ByteString
forall a. ByteArrayAccess a => a -> ByteString
toBytes (Digest' SHA256d -> ByteString) -> Digest' SHA256d -> ByteString
forall a b. (a -> b) -> a -> b
$ ByteString -> ByteString -> Digest' SHA256d
forall hash.
HashAlgorithm hash =>
ByteString -> ByteString -> Digest' hash
taggedHash' @SHA256d ByteString
tag ByteString
bytes
taggedHash' :: HashAlgorithm hash => B.ByteString -> B.ByteString -> Digest' hash
taggedHash' :: ByteString -> ByteString -> Digest' hash
taggedHash' ByteString
tag ByteString
bytes = Digest hash -> Digest' hash
forall a. Digest a -> Digest' a
Digest' (Digest hash -> Digest' hash)
-> ([ByteString] -> Digest hash) -> [ByteString] -> Digest' hash
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Digest hash
forall ba a.
(ByteArrayAccess ba, HashAlgorithm a) =>
ba -> Digest a
hash (ByteString -> Digest hash)
-> ([ByteString] -> ByteString) -> [ByteString] -> Digest hash
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteString] -> ByteString
B.concat ([ByteString] -> Digest' hash) -> [ByteString] -> Digest' hash
forall a b. (a -> b) -> a -> b
$ [ByteString -> ByteString
netstring ByteString
tag, ByteString
bytes]
taggedPairHash :: Int -> B.ByteString -> B.ByteString -> B.ByteString -> B.ByteString
taggedPairHash :: Int -> ByteString -> ByteString -> ByteString -> ByteString
taggedPairHash Int
size ByteString
tag ByteString
left ByteString
right = Int -> ByteString -> ByteString
B.take Int
size (ByteString -> ByteString)
-> (Digest' SHA256d -> ByteString) -> Digest' SHA256d -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Digest' SHA256d -> ByteString
forall a. ByteArrayAccess a => a -> ByteString
toBytes (Digest' SHA256d -> ByteString) -> Digest' SHA256d -> ByteString
forall a b. (a -> b) -> a -> b
$ ByteString -> ByteString -> ByteString -> Digest' SHA256d
forall hash.
HashAlgorithm hash =>
ByteString -> ByteString -> ByteString -> Digest' hash
taggedPairHash' @SHA256d ByteString
tag ByteString
left ByteString
right
taggedPairHash' :: HashAlgorithm hash => B.ByteString -> B.ByteString -> B.ByteString -> Digest' hash
taggedPairHash' :: ByteString -> ByteString -> ByteString -> Digest' hash
taggedPairHash' ByteString
tag ByteString
left ByteString
right = Digest hash -> Digest' hash
forall a. Digest a -> Digest' a
Digest' (Digest hash -> Digest' hash)
-> ([ByteString] -> Digest hash) -> [ByteString] -> Digest' hash
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Digest hash
forall ba a.
(ByteArrayAccess ba, HashAlgorithm a) =>
ba -> Digest a
hash (ByteString -> Digest hash)
-> ([ByteString] -> ByteString) -> [ByteString] -> Digest hash
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteString] -> ByteString
B.concat ([ByteString] -> Digest' hash) -> [ByteString] -> Digest' hash
forall a b. (a -> b) -> a -> b
$ [ByteString -> ByteString
netstring ByteString
tag, ByteString -> ByteString
netstring ByteString
left, ByteString -> ByteString
netstring ByteString
right]
blockTag :: B.ByteString
blockTag :: ByteString
blockTag = ByteString
"allmydata_encoded_subshare_v1"
blockHash :: B.ByteString -> B.ByteString
blockHash :: ByteString -> ByteString
blockHash = Int -> ByteString -> ByteString -> ByteString
taggedHash (SHA256 -> Int
forall a. HashAlgorithm a => a -> Int
hashDigestSize SHA256
SHA256) ByteString
blockTag
blockHash' :: HashAlgorithm hash => B.ByteString -> Digest' hash
blockHash' :: ByteString -> Digest' hash
blockHash' = ByteString -> ByteString -> Digest' hash
forall hash.
HashAlgorithm hash =>
ByteString -> ByteString -> Digest' hash
taggedHash' ByteString
blockTag
storageIndexTag :: B.ByteString
storageIndexTag :: ByteString
storageIndexTag = ByteString
"allmydata_immutable_key_to_storage_index_v1"
storageIndexHash :: Key AES128 -> StorageIndex
storageIndexHash :: Key AES128 -> ByteString
storageIndexHash = Int -> ByteString -> ByteString -> ByteString
taggedHash Int
storageIndexLength ByteString
storageIndexTag (ByteString -> ByteString)
-> (Key AES128 -> ByteString) -> Key AES128 -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Key AES128 -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
convert
ciphertextTag :: B.ByteString
ciphertextTag :: ByteString
ciphertextTag = ByteString
"allmydata_crypttext_v1"
ciphertextSegmentTag :: B.ByteString
ciphertextSegmentTag :: ByteString
ciphertextSegmentTag = ByteString
"allmydata_crypttext_segment_v1"
ciphertextSegmentHash :: B.ByteString -> B.ByteString
ciphertextSegmentHash :: ByteString -> ByteString
ciphertextSegmentHash = Digest' SHA256d -> ByteString
forall a. ByteArrayAccess a => a -> ByteString
toBytes (Digest' SHA256d -> ByteString)
-> (ByteString -> Digest' SHA256d) -> ByteString -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HashAlgorithm SHA256d => ByteString -> Digest' SHA256d
forall hash. HashAlgorithm hash => ByteString -> Digest' hash
ciphertextSegmentHash' @SHA256d
ciphertextSegmentHash' :: HashAlgorithm hash => B.ByteString -> Digest' hash
ciphertextSegmentHash' :: ByteString -> Digest' hash
ciphertextSegmentHash' = ByteString -> ByteString -> Digest' hash
forall hash.
HashAlgorithm hash =>
ByteString -> ByteString -> Digest' hash
taggedHash' ByteString
ciphertextSegmentTag
uriExtensionTag :: B.ByteString
uriExtensionTag :: ByteString
uriExtensionTag = ByteString
"allmydata_uri_extension_v1"
uriExtensionHash :: URIExtension -> B.ByteString
uriExtensionHash :: URIExtension -> ByteString
uriExtensionHash = Int -> ByteString -> ByteString -> ByteString
taggedHash (SHA256 -> Int
forall a. HashAlgorithm a => a -> Int
hashDigestSize SHA256
SHA256) ByteString
uriExtensionTag (ByteString -> ByteString)
-> (URIExtension -> ByteString) -> URIExtension -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. URIExtension -> ByteString
uriExtensionToBytes
convergenceEncryptionTagPrefix :: B.ByteString
convergenceEncryptionTagPrefix :: ByteString
convergenceEncryptionTagPrefix = ByteString
"allmydata_immutable_content_to_key_with_added_secret_v1+"
convergenceEncryptionTag :: B.ByteString -> Parameters -> B.ByteString
convergenceEncryptionTag :: ByteString -> Parameters -> ByteString
convergenceEncryptionTag ByteString
secret (Parameters SegmentSize
segmentSize Total
total Int
_ Total
required) =
ByteString
tag
where
tag :: ByteString
tag = [ByteString] -> ByteString
B.concat [ByteString
convergenceEncryptionTagPrefix, ByteString -> ByteString
netstring ByteString
secret, ByteString -> ByteString
netstring ByteString
paramTag]
paramTag :: ByteString
paramTag = ByteString -> [ByteString] -> ByteString
B.intercalate ByteString
"," ([ByteString] -> ByteString)
-> ([SegmentSize] -> [ByteString]) -> [SegmentSize] -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (SegmentSize -> ByteString) -> [SegmentSize] -> [ByteString]
forall a b. (a -> b) -> [a] -> [b]
map SegmentSize -> ByteString
forall s. Show s => s -> ByteString
showBytes ([SegmentSize] -> ByteString) -> [SegmentSize] -> ByteString
forall a b. (a -> b) -> a -> b
$ [SegmentSize
requiredI, SegmentSize
totalI, SegmentSize
segmentSizeI]
requiredI :: SegmentSize
requiredI = Total -> SegmentSize
forall a. Integral a => a -> SegmentSize
toInteger Total
required
totalI :: SegmentSize
totalI = Total -> SegmentSize
forall a. Integral a => a -> SegmentSize
toInteger Total
total
segmentSizeI :: SegmentSize
segmentSizeI = SegmentSize -> SegmentSize
forall a. Integral a => a -> SegmentSize
toInteger SegmentSize
segmentSize
convergenceEncryptionHashLazy :: B.ByteString -> Parameters -> BL.ByteString -> B.ByteString
convergenceEncryptionHashLazy :: ByteString -> Parameters -> ByteString -> ByteString
convergenceEncryptionHashLazy ByteString
secret Parameters
params ByteString
bytes =
Int -> ByteString -> ByteString
B.take Int
convergenceSecretLength ByteString
theSHA256d
where
theSHA256d :: ByteString
theSHA256d = Digest SHA256d -> ByteString
forall a. ByteArrayAccess a => a -> ByteString
toBytes (ByteString -> Digest SHA256d
forall a. HashAlgorithm a => ByteString -> Digest a
hashlazy ByteString
toHash :: Digest SHA256d)
toHash :: BL.ByteString
toHash :: ByteString
toHash = [ByteString] -> ByteString
BL.concat [ByteString
tag, ByteString
bytes]
tag :: ByteString
tag = ByteString -> ByteString
BL.fromStrict (ByteString -> ByteString)
-> (ByteString -> ByteString) -> ByteString -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString
netstring (ByteString -> ByteString) -> ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ ByteString -> Parameters -> ByteString
convergenceEncryptionTag ByteString
secret Parameters
params
type ByteLength = Int
convergenceSecretLength :: ByteLength
convergenceSecretLength :: Int
convergenceSecretLength = Int
16
storageIndexLength :: ByteLength
storageIndexLength :: Int
storageIndexLength = Int
16