{-# LANGUAGE TypeApplications #-}
module Sel.Scrypt
(
ScryptHash
, scryptHashPassword
, scryptVerifyPassword
, scryptHashToByteString
, scryptHashToText
, asciiTextToScryptHash
, asciiByteStringToScryptHash
)
where
import Control.Monad (void)
import Data.ByteString (StrictByteString)
import qualified Data.ByteString.Internal as BS
import Data.ByteString.Unsafe (unsafeUseAsCStringLen)
import Data.Text as Text
import qualified Data.Text.Builder.Linear as Builder
import Data.Text.Display
import qualified Data.Text.Encoding as Text
import Foreign hiding (void)
import Foreign.C
import LibSodium.Bindings.Scrypt
import Sel.Internal
import Sel.Internal.Sodium (binaryToHex)
newtype ScryptHash = ScryptHash (ForeignPtr CChar)
instance Eq ScryptHash where
(ScryptHash ForeignPtr CChar
sh1) == :: ScryptHash -> ScryptHash -> Bool
== (ScryptHash ForeignPtr CChar
sh2) =
ForeignPtr CUChar -> ForeignPtr CUChar -> CSize -> Bool
foreignPtrEq
(forall a b. ForeignPtr a -> ForeignPtr b
Foreign.castForeignPtr @CChar @CUChar ForeignPtr CChar
sh1)
(forall a b. ForeignPtr a -> ForeignPtr b
Foreign.castForeignPtr @CChar @CUChar ForeignPtr CChar
sh2)
CSize
cryptoPWHashScryptSalsa208SHA256StrBytes
instance Ord ScryptHash where
compare :: ScryptHash -> ScryptHash -> Ordering
compare (ScryptHash ForeignPtr CChar
sh1) (ScryptHash ForeignPtr CChar
sh2) =
ForeignPtr CUChar -> ForeignPtr CUChar -> CSize -> Ordering
foreignPtrOrd
(forall a b. ForeignPtr a -> ForeignPtr b
Foreign.castForeignPtr @CChar @CUChar ForeignPtr CChar
sh1)
(forall a b. ForeignPtr a -> ForeignPtr b
Foreign.castForeignPtr @CChar @CUChar ForeignPtr CChar
sh2)
CSize
cryptoPWHashScryptSalsa208SHA256StrBytes
instance Show ScryptHash where
show :: ScryptHash -> String
show = Text -> String
Text.unpack (Text -> String) -> (ScryptHash -> Text) -> ScryptHash -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScryptHash -> Text
scryptHashToText
instance Display ScryptHash where
displayBuilder :: ScryptHash -> Builder
displayBuilder = Text -> Builder
Builder.fromText (Text -> Builder) -> (ScryptHash -> Text) -> ScryptHash -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScryptHash -> Text
scryptHashToText
scryptHashPassword :: StrictByteString -> IO ScryptHash
scryptHashPassword :: StrictByteString -> IO ScryptHash
scryptHashPassword StrictByteString
bytestring = do
StrictByteString -> (CStringLen -> IO ScryptHash) -> IO ScryptHash
forall a. StrictByteString -> (CStringLen -> IO a) -> IO a
unsafeUseAsCStringLen StrictByteString
bytestring ((CStringLen -> IO ScryptHash) -> IO ScryptHash)
-> (CStringLen -> IO ScryptHash) -> IO ScryptHash
forall a b. (a -> b) -> a -> b
$ \(Ptr CChar
cString, Int
cStringLen) -> do
hashForeignPtr <- Int -> IO (ForeignPtr CChar)
forall a. Int -> IO (ForeignPtr a)
mallocForeignPtrBytes (CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
cryptoPWHashScryptSalsa208SHA256StrBytes)
withForeignPtr hashForeignPtr $ \Ptr CChar
hashPtr ->
IO CInt -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (IO CInt -> IO ()) -> IO CInt -> IO ()
forall a b. (a -> b) -> a -> b
$
Ptr CChar -> Ptr CChar -> CULLong -> CULLong -> CSize -> IO CInt
cryptoPWHashScryptSalsa208SHA256Str
Ptr CChar
hashPtr
Ptr CChar
cString
(Int -> CULLong
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
cStringLen)
(CSize -> CULLong
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
cryptoPWHashScryptSalsa208SHA256OpsLimitInteractive)
CSize
cryptoPWHashScryptSalsa208SHA256MemLimitInteractive
pure $ ScryptHash hashForeignPtr
scryptVerifyPassword :: StrictByteString -> ScryptHash -> IO Bool
scryptVerifyPassword :: StrictByteString -> ScryptHash -> IO Bool
scryptVerifyPassword StrictByteString
bytestring (ScryptHash ForeignPtr CChar
sh) = do
StrictByteString -> (CStringLen -> IO Bool) -> IO Bool
forall a. StrictByteString -> (CStringLen -> IO a) -> IO a
unsafeUseAsCStringLen StrictByteString
bytestring ((CStringLen -> IO Bool) -> IO Bool)
-> (CStringLen -> IO Bool) -> IO Bool
forall a b. (a -> b) -> a -> b
$ \(Ptr CChar
cString, Int
cStringLen) -> do
ForeignPtr CChar -> (Ptr CChar -> IO Bool) -> IO Bool
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr CChar
sh ((Ptr CChar -> IO Bool) -> IO Bool)
-> (Ptr CChar -> IO Bool) -> IO Bool
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
scryptHash -> do
result <-
Ptr CChar -> Ptr CChar -> CULLong -> IO CInt
cryptoPWHashScryptSalsa208SHA256StrVerify
Ptr CChar
scryptHash
Ptr CChar
cString
(Int -> CULLong
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
cStringLen)
return (result == 0)
scryptHashToByteString :: ScryptHash -> StrictByteString
scryptHashToByteString :: ScryptHash -> StrictByteString
scryptHashToByteString (ScryptHash ForeignPtr CChar
fPtr) =
ForeignPtr CUChar -> CSize -> StrictByteString
binaryToHex (forall a b. ForeignPtr a -> ForeignPtr b
Foreign.castForeignPtr @CChar @CUChar ForeignPtr CChar
fPtr) CSize
cryptoPWHashScryptSalsa208SHA256StrBytes
scryptHashToText :: ScryptHash -> Text
scryptHashToText :: ScryptHash -> Text
scryptHashToText = StrictByteString -> Text
Text.decodeASCII (StrictByteString -> Text)
-> (ScryptHash -> StrictByteString) -> ScryptHash -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScryptHash -> StrictByteString
scryptHashToByteString
asciiByteStringToScryptHash :: StrictByteString -> ScryptHash
asciiByteStringToScryptHash :: StrictByteString -> ScryptHash
asciiByteStringToScryptHash StrictByteString
textualHash =
let (ForeignPtr Word8
fPtr, Int
_length) = StrictByteString -> (ForeignPtr Word8, Int)
BS.toForeignPtr0 StrictByteString
textualHash
in ForeignPtr CChar -> ScryptHash
ScryptHash (forall a b. ForeignPtr a -> ForeignPtr b
castForeignPtr @Word8 @CChar ForeignPtr Word8
fPtr)
asciiTextToScryptHash :: Text -> ScryptHash
asciiTextToScryptHash :: Text -> ScryptHash
asciiTextToScryptHash = StrictByteString -> ScryptHash
asciiByteStringToScryptHash (StrictByteString -> ScryptHash)
-> (Text -> StrictByteString) -> Text -> ScryptHash
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> StrictByteString
Text.encodeUtf8