{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ImportQualifiedPost #-}
module Crypto.Secp256k1
(
Msg,
msg,
getMsg,
SecKey,
secKey,
getSecKey,
derivePubKey,
PubKey,
importPubKey,
exportPubKey,
Sig,
signMsg,
verifySig,
normalizeSig,
importSig,
exportSig,
CompactSig,
getCompactSig,
compactSig,
exportCompactSig,
importCompactSig,
Tweak,
tweak,
getTweak,
tweakAddSecKey,
tweakMulSecKey,
tweakAddPubKey,
tweakMulPubKey,
combinePubKeys,
tweakNegate,
)
where
import Control.DeepSeq (NFData)
import Control.Monad (replicateM, unless, (<=<))
import Crypto.Secp256k1.Internal
import Data.Base16.Types (assertBase16, extractBase16)
import Data.ByteString (ByteString)
import Data.ByteString qualified as BS
import Data.ByteString.Base16 (decodeBase16, encodeBase16, isBase16)
import Data.Hashable (Hashable (..))
import Data.Maybe (fromJust, fromMaybe, isJust)
import Data.Serialize
( Serialize (..),
getByteString,
putByteString,
)
import Data.String (IsString (..))
import Data.String.Conversions (ConvertibleStrings, cs)
import Foreign
( alloca,
allocaArray,
allocaBytes,
free,
mallocBytes,
nullFunPtr,
nullPtr,
peek,
poke,
pokeArray,
)
import GHC.Generics (Generic)
import System.IO.Unsafe (unsafePerformIO)
import Test.QuickCheck
( Arbitrary (..),
arbitraryBoundedRandom,
suchThat,
)
import Text.Read
( Lexeme (String),
lexP,
parens,
pfail,
readPrec,
)
newtype PubKey = PubKey {PubKey -> ByteString
getPubKey :: ByteString}
deriving (PubKey -> PubKey -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PubKey -> PubKey -> Bool
$c/= :: PubKey -> PubKey -> Bool
== :: PubKey -> PubKey -> Bool
$c== :: PubKey -> PubKey -> Bool
Eq, forall x. Rep PubKey x -> PubKey
forall x. PubKey -> Rep PubKey x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep PubKey x -> PubKey
$cfrom :: forall x. PubKey -> Rep PubKey x
Generic, PubKey -> ()
forall a. (a -> ()) -> NFData a
rnf :: PubKey -> ()
$crnf :: PubKey -> ()
NFData)
newtype Msg = Msg {Msg -> ByteString
getMsg :: ByteString}
deriving (Msg -> Msg -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Msg -> Msg -> Bool
$c/= :: Msg -> Msg -> Bool
== :: Msg -> Msg -> Bool
$c== :: Msg -> Msg -> Bool
Eq, forall x. Rep Msg x -> Msg
forall x. Msg -> Rep Msg x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Msg x -> Msg
$cfrom :: forall x. Msg -> Rep Msg x
Generic, Msg -> ()
forall a. (a -> ()) -> NFData a
rnf :: Msg -> ()
$crnf :: Msg -> ()
NFData)
newtype Sig = Sig {Sig -> ByteString
getSig :: ByteString}
deriving (Sig -> Sig -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Sig -> Sig -> Bool
$c/= :: Sig -> Sig -> Bool
== :: Sig -> Sig -> Bool
$c== :: Sig -> Sig -> Bool
Eq, forall x. Rep Sig x -> Sig
forall x. Sig -> Rep Sig x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Sig x -> Sig
$cfrom :: forall x. Sig -> Rep Sig x
Generic, Sig -> ()
forall a. (a -> ()) -> NFData a
rnf :: Sig -> ()
$crnf :: Sig -> ()
NFData)
newtype SecKey = SecKey {SecKey -> ByteString
getSecKey :: ByteString}
deriving (SecKey -> SecKey -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SecKey -> SecKey -> Bool
$c/= :: SecKey -> SecKey -> Bool
== :: SecKey -> SecKey -> Bool
$c== :: SecKey -> SecKey -> Bool
Eq, forall x. Rep SecKey x -> SecKey
forall x. SecKey -> Rep SecKey x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep SecKey x -> SecKey
$cfrom :: forall x. SecKey -> Rep SecKey x
Generic, SecKey -> ()
forall a. (a -> ()) -> NFData a
rnf :: SecKey -> ()
$crnf :: SecKey -> ()
NFData)
newtype Tweak = Tweak {Tweak -> ByteString
getTweak :: ByteString}
deriving (Tweak -> Tweak -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Tweak -> Tweak -> Bool
$c/= :: Tweak -> Tweak -> Bool
== :: Tweak -> Tweak -> Bool
$c== :: Tweak -> Tweak -> Bool
Eq, forall x. Rep Tweak x -> Tweak
forall x. Tweak -> Rep Tweak x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Tweak x -> Tweak
$cfrom :: forall x. Tweak -> Rep Tweak x
Generic, Tweak -> ()
forall a. (a -> ()) -> NFData a
rnf :: Tweak -> ()
$crnf :: Tweak -> ()
NFData)
newtype CompactSig = CompactSig {CompactSig -> ByteString
getCompactSig :: ByteString}
deriving (CompactSig -> CompactSig -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CompactSig -> CompactSig -> Bool
$c/= :: CompactSig -> CompactSig -> Bool
== :: CompactSig -> CompactSig -> Bool
$c== :: CompactSig -> CompactSig -> Bool
Eq, forall x. Rep CompactSig x -> CompactSig
forall x. CompactSig -> Rep CompactSig x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep CompactSig x -> CompactSig
$cfrom :: forall x. CompactSig -> Rep CompactSig x
Generic, CompactSig -> ()
forall a. (a -> ()) -> NFData a
rnf :: CompactSig -> ()
$crnf :: CompactSig -> ()
NFData)
instance Serialize PubKey where
put :: Putter PubKey
put (PubKey ByteString
bs) = Putter ByteString
putByteString ByteString
bs
get :: Get PubKey
get = ByteString -> PubKey
PubKey forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Get ByteString
getByteString Int
64
instance Serialize Msg where
put :: Putter Msg
put (Msg ByteString
m) = Putter ByteString
putByteString ByteString
m
get :: Get Msg
get = ByteString -> Msg
Msg forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Get ByteString
getByteString Int
32
instance Serialize Sig where
put :: Putter Sig
put (Sig ByteString
bs) = Putter ByteString
putByteString ByteString
bs
get :: Get Sig
get = ByteString -> Sig
Sig forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Get ByteString
getByteString Int
64
instance Serialize SecKey where
put :: Putter SecKey
put (SecKey ByteString
bs) = Putter ByteString
putByteString ByteString
bs
get :: Get SecKey
get = ByteString -> SecKey
SecKey forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Get ByteString
getByteString Int
32
instance Serialize Tweak where
put :: Putter Tweak
put (Tweak ByteString
bs) = Putter ByteString
putByteString ByteString
bs
get :: Get Tweak
get = ByteString -> Tweak
Tweak forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Get ByteString
getByteString Int
32
instance Serialize CompactSig where
put :: Putter CompactSig
put (CompactSig ByteString
bs) = Putter ByteString
putByteString ByteString
bs
get :: Get CompactSig
get = ByteString -> CompactSig
CompactSig forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Get ByteString
getByteString Int
64
decodeHex :: (ConvertibleStrings a ByteString) => a -> Maybe ByteString
decodeHex :: forall a. ConvertibleStrings a ByteString => a -> Maybe ByteString
decodeHex a
str =
if ByteString -> Bool
isBase16 forall a b. (a -> b) -> a -> b
$ forall a b. ConvertibleStrings a b => a -> b
cs a
str
then forall a. a -> Maybe a
Just forall b c a. (b -> c) -> (a -> b) -> a -> c
. Base16 ByteString -> ByteString
decodeBase16 forall a b. (a -> b) -> a -> b
$ forall a. a -> Base16 a
assertBase16 forall a b. (a -> b) -> a -> b
$ forall a b. ConvertibleStrings a b => a -> b
cs a
str
else forall a. Maybe a
Nothing
instance Read PubKey where
readPrec :: ReadPrec PubKey
readPrec = do
String String
str <- ReadPrec Lexeme
lexP
forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. ReadPrec a
pfail forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ ByteString -> Maybe PubKey
importPubKey forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a. ConvertibleStrings a ByteString => a -> Maybe ByteString
decodeHex String
str
instance Hashable PubKey where
Int
i hashWithSalt :: Int -> PubKey -> Int
`hashWithSalt` PubKey
k = Int
i forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Bool -> PubKey -> ByteString
exportPubKey Bool
True PubKey
k
instance IsString PubKey where
fromString :: String -> PubKey
fromString = forall a. a -> Maybe a -> a
fromMaybe forall {a}. a
e forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ByteString -> Maybe PubKey
importPubKey forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall a. ConvertibleStrings a ByteString => a -> Maybe ByteString
decodeHex)
where
e :: a
e = forall a. HasCallStack => String -> a
error String
"Could not decode public key from hex string"
instance Show PubKey where
showsPrec :: Int -> PubKey -> ShowS
showsPrec Int
_ = forall a. Show a => a -> ShowS
shows forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Base16 a -> a
extractBase16 forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Base16 Text
encodeBase16 forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> PubKey -> ByteString
exportPubKey Bool
True
instance Read Msg where
readPrec :: ReadPrec Msg
readPrec = forall a. ReadPrec a -> ReadPrec a
parens forall a b. (a -> b) -> a -> b
$ do
String String
str <- ReadPrec Lexeme
lexP
forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. ReadPrec a
pfail forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ ByteString -> Maybe Msg
msg forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a. ConvertibleStrings a ByteString => a -> Maybe ByteString
decodeHex String
str
instance Hashable Msg where
Int
i hashWithSalt :: Int -> Msg -> Int
`hashWithSalt` Msg
m = Int
i forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Msg -> ByteString
getMsg Msg
m
instance IsString Msg where
fromString :: String -> Msg
fromString = forall a. a -> Maybe a -> a
fromMaybe forall {a}. a
e forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ByteString -> Maybe Msg
msg forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall a. ConvertibleStrings a ByteString => a -> Maybe ByteString
decodeHex)
where
e :: a
e = forall a. HasCallStack => String -> a
error String
"Could not decode message from hex string"
instance Show Msg where
showsPrec :: Int -> Msg -> ShowS
showsPrec Int
_ = forall a. Show a => a -> ShowS
shows forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Base16 a -> a
extractBase16 forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Base16 Text
encodeBase16 forall b c a. (b -> c) -> (a -> b) -> a -> c
. Msg -> ByteString
getMsg
instance Read Sig where
readPrec :: ReadPrec Sig
readPrec = forall a. ReadPrec a -> ReadPrec a
parens forall a b. (a -> b) -> a -> b
$ do
String String
str <- ReadPrec Lexeme
lexP
forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. ReadPrec a
pfail forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ ByteString -> Maybe Sig
importSig forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a. ConvertibleStrings a ByteString => a -> Maybe ByteString
decodeHex String
str
instance IsString Sig where
fromString :: String -> Sig
fromString = forall a. a -> Maybe a -> a
fromMaybe forall {a}. a
e forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ByteString -> Maybe Sig
importSig forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall a. ConvertibleStrings a ByteString => a -> Maybe ByteString
decodeHex)
where
e :: a
e = forall a. HasCallStack => String -> a
error String
"Could not decode signature from hex string"
instance Hashable Sig where
Int
i hashWithSalt :: Int -> Sig -> Int
`hashWithSalt` Sig
s = Int
i forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Sig -> ByteString
exportSig Sig
s
instance Show Sig where
showsPrec :: Int -> Sig -> ShowS
showsPrec Int
_ = forall a. Show a => a -> ShowS
shows forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Base16 a -> a
extractBase16 forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Base16 Text
encodeBase16 forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sig -> ByteString
exportSig
instance Read SecKey where
readPrec :: ReadPrec SecKey
readPrec = forall a. ReadPrec a -> ReadPrec a
parens forall a b. (a -> b) -> a -> b
$ do
String String
str <- ReadPrec Lexeme
lexP
forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. ReadPrec a
pfail forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ ByteString -> Maybe SecKey
secKey forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a. ConvertibleStrings a ByteString => a -> Maybe ByteString
decodeHex String
str
instance Hashable SecKey where
Int
i hashWithSalt :: Int -> SecKey -> Int
`hashWithSalt` SecKey
k = Int
i forall a. Hashable a => Int -> a -> Int
`hashWithSalt` SecKey -> ByteString
getSecKey SecKey
k
instance IsString SecKey where
fromString :: String -> SecKey
fromString = forall a. a -> Maybe a -> a
fromMaybe forall {a}. a
e forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ByteString -> Maybe SecKey
secKey forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall a. ConvertibleStrings a ByteString => a -> Maybe ByteString
decodeHex)
where
e :: a
e = forall a. HasCallStack => String -> a
error String
"Colud not decode secret key from hex string"
instance Show SecKey where
showsPrec :: Int -> SecKey -> ShowS
showsPrec Int
_ = forall a. Show a => a -> ShowS
shows forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Base16 a -> a
extractBase16 forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Base16 Text
encodeBase16 forall b c a. (b -> c) -> (a -> b) -> a -> c
. SecKey -> ByteString
getSecKey
instance Hashable Tweak where
Int
i hashWithSalt :: Int -> Tweak -> Int
`hashWithSalt` Tweak
t = Int
i forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Tweak -> ByteString
getTweak Tweak
t
instance Read Tweak where
readPrec :: ReadPrec Tweak
readPrec = forall a. ReadPrec a -> ReadPrec a
parens forall a b. (a -> b) -> a -> b
$ do
String String
str <- ReadPrec Lexeme
lexP
forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. ReadPrec a
pfail forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ ByteString -> Maybe Tweak
tweak forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall a. ConvertibleStrings a ByteString => a -> Maybe ByteString
decodeHex String
str
instance IsString Tweak where
fromString :: String -> Tweak
fromString = forall a. a -> Maybe a -> a
fromMaybe forall {a}. a
e forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ByteString -> Maybe Tweak
tweak forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall a. ConvertibleStrings a ByteString => a -> Maybe ByteString
decodeHex)
where
e :: a
e = forall a. HasCallStack => String -> a
error String
"Could not decode tweak from hex string"
instance Show Tweak where
showsPrec :: Int -> Tweak -> ShowS
showsPrec Int
_ = forall a. Show a => a -> ShowS
shows forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Base16 a -> a
extractBase16 forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Base16 Text
encodeBase16 forall b c a. (b -> c) -> (a -> b) -> a -> c
. Tweak -> ByteString
getTweak
msg :: ByteString -> Maybe Msg
msg :: ByteString -> Maybe Msg
msg ByteString
bs
| ByteString -> Int
BS.length ByteString
bs forall a. Eq a => a -> a -> Bool
== Int
32 = forall a. a -> Maybe a
Just (ByteString -> Msg
Msg ByteString
bs)
| Bool
otherwise = forall a. Maybe a
Nothing
secKey :: ByteString -> Maybe SecKey
secKey :: ByteString -> Maybe SecKey
secKey ByteString
bs
| ByteString -> Int
BS.length ByteString
bs forall a. Eq a => a -> a -> Bool
== Int
32 = forall a. a -> Maybe a
Just (ByteString -> SecKey
SecKey ByteString
bs)
| Bool
otherwise = forall a. Maybe a
Nothing
compactSig :: ByteString -> Maybe CompactSig
compactSig :: ByteString -> Maybe CompactSig
compactSig ByteString
bs
| ByteString -> Int
BS.length ByteString
bs forall a. Eq a => a -> a -> Bool
== Int
64 = forall a. a -> Maybe a
Just (ByteString -> CompactSig
CompactSig ByteString
bs)
| Bool
otherwise = forall a. Maybe a
Nothing
normalizeSig :: Sig -> Maybe Sig
normalizeSig :: Sig -> Maybe Sig
normalizeSig (Sig ByteString
sig) = forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
sig forall a b. (a -> b) -> a -> b
$ \(Ptr Sig64
sig_in, CSize
_) -> do
Ptr Sig64
sig_out <- forall a. Int -> IO (Ptr a)
mallocBytes Int
64
CInt
ret <- Ctx -> Ptr Sig64 -> Ptr Sig64 -> IO CInt
ecdsaSignatureNormalize Ctx
ctx Ptr Sig64
sig_out Ptr Sig64
sig_in
if CInt -> Bool
isSuccess CInt
ret
then do
ByteString
bs <- forall a. (Ptr a, CSize) -> IO ByteString
unsafePackByteString (Ptr Sig64
sig_out, CSize
64)
forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Maybe a
Just (ByteString -> Sig
Sig ByteString
bs))
else do
forall a. Ptr a -> IO ()
free Ptr Sig64
sig_out
forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
tweak :: ByteString -> Maybe Tweak
tweak :: ByteString -> Maybe Tweak
tweak ByteString
bs
| ByteString -> Int
BS.length ByteString
bs forall a. Eq a => a -> a -> Bool
== Int
32 = forall a. a -> Maybe a
Just (ByteString -> Tweak
Tweak ByteString
bs)
| Bool
otherwise = forall a. Maybe a
Nothing
importPubKey :: ByteString -> Maybe PubKey
importPubKey :: ByteString -> Maybe PubKey
importPubKey ByteString
bs
| ByteString -> Bool
BS.null ByteString
bs = forall a. Maybe a
Nothing
| Bool
otherwise = forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
bs forall a b. (a -> b) -> a -> b
$ \(Ptr CUChar
input, CSize
len) -> do
Ptr PubKey64
pub_key <- forall a. Int -> IO (Ptr a)
mallocBytes Int
64
CInt
ret <- Ctx -> Ptr PubKey64 -> Ptr CUChar -> CSize -> IO CInt
ecPubKeyParse Ctx
ctx Ptr PubKey64
pub_key Ptr CUChar
input CSize
len
if CInt -> Bool
isSuccess CInt
ret
then do
ByteString
out <- forall a. (Ptr a, CSize) -> IO ByteString
unsafePackByteString (Ptr PubKey64
pub_key, CSize
64)
forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Maybe a
Just (ByteString -> PubKey
PubKey ByteString
out))
else do
forall a. Ptr a -> IO ()
free Ptr PubKey64
pub_key
forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
exportPubKey :: Bool -> PubKey -> ByteString
exportPubKey :: Bool -> PubKey -> ByteString
exportPubKey Bool
compress (PubKey ByteString
in_bs) = forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
in_bs forall a b. (a -> b) -> a -> b
$ \(Ptr PubKey64
in_ptr, CSize
_) ->
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca forall a b. (a -> b) -> a -> b
$ \Ptr CSize
len_ptr ->
forall a b. Int -> (Ptr a -> IO b) -> IO b
allocaBytes Int
len forall a b. (a -> b) -> a -> b
$ \Ptr CUChar
out_ptr -> do
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr CSize
len_ptr forall a b. (a -> b) -> a -> b
$ forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len
CInt
ret <- Ctx
-> Ptr CUChar -> Ptr CSize -> Ptr PubKey64 -> SerFlags -> IO CInt
ecPubKeySerialize Ctx
ctx Ptr CUChar
out_ptr Ptr CSize
len_ptr Ptr PubKey64
in_ptr SerFlags
flags
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (CInt -> Bool
isSuccess CInt
ret) forall a b. (a -> b) -> a -> b
$ forall a. HasCallStack => String -> a
error String
"could not serialize public key"
CSize
final_len <- forall a. Storable a => Ptr a -> IO a
peek Ptr CSize
len_ptr
forall a. (Ptr a, CSize) -> IO ByteString
packByteString (Ptr CUChar
out_ptr, CSize
final_len)
where
len :: Int
len = if Bool
compress then Int
33 else Int
65
flags :: SerFlags
flags = if Bool
compress then SerFlags
compressed else SerFlags
uncompressed
exportCompactSig :: Sig -> CompactSig
exportCompactSig :: Sig -> CompactSig
exportCompactSig (Sig ByteString
sig_bs) = forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
sig_bs forall a b. (a -> b) -> a -> b
$ \(Ptr Sig64
sig_ptr, CSize
_) -> do
Ptr Compact64
out_ptr <- forall a. Int -> IO (Ptr a)
mallocBytes Int
64
CInt
ret <- Ctx -> Ptr Compact64 -> Ptr Sig64 -> IO CInt
ecdsaSignatureSerializeCompact Ctx
ctx Ptr Compact64
out_ptr Ptr Sig64
sig_ptr
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (CInt -> Bool
isSuccess CInt
ret) forall a b. (a -> b) -> a -> b
$ do
forall a. Ptr a -> IO ()
free Ptr Compact64
out_ptr
forall a. HasCallStack => String -> a
error String
"Could not obtain compact signature"
ByteString
out_bs <- forall a. (Ptr a, CSize) -> IO ByteString
unsafePackByteString (Ptr Compact64
out_ptr, CSize
64)
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ ByteString -> CompactSig
CompactSig ByteString
out_bs
importCompactSig :: CompactSig -> Maybe Sig
importCompactSig :: CompactSig -> Maybe Sig
importCompactSig (CompactSig ByteString
compact_sig) = forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
compact_sig forall a b. (a -> b) -> a -> b
$ \(Ptr Compact64
compact_ptr, CSize
_) -> do
Ptr Sig64
out_sig <- forall a. Int -> IO (Ptr a)
mallocBytes Int
64
CInt
ret <- Ctx -> Ptr Sig64 -> Ptr Compact64 -> IO CInt
ecdsaSignatureParseCompact Ctx
ctx Ptr Sig64
out_sig Ptr Compact64
compact_ptr
if CInt -> Bool
isSuccess CInt
ret
then do
ByteString
out_bs <- forall a. (Ptr a, CSize) -> IO ByteString
unsafePackByteString (Ptr Sig64
out_sig, CSize
64)
forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Maybe a
Just (ByteString -> Sig
Sig ByteString
out_bs))
else do
forall a. Ptr a -> IO ()
free Ptr Sig64
out_sig
forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
importSig :: ByteString -> Maybe Sig
importSig :: ByteString -> Maybe Sig
importSig ByteString
bs
| ByteString -> Bool
BS.null ByteString
bs = forall a. Maybe a
Nothing
| Bool
otherwise = forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
bs forall a b. (a -> b) -> a -> b
$ \(Ptr CUChar
in_ptr, CSize
in_len) -> do
Ptr Sig64
out_sig <- forall a. Int -> IO (Ptr a)
mallocBytes Int
64
CInt
ret <- Ctx -> Ptr Sig64 -> Ptr CUChar -> CSize -> IO CInt
ecdsaSignatureParseDer Ctx
ctx Ptr Sig64
out_sig Ptr CUChar
in_ptr CSize
in_len
if CInt -> Bool
isSuccess CInt
ret
then do
ByteString
out_bs <- forall a. (Ptr a, CSize) -> IO ByteString
unsafePackByteString (Ptr Sig64
out_sig, CSize
64)
forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Maybe a
Just (ByteString -> Sig
Sig ByteString
out_bs))
else do
forall a. Ptr a -> IO ()
free Ptr Sig64
out_sig
forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
exportSig :: Sig -> ByteString
exportSig :: Sig -> ByteString
exportSig (Sig ByteString
in_sig) = forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
in_sig forall a b. (a -> b) -> a -> b
$ \(Ptr Sig64
in_ptr, CSize
_) ->
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca forall a b. (a -> b) -> a -> b
$ \Ptr CSize
out_len ->
forall a b. Int -> (Ptr a -> IO b) -> IO b
allocaBytes Int
72 forall a b. (a -> b) -> a -> b
$ \Ptr CUChar
out_ptr -> do
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr CSize
out_len CSize
72
CInt
ret <- Ctx -> Ptr CUChar -> Ptr CSize -> Ptr Sig64 -> IO CInt
ecdsaSignatureSerializeDer Ctx
ctx Ptr CUChar
out_ptr Ptr CSize
out_len Ptr Sig64
in_ptr
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (CInt -> Bool
isSuccess CInt
ret) forall a b. (a -> b) -> a -> b
$ forall a. HasCallStack => String -> a
error String
"could not serialize signature"
CSize
final_len <- forall a. Storable a => Ptr a -> IO a
peek Ptr CSize
out_len
forall a. (Ptr a, CSize) -> IO ByteString
packByteString (Ptr CUChar
out_ptr, CSize
final_len)
verifySig :: PubKey -> Sig -> Msg -> Bool
verifySig :: PubKey -> Sig -> Msg -> Bool
verifySig (PubKey ByteString
pub_key) (Sig ByteString
sig) (Msg ByteString
m) = forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
pub_key forall a b. (a -> b) -> a -> b
$ \(Ptr PubKey64
pub_key_ptr, CSize
_) ->
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
sig forall a b. (a -> b) -> a -> b
$ \(Ptr Sig64
sig_ptr, CSize
_) ->
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
m forall a b. (a -> b) -> a -> b
$ \(Ptr Msg32
msg_ptr, CSize
_) ->
CInt -> Bool
isSuccess forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ctx -> Ptr Sig64 -> Ptr Msg32 -> Ptr PubKey64 -> IO CInt
ecdsaVerify Ctx
ctx Ptr Sig64
sig_ptr Ptr Msg32
msg_ptr Ptr PubKey64
pub_key_ptr
signMsg :: SecKey -> Msg -> Sig
signMsg :: SecKey -> Msg -> Sig
signMsg (SecKey ByteString
sec_key) (Msg ByteString
m) = forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
sec_key forall a b. (a -> b) -> a -> b
$ \(Ptr SecKey32
sec_key_ptr, CSize
_) ->
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
m forall a b. (a -> b) -> a -> b
$ \(Ptr Msg32
msg_ptr, CSize
_) -> do
Ptr Sig64
sig_ptr <- forall a. Int -> IO (Ptr a)
mallocBytes Int
64
CInt
ret <- forall a.
Ctx
-> Ptr Sig64
-> Ptr Msg32
-> Ptr SecKey32
-> FunPtr (NonceFun a)
-> Ptr a
-> IO CInt
ecdsaSign Ctx
ctx Ptr Sig64
sig_ptr Ptr Msg32
msg_ptr Ptr SecKey32
sec_key_ptr forall a. FunPtr a
nullFunPtr forall a. Ptr a
nullPtr
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (CInt -> Bool
isSuccess CInt
ret) forall a b. (a -> b) -> a -> b
$ do
forall a. Ptr a -> IO ()
free Ptr Sig64
sig_ptr
forall a. HasCallStack => String -> a
error String
"could not sign message"
ByteString -> Sig
Sig forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. (Ptr a, CSize) -> IO ByteString
unsafePackByteString (Ptr Sig64
sig_ptr, CSize
64)
derivePubKey :: SecKey -> PubKey
derivePubKey :: SecKey -> PubKey
derivePubKey (SecKey ByteString
sec_key) = forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
sec_key forall a b. (a -> b) -> a -> b
$ \(Ptr SecKey32
sec_key_ptr, CSize
_) -> do
Ptr PubKey64
pub_key_ptr <- forall a. Int -> IO (Ptr a)
mallocBytes Int
64
CInt
ret <- Ctx -> Ptr PubKey64 -> Ptr SecKey32 -> IO CInt
ecPubKeyCreate Ctx
ctx Ptr PubKey64
pub_key_ptr Ptr SecKey32
sec_key_ptr
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (CInt -> Bool
isSuccess CInt
ret) forall a b. (a -> b) -> a -> b
$ do
forall a. Ptr a -> IO ()
free Ptr PubKey64
pub_key_ptr
forall a. HasCallStack => String -> a
error String
"could not compute public key"
ByteString -> PubKey
PubKey forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. (Ptr a, CSize) -> IO ByteString
unsafePackByteString (Ptr PubKey64
pub_key_ptr, CSize
64)
tweakAddSecKey :: SecKey -> Tweak -> Maybe SecKey
tweakAddSecKey :: SecKey -> Tweak -> Maybe SecKey
tweakAddSecKey (SecKey ByteString
sec_key) (Tweak ByteString
t) = forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
new_bs forall a b. (a -> b) -> a -> b
$ \(Ptr SecKey32
sec_key_ptr, CSize
_) ->
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
t forall a b. (a -> b) -> a -> b
$ \(Ptr Tweak32
tweak_ptr, CSize
_) -> do
CInt
ret <- Ctx -> Ptr SecKey32 -> Ptr Tweak32 -> IO CInt
ecSecKeyTweakAdd Ctx
ctx Ptr SecKey32
sec_key_ptr Ptr Tweak32
tweak_ptr
if CInt -> Bool
isSuccess CInt
ret
then forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Maybe a
Just (ByteString -> SecKey
SecKey ByteString
new_bs))
else forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
where
new_bs :: ByteString
new_bs = ByteString -> ByteString
BS.copy ByteString
sec_key
tweakMulSecKey :: SecKey -> Tweak -> Maybe SecKey
tweakMulSecKey :: SecKey -> Tweak -> Maybe SecKey
tweakMulSecKey (SecKey ByteString
sec_key) (Tweak ByteString
t) = forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
new_bs forall a b. (a -> b) -> a -> b
$ \(Ptr SecKey32
sec_key_ptr, CSize
_) ->
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
t forall a b. (a -> b) -> a -> b
$ \(Ptr Tweak32
tweak_ptr, CSize
_) -> do
CInt
ret <- Ctx -> Ptr SecKey32 -> Ptr Tweak32 -> IO CInt
ecSecKeyTweakMul Ctx
ctx Ptr SecKey32
sec_key_ptr Ptr Tweak32
tweak_ptr
if CInt -> Bool
isSuccess CInt
ret
then forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Maybe a
Just (ByteString -> SecKey
SecKey ByteString
new_bs))
else forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
where
new_bs :: ByteString
new_bs = ByteString -> ByteString
BS.copy ByteString
sec_key
tweakAddPubKey :: PubKey -> Tweak -> Maybe PubKey
tweakAddPubKey :: PubKey -> Tweak -> Maybe PubKey
tweakAddPubKey (PubKey ByteString
pub_key) (Tweak ByteString
t) = forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
new_bs forall a b. (a -> b) -> a -> b
$ \(Ptr PubKey64
pub_key_ptr, CSize
_) ->
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
t forall a b. (a -> b) -> a -> b
$ \(Ptr Tweak32
tweak_ptr, CSize
_) -> do
CInt
ret <- Ctx -> Ptr PubKey64 -> Ptr Tweak32 -> IO CInt
ecPubKeyTweakAdd Ctx
ctx Ptr PubKey64
pub_key_ptr Ptr Tweak32
tweak_ptr
if CInt -> Bool
isSuccess CInt
ret
then forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Maybe a
Just (ByteString -> PubKey
PubKey ByteString
new_bs))
else forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
where
new_bs :: ByteString
new_bs = ByteString -> ByteString
BS.copy ByteString
pub_key
tweakMulPubKey :: PubKey -> Tweak -> Maybe PubKey
tweakMulPubKey :: PubKey -> Tweak -> Maybe PubKey
tweakMulPubKey (PubKey ByteString
pub_key) (Tweak ByteString
t) = forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
new_bs forall a b. (a -> b) -> a -> b
$ \(Ptr PubKey64
pub_key_ptr, CSize
_) ->
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
t forall a b. (a -> b) -> a -> b
$ \(Ptr Tweak32
tweak_ptr, CSize
_) -> do
CInt
ret <- Ctx -> Ptr PubKey64 -> Ptr Tweak32 -> IO CInt
ecPubKeyTweakMul Ctx
ctx Ptr PubKey64
pub_key_ptr Ptr Tweak32
tweak_ptr
if CInt -> Bool
isSuccess CInt
ret
then forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Maybe a
Just (ByteString -> PubKey
PubKey ByteString
new_bs))
else forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
where
new_bs :: ByteString
new_bs = ByteString -> ByteString
BS.copy ByteString
pub_key
combinePubKeys :: [PubKey] -> Maybe PubKey
combinePubKeys :: [PubKey] -> Maybe PubKey
combinePubKeys [] = forall a. Maybe a
Nothing
combinePubKeys [PubKey]
pubs = forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$
forall {a} {b}. [Ptr a] -> [PubKey] -> ([Ptr a] -> IO b) -> IO b
pointers [] [PubKey]
pubs forall a b. (a -> b) -> a -> b
$ \[Ptr PubKey64]
ps ->
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray (forall (t :: * -> *) a. Foldable t => t a -> Int
length [Ptr PubKey64]
ps) forall a b. (a -> b) -> a -> b
$ \Ptr (Ptr PubKey64)
a -> do
Ptr PubKey64
out <- forall a. Int -> IO (Ptr a)
mallocBytes Int
64
forall a. Storable a => Ptr a -> [a] -> IO ()
pokeArray Ptr (Ptr PubKey64)
a [Ptr PubKey64]
ps
CInt
ret <- Ctx -> Ptr PubKey64 -> Ptr (Ptr PubKey64) -> CInt -> IO CInt
ecPubKeyCombine Ctx
ctx Ptr PubKey64
out Ptr (Ptr PubKey64)
a (forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t a -> Int
length [Ptr PubKey64]
ps)
if CInt -> Bool
isSuccess CInt
ret
then do
ByteString
bs <- forall a. (Ptr a, CSize) -> IO ByteString
unsafePackByteString (Ptr PubKey64
out, CSize
64)
forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Maybe a
Just (ByteString -> PubKey
PubKey ByteString
bs))
else do
forall a. Ptr a -> IO ()
free Ptr PubKey64
out
forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
where
pointers :: [Ptr a] -> [PubKey] -> ([Ptr a] -> IO b) -> IO b
pointers [Ptr a]
ps [] [Ptr a] -> IO b
f = [Ptr a] -> IO b
f [Ptr a]
ps
pointers [Ptr a]
ps (PubKey ByteString
pub_key : [PubKey]
pub_keys) [Ptr a] -> IO b
f =
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
pub_key forall a b. (a -> b) -> a -> b
$ \(Ptr a
p, CSize
_) ->
[Ptr a] -> [PubKey] -> ([Ptr a] -> IO b) -> IO b
pointers (Ptr a
p forall a. a -> [a] -> [a]
: [Ptr a]
ps) [PubKey]
pub_keys [Ptr a] -> IO b
f
tweakNegate :: Tweak -> Maybe Tweak
tweakNegate :: Tweak -> Maybe Tweak
tweakNegate (Tweak ByteString
t) = forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
new forall a b. (a -> b) -> a -> b
$ \(Ptr Tweak32
out, CSize
_) -> do
CInt
ret <- Ctx -> Ptr Tweak32 -> IO CInt
ecTweakNegate Ctx
ctx Ptr Tweak32
out
if CInt -> Bool
isSuccess CInt
ret
then forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Maybe a
Just (ByteString -> Tweak
Tweak ByteString
new))
else forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
where
new :: ByteString
new = ByteString -> ByteString
BS.copy ByteString
t
instance Arbitrary Msg where
arbitrary :: Gen Msg
arbitrary = Gen Msg
gen_msg
where
valid_bs :: Gen (Maybe Msg)
valid_bs = Gen (Maybe Msg)
bs_gen forall a. Gen a -> (a -> Bool) -> Gen a
`suchThat` forall a. Maybe a -> Bool
isJust
bs_gen :: Gen (Maybe Msg)
bs_gen = ByteString -> Maybe Msg
msg forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Word8] -> ByteString
BS.pack forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
32 forall a. (Bounded a, Random a) => Gen a
arbitraryBoundedRandom
gen_msg :: Gen Msg
gen_msg = forall a. HasCallStack => Maybe a -> a
fromJust forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen (Maybe Msg)
valid_bs
instance Arbitrary SecKey where
arbitrary :: Gen SecKey
arbitrary = Gen SecKey
gen_key
where
valid_bs :: Gen (Maybe SecKey)
valid_bs = Gen (Maybe SecKey)
bs_gen forall a. Gen a -> (a -> Bool) -> Gen a
`suchThat` forall a. Maybe a -> Bool
isJust
bs_gen :: Gen (Maybe SecKey)
bs_gen = ByteString -> Maybe SecKey
secKey forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Word8] -> ByteString
BS.pack forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
32 forall a. (Bounded a, Random a) => Gen a
arbitraryBoundedRandom
gen_key :: Gen SecKey
gen_key = forall a. HasCallStack => Maybe a -> a
fromJust forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen (Maybe SecKey)
valid_bs
instance Arbitrary PubKey where
arbitrary :: Gen PubKey
arbitrary = SecKey -> PubKey
derivePubKey forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Arbitrary a => Gen a
arbitrary