{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ImportQualifiedPost #-}

-- |
-- Module      : Crypto.Secp256k1
-- License     : UNLICENSE
-- Maintainer  : Jean-Pierre Rupp <jprupp@protonmail.ch>
-- Stability   : experimental
-- Portability : POSIX
--
-- Crytpographic functions from Bitcoin’s secp256k1 library.
module Crypto.Secp256k1
  ( -- * Messages
    Msg,
    msg,
    getMsg,

    -- * Secret Keys
    SecKey,
    secKey,
    getSecKey,
    derivePubKey,

    -- * Public Keys
    PubKey,
    importPubKey,
    exportPubKey,

    -- * Signatures
    Sig,
    signMsg,
    verifySig,
    normalizeSig,

    -- ** DER
    importSig,
    exportSig,

    -- ** Compact
    CompactSig,
    getCompactSig,
    compactSig,
    exportCompactSig,
    importCompactSig,

    -- * Addition & Multiplication
    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

-- | Import 32-byte 'ByteString' as 'Msg'.
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

-- | Import 32-byte 'ByteString' as 'SecKey'.
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

-- | Convert signature to a normalized lower-S form. 'Nothing' indicates that it
-- was already normal.
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

-- | 32-Byte 'ByteString' as 'Tweak'.
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

-- | Import DER-encoded public key.
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

-- | Encode public key as DER. First argument 'True' for compressed output.
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

-- | Import DER-encoded signature.
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

-- | Encode signature as strict DER.
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)

-- | Verify message signature. 'True' means that the signature is correct.
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)

-- | Add tweak to secret key.
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

-- | Multiply secret key by tweak.
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

-- | Add tweak to public key. Tweak is multiplied first by G to obtain a point.
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

-- | Multiply public key by tweak. Tweak is multiplied first by G to obtain a
-- point.
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

-- | Add multiple public keys together.
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