summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRoman Smrž <roman.smrz@seznam.cz>2026-10-27 22:08:47 +0100
committerRoman Smrž <roman.smrz@seznam.cz>2026-11-06 21:06:49 +0100
commite0762612e95b0816721165c5aba6189809fcde58 (patch)
tree57a2b7eed322086e6e19bfa652798d3dceceb6f6 /src
parent0bb8daa7da52240a971a4ce83d97cfb62971ea78 (diff)
ByteString conversion classes
Diffstat (limited to 'src')
-rw-r--r--src/ConvertByteString.hs45
-rw-r--r--src/Erebos/Invite.hs3
-rw-r--r--src/Erebos/Object/Internal.hs9
-rw-r--r--src/Erebos/PubKey.hs2
-rw-r--r--src/Erebos/Storage/Backend.hs4
-rw-r--r--src/Erebos/Storage/Internal.hs14
-rw-r--r--src/Erebos/Util.hs12
-rw-r--r--src/crypto/crypton/Crypto.hs38
-rw-r--r--src/crypto/reflibs/Crypto/Hash.hs4
-rw-r--r--src/crypto/reflibs/Crypto/PubKey/Ed25519.hs32
10 files changed, 124 insertions, 39 deletions
diff --git a/src/ConvertByteString.hs b/src/ConvertByteString.hs
new file mode 100644
index 0000000..6b8f39f
--- /dev/null
+++ b/src/ConvertByteString.hs
@@ -0,0 +1,45 @@
+module ConvertByteString (
+ ToByteString(..),
+ FromByteString(..),
+ ConvertByteString(..),
+ BA.ScrubbedBytes,
+) where
+
+import Data.ByteArray qualified as BA
+import Data.ByteString (ByteString)
+import Data.ByteString.Unsafe qualified as BS
+
+import Foreign.Ptr
+
+
+class ToByteString a where
+ toByteString :: a -> ByteString
+ withByteArray :: a -> (Ptr p -> IO b) -> IO b
+
+class FromByteString a where
+ fromByteString :: ByteString -> a
+
+class ConvertByteString a b where
+ convert :: a -> b
+
+
+instance ToByteString ByteString where
+ toByteString = id
+ withByteArray bs f = BS.unsafeUseAsCString bs (f . castPtr)
+
+instance FromByteString ByteString where
+ fromByteString = id
+
+instance ToByteString a => ConvertByteString a ByteString where
+ convert = toByteString
+
+
+instance ToByteString BA.ScrubbedBytes where
+ toByteString = BA.convert
+ withByteArray = BA.withByteArray
+
+instance FromByteString BA.ScrubbedBytes where
+ fromByteString = BA.convert
+
+instance BA.ByteArrayAccess a => ConvertByteString a BA.ScrubbedBytes where
+ convert = BA.convert
diff --git a/src/Erebos/Invite.hs b/src/Erebos/Invite.hs
index 69a6977..fdf90dd 100644
--- a/src/Erebos/Invite.hs
+++ b/src/Erebos/Invite.hs
@@ -31,6 +31,7 @@ import Data.Text qualified as T
import Data.Text.Encoding
import Data.Time.LocalTime
+import ConvertByteString
import Crypto
import Erebos.Contact
import Erebos.Discovery
@@ -79,7 +80,7 @@ instance Storable InviteData where
newtype InviteToken = InviteToken ByteString
- deriving (Eq, Ord, Semigroup, Monoid, ByteArray, ByteArrayAccess)
+ deriving (Eq, Ord, Semigroup, Monoid, ByteArray, ByteArrayAccess, ToByteString)
showInviteToken :: InviteToken -> String
showInviteToken (InviteToken token) = BC.unpack (showHex token)
diff --git a/src/Erebos/Object/Internal.hs b/src/Erebos/Object/Internal.hs
index 4a33dba..6f6fe6b 100644
--- a/src/Erebos/Object/Internal.hs
+++ b/src/Erebos/Object/Internal.hs
@@ -73,6 +73,7 @@ import Data.Word
import System.IO.Unsafe
+import ConvertByteString
import Crypto
import Erebos.Error
import Erebos.Storage.Internal
@@ -92,9 +93,9 @@ instance Eq (Ref' c) where
instance Show (Ref' c) where
show ref@(Ref st _) = show st ++ ":" ++ BC.unpack (showRef ref)
-instance BA.ByteArrayAccess (Ref' c) where
- length (Ref _ dgst) = BA.length dgst
- withByteArray (Ref _ dgst) = BA.withByteArray dgst
+instance ToByteString (Ref' c) where
+ withByteArray (Ref _ dgst) = withByteArray dgst
+ toByteString (Ref _ dgst) = toByteString dgst
instance Hashable (Ref' c) where
hashWithSalt salt = hashWithSalt salt . refDigest
@@ -117,7 +118,7 @@ zeroRef s = Ref s (RefDigest h)
digestAlgo = undefined
isZeroRef :: Ref' c -> Bool
-isZeroRef (Ref _ h) = all (==0) $ BA.unpack h
+isZeroRef (Ref _ h) = all (== 0) $ B.unpack $ toByteString h
refFromDigest :: Storage' c -> RefDigest -> IO (Maybe (Ref' c))
diff --git a/src/Erebos/PubKey.hs b/src/Erebos/PubKey.hs
index ef56d41..02ec8be 100644
--- a/src/Erebos/PubKey.hs
+++ b/src/Erebos/PubKey.hs
@@ -12,9 +12,9 @@ module Erebos.PubKey (
import Control.Monad
-import Data.ByteArray
import Data.Text qualified as T
+import ConvertByteString
import Crypto
import Erebos.Storable
import Erebos.Storage.Key
diff --git a/src/Erebos/Storage/Backend.hs b/src/Erebos/Storage/Backend.hs
index 07bd63e..c802d95 100644
--- a/src/Erebos/Storage/Backend.hs
+++ b/src/Erebos/Storage/Backend.hs
@@ -18,10 +18,10 @@ module Erebos.Storage.Backend (
import Control.Concurrent.MVar
-import Data.ByteArray qualified as BA
import Data.ByteString (ByteString)
import Data.HashTable.IO qualified as HT
+import ConvertByteString
import Erebos.Object.Internal
import Erebos.Storage.Internal
@@ -37,4 +37,4 @@ withStorageBackend Storage {..} f = f stBackend
refDigestBytes :: RefDigest -> ByteString
-refDigestBytes = BA.convert
+refDigestBytes = toByteString
diff --git a/src/Erebos/Storage/Internal.hs b/src/Erebos/Storage/Internal.hs
index 49a2b27..5dbe9c2 100644
--- a/src/Erebos/Storage/Internal.hs
+++ b/src/Erebos/Storage/Internal.hs
@@ -25,8 +25,7 @@ import Control.DeepSeq
import Control.Monad.Identity
import Data.Bits
-import Data.ByteArray (ByteArrayAccess, ScrubbedBytes)
-import Data.ByteArray qualified as BA
+import Data.ByteArray (ByteArrayAccess)
import Data.ByteString (ByteString)
import Data.ByteString.Char8 qualified as BC
import Data.ByteString.Lazy qualified as BL
@@ -40,6 +39,7 @@ import Foreign.Storable (peek)
import System.IO.Unsafe (unsafePerformIO)
import Crypto
+import ConvertByteString
import Erebos.UUID (UUID)
import Erebos.Util
@@ -168,13 +168,13 @@ watchListDel wid wl = wl { wlList = filter ((/= wid) . wlID) $ wlList wl }
newtype RefDigest = RefDigest (Digest Blake2b_256)
- deriving (Eq, Ord, NFData, ByteArrayAccess)
+ deriving (Eq, Ord, NFData, ByteArrayAccess, ToByteString)
instance Show RefDigest where
show = BC.unpack . showRefDigest
instance Hashable RefDigest where
- hashWithSalt salt ref = salt `xor` unsafePerformIO (BA.withByteArray ref peek)
+ hashWithSalt salt ref = salt `xor` unsafePerformIO (withByteArray ref peek)
showRefDigestParts :: RefDigest -> (ByteString, ByteString)
showRefDigestParts x = (BC.pack "blake2", showHex x)
@@ -184,9 +184,9 @@ showRefDigest = showRefDigestParts >>> \(alg, hex) -> alg <> BC.pack "#" <> hex
readRefDigest :: ByteString -> Maybe RefDigest
readRefDigest x = case BC.split '#' x of
- [alg, dgst] | BA.convert alg == BC.pack "blake2" ->
- refDigestFromByteString =<< readHex dgst
- _ -> Nothing
+ [ alg, dgst ] | alg == BC.pack "blake2" ->
+ refDigestFromByteString =<< readHex dgst
+ _ -> Nothing
refDigestFromByteString :: ByteString -> Maybe RefDigest
refDigestFromByteString = fmap RefDigest . digestFromByteString
diff --git a/src/Erebos/Util.hs b/src/Erebos/Util.hs
index 0d53e98..1c14417 100644
--- a/src/Erebos/Util.hs
+++ b/src/Erebos/Util.hs
@@ -2,12 +2,12 @@ module Erebos.Util where
import Control.Monad
-import Data.ByteArray (ByteArray, ByteArrayAccess)
-import Data.ByteArray qualified as BA
import Data.ByteString (ByteString)
import Data.ByteString qualified as B
import Data.Char
+import ConvertByteString
+
uniq :: Eq a => [a] -> [a]
uniq (x:y:xs) | x == y = uniq (x:xs)
@@ -47,15 +47,15 @@ intersectsSorted (x:xs) (y:ys) | x < y = intersectsSorted xs (y:ys)
intersectsSorted _ _ = False
-showHex :: ByteArrayAccess ba => ba -> ByteString
-showHex = B.concat . map showHexByte . BA.unpack
+showHex :: ToByteString ba => ba -> ByteString
+showHex = B.concat . map showHexByte . B.unpack . toByteString
where showHexChar x | x < 10 = x + o '0'
| otherwise = x + o 'a' - 10
showHexByte x = B.pack [ showHexChar (x `div` 16), showHexChar (x `mod` 16) ]
o = fromIntegral . ord
-readHex :: ByteArray ba => ByteString -> Maybe ba
-readHex = return . BA.concat <=< readHex'
+readHex :: FromByteString ba => ByteString -> Maybe ba
+readHex = return . fromByteString . B.concat <=< readHex'
where readHex' bs | B.null bs = Just []
readHex' bs = do (bx, bs') <- B.uncons bs
(by, bs'') <- B.uncons bs'
diff --git a/src/crypto/crypton/Crypto.hs b/src/crypto/crypton/Crypto.hs
index 7c98088..e84cec2 100644
--- a/src/crypto/crypton/Crypto.hs
+++ b/src/crypto/crypton/Crypto.hs
@@ -1,3 +1,5 @@
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+
module Crypto (
getEntropy,
getRandomBytes,
@@ -37,9 +39,17 @@ import Crypto.PubKey.Ed25519 qualified as Ed
import Crypto.Random
import Crypto.Random.Entropy
-import Data.ByteArray
+import Data.ByteArray (Bytes, ByteArray)
+import Data.ByteArray qualified as BA
import Data.ByteString (ByteString)
+import ConvertByteString
+
+
+instance ToByteString (Digest a) where
+ toByteString = BA.convert
+ withByteArray = BA.withByteArray
+
type AeadState = C.State
@@ -66,7 +76,7 @@ encrypt = C.encrypt
decrypt :: ByteArray ba => ( ba, Auth ) -> AeadState -> Maybe ba
decrypt ( ctext, auth ) st = do
let ( plain, st' ) = C.decrypt ctext st
- guard (C.finalize st' `constEq` auth)
+ guard (C.finalize st' `BA.constEq` auth)
return plain
aeadFinalize :: AeadState -> Auth
@@ -77,10 +87,14 @@ type EdPublicKey = Ed.PublicKey
type EdSecretKey = Ed.SecretKey
type EdSignature = Ed.Signature
+instance ToByteString EdSecretKey where
+ toByteString = BA.convert
+ withByteArray = BA.withByteArray
+
edPublicKey :: ByteString -> CryptoFailable EdPublicKey
edPublicKey = Ed.publicKey
-edSecretKey :: ByteArrayAccess ba => ba -> CryptoFailable EdSecretKey
+edSecretKey :: ScrubbedBytes -> CryptoFailable EdSecretKey
edSecretKey = Ed.secretKey
edGenerateSecretKey :: IO EdSecretKey
@@ -92,20 +106,28 @@ edToPublic = Ed.toPublic
edSignature :: ByteString -> CryptoFailable EdSignature
edSignature = Ed.signature
-edSign :: ByteArrayAccess ba => EdSecretKey -> EdPublicKey -> ba -> EdSignature
-edSign = Ed.sign
+edSign :: ToByteString ba => EdSecretKey -> EdPublicKey -> ba -> EdSignature
+edSign skey pkey content = Ed.sign skey pkey (toByteString content)
-edVerify :: ByteArrayAccess ba => EdPublicKey -> ba -> EdSignature -> Bool
-edVerify = Ed.verify
+edVerify :: ToByteString ba => EdPublicKey -> ba -> EdSignature -> Bool
+edVerify pkey content sig = Ed.verify pkey (toByteString content) sig
type CxPublicKey = Cx.PublicKey
type CxSecretKey = Cx.SecretKey
type DhSecret = Cx.DhSecret
+instance ToByteString CxSecretKey where
+ toByteString = BA.convert
+ withByteArray = BA.withByteArray
+
+instance ToByteString DhSecret where
+ toByteString = BA.convert
+ withByteArray = BA.withByteArray
+
cxPublicKey :: ByteString -> CryptoFailable CxPublicKey
cxPublicKey = Cx.publicKey
-cxSecretKey :: ByteArrayAccess ba => ba -> CryptoFailable CxSecretKey
+cxSecretKey :: ScrubbedBytes -> CryptoFailable CxSecretKey
cxSecretKey = Cx.secretKey
cxGenerateSecretKey :: IO CxSecretKey
diff --git a/src/crypto/reflibs/Crypto/Hash.hs b/src/crypto/reflibs/Crypto/Hash.hs
index 36308f9..4d83e5d 100644
--- a/src/crypto/reflibs/Crypto/Hash.hs
+++ b/src/crypto/reflibs/Crypto/Hash.hs
@@ -26,9 +26,11 @@ import Foreign.Storable
import System.IO.Unsafe
+import ConvertByteString
+
newtype Digest a = Digest ByteString
- deriving (Eq, Ord, NFData, ByteArrayAccess)
+ deriving (Eq, Ord, NFData, ByteArrayAccess, ToByteString)
data Context a = Context (ForeignPtr Blake2bContext)
diff --git a/src/crypto/reflibs/Crypto/PubKey/Ed25519.hs b/src/crypto/reflibs/Crypto/PubKey/Ed25519.hs
index 88c7302..a4c24c0 100644
--- a/src/crypto/reflibs/Crypto/PubKey/Ed25519.hs
+++ b/src/crypto/reflibs/Crypto/PubKey/Ed25519.hs
@@ -16,10 +16,12 @@ import Crypto.Error
import Crypto.Random
import Crypto.Sign.Ed25519 qualified as Ed
-import Data.ByteArray as BA
+import Data.ByteArray qualified as BA
import Data.ByteString (ByteString)
import Data.ByteString qualified as BS
+import ConvertByteString
+
newtype EdSecretKey = EdSecretKey { fromSecretKey :: Ed.SecretKey }
deriving (Eq)
@@ -34,16 +36,28 @@ instance Show EdSecretKey where show = show . fromSecretKey
instance Show EdPublicKey where show = show . fromPublicKey
instance Show EdSignature where show = show . fromSignature
-instance ByteArrayAccess EdSecretKey where
+instance BA.ByteArrayAccess EdSecretKey where
length = BS.length . Ed.openSecretKey . fromSecretKey
- withByteArray = withByteArray . Ed.openSecretKey . fromSecretKey
+ withByteArray = BA.withByteArray . Ed.openSecretKey . fromSecretKey
-instance ByteArrayAccess EdPublicKey where
+instance BA.ByteArrayAccess EdPublicKey where
length = BS.length . Ed.openPublicKey . fromPublicKey
- withByteArray = withByteArray . Ed.openPublicKey . fromPublicKey
+ withByteArray = BA.withByteArray . Ed.openPublicKey . fromPublicKey
-instance ByteArrayAccess EdSignature where
+instance BA.ByteArrayAccess EdSignature where
length = BS.length . Ed.unSignature . fromSignature
+ withByteArray = BA.withByteArray . Ed.unSignature . fromSignature
+
+instance ToByteString EdSecretKey where
+ toByteString = Ed.openSecretKey . fromSecretKey
+ withByteArray = withByteArray . Ed.openSecretKey . fromSecretKey
+
+instance ToByteString EdPublicKey where
+ toByteString = Ed.openPublicKey . fromPublicKey
+ withByteArray = withByteArray . Ed.openPublicKey . fromPublicKey
+
+instance ToByteString EdSignature where
+ toByteString = Ed.unSignature . fromSignature
withByteArray = withByteArray . Ed.unSignature . fromSignature
signatureSize :: Int
@@ -57,16 +71,16 @@ edSignature bs
edPublicKey :: ByteString -> CryptoFailable EdPublicKey
edPublicKey = maybe (CryptoFailed CryptoError) (CryptoPassed . EdPublicKey) . Ed.makePublicKey . convert
-edSecretKey :: ByteArrayAccess ba => ba -> CryptoFailable EdSecretKey
+edSecretKey :: ScrubbedBytes -> CryptoFailable EdSecretKey
edSecretKey = maybe (CryptoFailed CryptoError) (CryptoPassed . EdSecretKey) . Ed.makeSecretKey . convert
edToPublic :: EdSecretKey -> EdPublicKey
edToPublic = EdPublicKey . Ed.secretToPublicKey . fromSecretKey
-edSign :: ByteArrayAccess ba => EdSecretKey -> EdPublicKey -> ba -> EdSignature
+edSign :: ToByteString ba => EdSecretKey -> EdPublicKey -> ba -> EdSignature
edSign (EdSecretKey key) _ = EdSignature . Ed.dsign key . convert
-edVerify :: ByteArrayAccess ba => EdPublicKey -> ba -> EdSignature -> Bool
+edVerify :: ToByteString ba => EdPublicKey -> ba -> EdSignature -> Bool
edVerify (EdPublicKey pub) msg (EdSignature sig) = Ed.dverify pub (convert msg) sig
edGenerateSecretKey :: IO EdSecretKey