{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE ImportQualifiedPost #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedRecordDot #-}
{-# LANGUAGE NoFieldSelectors #-}

-- |
-- Module      : Crypto.Secp256k1
-- License     : UNLICENSE
-- Maintainer  : Jean-Pierre Rupp <jprupp@protonmail.ch>
-- Stability   : experimental
-- Portability : POSIX
--
-- Crytpographic functions from Bitcoin’s secp256k1 library.
--
-- The API for this module may change at any time. This is an internal module only
-- exposed for hacking and experimentation.
module Crypto.Secp256k1.Internal.Base where

import Control.DeepSeq (NFData)
import Control.Exception (bracket)
import Control.Monad (replicateM, unless, (<=<))
import Crypto.Secp256k1.Internal.BaseOps
  ( ecPubKeyCombine,
    ecPubKeyCreate,
    ecPubKeyParse,
    ecPubKeySerialize,
    ecPubKeyTweakAdd,
    ecPubKeyTweakMul,
    ecSecKeyTweakAdd,
    ecSecKeyTweakMul,
    ecTweakNegate,
    ecdsaSign,
    ecdsaSignatureNormalize,
    ecdsaSignatureParseCompact,
    ecdsaSignatureParseDer,
    ecdsaSignatureSerializeCompact,
    ecdsaSignatureSerializeDer,
    ecdsaVerify,
  )
import Crypto.Secp256k1.Internal.Context (Ctx (..))
import Crypto.Secp256k1.Internal.ForeignTypes
  ( LCtx,
    compressed,
    isSuccess,
    uncompressed,
  )
import Crypto.Secp256k1.Internal.Util
  ( decodeHex,
    packByteString,
    showsHex,
    unsafePackByteString,
    unsafeUseByteString,
  )
import Data.ByteString (ByteString)
import Data.ByteString qualified as BS
import Data.Hashable (Hashable (..))
import Data.Maybe (fromJust, fromMaybe, isJust)
import Data.String (IsString (..))
import Foreign
  ( Bits (bitSize),
    Ptr,
    alloca,
    allocaArray,
    allocaBytes,
    free,
    mallocBytes,
    nullFunPtr,
    nullPtr,
    peek,
    poke,
    pokeArray,
    withForeignPtr,
  )
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
get :: ByteString}
  deriving (PubKey -> PubKey -> Bool
(PubKey -> PubKey -> Bool)
-> (PubKey -> PubKey -> Bool) -> Eq PubKey
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: PubKey -> PubKey -> Bool
== :: PubKey -> PubKey -> Bool
$c/= :: PubKey -> PubKey -> Bool
/= :: PubKey -> PubKey -> Bool
Eq, (forall x. PubKey -> Rep PubKey x)
-> (forall x. Rep PubKey x -> PubKey) -> Generic PubKey
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
$cfrom :: forall x. PubKey -> Rep PubKey x
from :: forall x. PubKey -> Rep PubKey x
$cto :: forall x. Rep PubKey x -> PubKey
to :: forall x. Rep PubKey x -> PubKey
Generic, Eq PubKey
Eq PubKey =>
(Int -> PubKey -> Int) -> (PubKey -> Int) -> Hashable PubKey
Int -> PubKey -> Int
PubKey -> Int
forall a. Eq a => (Int -> a -> Int) -> (a -> Int) -> Hashable a
$chashWithSalt :: Int -> PubKey -> Int
hashWithSalt :: Int -> PubKey -> Int
$chash :: PubKey -> Int
hash :: PubKey -> Int
Hashable, PubKey -> ()
(PubKey -> ()) -> NFData PubKey
forall a. (a -> ()) -> NFData a
$crnf :: PubKey -> ()
rnf :: PubKey -> ()
NFData)

newtype Msg = Msg {Msg -> ByteString
get :: ByteString}
  deriving (Msg -> Msg -> Bool
(Msg -> Msg -> Bool) -> (Msg -> Msg -> Bool) -> Eq Msg
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Msg -> Msg -> Bool
== :: Msg -> Msg -> Bool
$c/= :: Msg -> Msg -> Bool
/= :: Msg -> Msg -> Bool
Eq, (forall x. Msg -> Rep Msg x)
-> (forall x. Rep Msg x -> Msg) -> Generic Msg
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
$cfrom :: forall x. Msg -> Rep Msg x
from :: forall x. Msg -> Rep Msg x
$cto :: forall x. Rep Msg x -> Msg
to :: forall x. Rep Msg x -> Msg
Generic, Eq Msg
Eq Msg => (Int -> Msg -> Int) -> (Msg -> Int) -> Hashable Msg
Int -> Msg -> Int
Msg -> Int
forall a. Eq a => (Int -> a -> Int) -> (a -> Int) -> Hashable a
$chashWithSalt :: Int -> Msg -> Int
hashWithSalt :: Int -> Msg -> Int
$chash :: Msg -> Int
hash :: Msg -> Int
Hashable, Msg -> ()
(Msg -> ()) -> NFData Msg
forall a. (a -> ()) -> NFData a
$crnf :: Msg -> ()
rnf :: Msg -> ()
NFData)

newtype Sig = Sig {Sig -> ByteString
get :: ByteString}
  deriving (Sig -> Sig -> Bool
(Sig -> Sig -> Bool) -> (Sig -> Sig -> Bool) -> Eq Sig
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Sig -> Sig -> Bool
== :: Sig -> Sig -> Bool
$c/= :: Sig -> Sig -> Bool
/= :: Sig -> Sig -> Bool
Eq, (forall x. Sig -> Rep Sig x)
-> (forall x. Rep Sig x -> Sig) -> Generic Sig
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
$cfrom :: forall x. Sig -> Rep Sig x
from :: forall x. Sig -> Rep Sig x
$cto :: forall x. Rep Sig x -> Sig
to :: forall x. Rep Sig x -> Sig
Generic, Eq Sig
Eq Sig => (Int -> Sig -> Int) -> (Sig -> Int) -> Hashable Sig
Int -> Sig -> Int
Sig -> Int
forall a. Eq a => (Int -> a -> Int) -> (a -> Int) -> Hashable a
$chashWithSalt :: Int -> Sig -> Int
hashWithSalt :: Int -> Sig -> Int
$chash :: Sig -> Int
hash :: Sig -> Int
Hashable, Sig -> ()
(Sig -> ()) -> NFData Sig
forall a. (a -> ()) -> NFData a
$crnf :: Sig -> ()
rnf :: Sig -> ()
NFData)

newtype SecKey = SecKey {SecKey -> ByteString
get :: ByteString}
  deriving (SecKey -> SecKey -> Bool
(SecKey -> SecKey -> Bool)
-> (SecKey -> SecKey -> Bool) -> Eq SecKey
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: SecKey -> SecKey -> Bool
== :: SecKey -> SecKey -> Bool
$c/= :: SecKey -> SecKey -> Bool
/= :: SecKey -> SecKey -> Bool
Eq, (forall x. SecKey -> Rep SecKey x)
-> (forall x. Rep SecKey x -> SecKey) -> Generic SecKey
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
$cfrom :: forall x. SecKey -> Rep SecKey x
from :: forall x. SecKey -> Rep SecKey x
$cto :: forall x. Rep SecKey x -> SecKey
to :: forall x. Rep SecKey x -> SecKey
Generic, Eq SecKey
Eq SecKey =>
(Int -> SecKey -> Int) -> (SecKey -> Int) -> Hashable SecKey
Int -> SecKey -> Int
SecKey -> Int
forall a. Eq a => (Int -> a -> Int) -> (a -> Int) -> Hashable a
$chashWithSalt :: Int -> SecKey -> Int
hashWithSalt :: Int -> SecKey -> Int
$chash :: SecKey -> Int
hash :: SecKey -> Int
Hashable, SecKey -> ()
(SecKey -> ()) -> NFData SecKey
forall a. (a -> ()) -> NFData a
$crnf :: SecKey -> ()
rnf :: SecKey -> ()
NFData)

newtype Tweak = Tweak {Tweak -> ByteString
get :: ByteString}
  deriving (Tweak -> Tweak -> Bool
(Tweak -> Tweak -> Bool) -> (Tweak -> Tweak -> Bool) -> Eq Tweak
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Tweak -> Tweak -> Bool
== :: Tweak -> Tweak -> Bool
$c/= :: Tweak -> Tweak -> Bool
/= :: Tweak -> Tweak -> Bool
Eq, (forall x. Tweak -> Rep Tweak x)
-> (forall x. Rep Tweak x -> Tweak) -> Generic Tweak
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
$cfrom :: forall x. Tweak -> Rep Tweak x
from :: forall x. Tweak -> Rep Tweak x
$cto :: forall x. Rep Tweak x -> Tweak
to :: forall x. Rep Tweak x -> Tweak
Generic, Eq Tweak
Eq Tweak =>
(Int -> Tweak -> Int) -> (Tweak -> Int) -> Hashable Tweak
Int -> Tweak -> Int
Tweak -> Int
forall a. Eq a => (Int -> a -> Int) -> (a -> Int) -> Hashable a
$chashWithSalt :: Int -> Tweak -> Int
hashWithSalt :: Int -> Tweak -> Int
$chash :: Tweak -> Int
hash :: Tweak -> Int
Hashable, Tweak -> ()
(Tweak -> ()) -> NFData Tweak
forall a. (a -> ()) -> NFData a
$crnf :: Tweak -> ()
rnf :: Tweak -> ()
NFData)

newtype CompactSig = CompactSig {CompactSig -> ByteString
get :: ByteString}
  deriving (CompactSig -> CompactSig -> Bool
(CompactSig -> CompactSig -> Bool)
-> (CompactSig -> CompactSig -> Bool) -> Eq CompactSig
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CompactSig -> CompactSig -> Bool
== :: CompactSig -> CompactSig -> Bool
$c/= :: CompactSig -> CompactSig -> Bool
/= :: CompactSig -> CompactSig -> Bool
Eq, (forall x. CompactSig -> Rep CompactSig x)
-> (forall x. Rep CompactSig x -> CompactSig) -> Generic CompactSig
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
$cfrom :: forall x. CompactSig -> Rep CompactSig x
from :: forall x. CompactSig -> Rep CompactSig x
$cto :: forall x. Rep CompactSig x -> CompactSig
to :: forall x. Rep CompactSig x -> CompactSig
Generic, Eq CompactSig
Eq CompactSig =>
(Int -> CompactSig -> Int)
-> (CompactSig -> Int) -> Hashable CompactSig
Int -> CompactSig -> Int
CompactSig -> Int
forall a. Eq a => (Int -> a -> Int) -> (a -> Int) -> Hashable a
$chashWithSalt :: Int -> CompactSig -> Int
hashWithSalt :: Int -> CompactSig -> Int
$chash :: CompactSig -> Int
hash :: CompactSig -> Int
Hashable, CompactSig -> ()
(CompactSig -> ()) -> NFData CompactSig
forall a. (a -> ()) -> NFData a
$crnf :: CompactSig -> ()
rnf :: CompactSig -> ()
NFData)

instance Read PubKey where
  readPrec :: ReadPrec PubKey
readPrec = ReadPrec PubKey -> ReadPrec PubKey
forall a. ReadPrec a -> ReadPrec a
parens (ReadPrec PubKey -> ReadPrec PubKey)
-> ReadPrec PubKey -> ReadPrec PubKey
forall a b. (a -> b) -> a -> b
$ do
    String String
str <- ReadPrec Lexeme
lexP
    ReadPrec PubKey
-> (PubKey -> ReadPrec PubKey) -> Maybe PubKey -> ReadPrec PubKey
forall b a. b -> (a -> b) -> Maybe a -> b
maybe ReadPrec PubKey
forall a. ReadPrec a
pfail PubKey -> ReadPrec PubKey
forall a. a -> ReadPrec a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe PubKey -> ReadPrec PubKey)
-> Maybe PubKey -> ReadPrec PubKey
forall a b. (a -> b) -> a -> b
$ ByteString -> Maybe PubKey
pubKey (ByteString -> Maybe PubKey) -> Maybe ByteString -> Maybe PubKey
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< String -> Maybe ByteString
forall a. ConvertibleStrings a ByteString => a -> Maybe ByteString
decodeHex String
str

instance IsString PubKey where
  fromString :: String -> PubKey
fromString = PubKey -> Maybe PubKey -> PubKey
forall a. a -> Maybe a -> a
fromMaybe PubKey
forall {a}. a
e (Maybe PubKey -> PubKey)
-> (String -> Maybe PubKey) -> String -> PubKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ByteString -> Maybe PubKey
pubKey (ByteString -> Maybe PubKey)
-> (String -> Maybe ByteString) -> String -> Maybe PubKey
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< String -> Maybe ByteString
forall a. ConvertibleStrings a ByteString => a -> Maybe ByteString
decodeHex)
    where
      e :: a
e = String -> a
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
_ = ByteString -> ShowS
showsHex (ByteString -> ShowS) -> (PubKey -> ByteString) -> PubKey -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (.get)

instance Read Msg where
  readPrec :: ReadPrec Msg
readPrec = ReadPrec Msg -> ReadPrec Msg
forall a. ReadPrec a -> ReadPrec a
parens (ReadPrec Msg -> ReadPrec Msg) -> ReadPrec Msg -> ReadPrec Msg
forall a b. (a -> b) -> a -> b
$ do
    String String
str <- ReadPrec Lexeme
lexP
    ReadPrec Msg -> (Msg -> ReadPrec Msg) -> Maybe Msg -> ReadPrec Msg
forall b a. b -> (a -> b) -> Maybe a -> b
maybe ReadPrec Msg
forall a. ReadPrec a
pfail Msg -> ReadPrec Msg
forall a. a -> ReadPrec a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Msg -> ReadPrec Msg) -> Maybe Msg -> ReadPrec Msg
forall a b. (a -> b) -> a -> b
$ ByteString -> Maybe Msg
msg (ByteString -> Maybe Msg) -> Maybe ByteString -> Maybe Msg
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< String -> Maybe ByteString
forall a. ConvertibleStrings a ByteString => a -> Maybe ByteString
decodeHex String
str

instance IsString Msg where
  fromString :: String -> Msg
fromString = Msg -> Maybe Msg -> Msg
forall a. a -> Maybe a -> a
fromMaybe Msg
forall {a}. a
e (Maybe Msg -> Msg) -> (String -> Maybe Msg) -> String -> Msg
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ByteString -> Maybe Msg
msg (ByteString -> Maybe Msg)
-> (String -> Maybe ByteString) -> String -> Maybe Msg
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< String -> Maybe ByteString
forall a. ConvertibleStrings a ByteString => a -> Maybe ByteString
decodeHex)
    where
      e :: a
e = String -> a
forall a. HasCallStack => String -> a
error String
"Could not decode message from hex string"

instance Show Msg where
  showsPrec :: Int -> Msg -> ShowS
showsPrec Int
_ = ByteString -> ShowS
showsHex (ByteString -> ShowS) -> (Msg -> ByteString) -> Msg -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (.get)

instance Read Sig where
  readPrec :: ReadPrec Sig
readPrec = ReadPrec Sig -> ReadPrec Sig
forall a. ReadPrec a -> ReadPrec a
parens (ReadPrec Sig -> ReadPrec Sig) -> ReadPrec Sig -> ReadPrec Sig
forall a b. (a -> b) -> a -> b
$ do
    String String
str <- ReadPrec Lexeme
lexP
    ReadPrec Sig -> (Sig -> ReadPrec Sig) -> Maybe Sig -> ReadPrec Sig
forall b a. b -> (a -> b) -> Maybe a -> b
maybe ReadPrec Sig
forall a. ReadPrec a
pfail Sig -> ReadPrec Sig
forall a. a -> ReadPrec a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Sig -> ReadPrec Sig) -> Maybe Sig -> ReadPrec Sig
forall a b. (a -> b) -> a -> b
$ ByteString -> Maybe Sig
sig (ByteString -> Maybe Sig) -> Maybe ByteString -> Maybe Sig
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< String -> Maybe ByteString
forall a. ConvertibleStrings a ByteString => a -> Maybe ByteString
decodeHex String
str

instance IsString Sig where
  fromString :: String -> Sig
fromString = Sig -> Maybe Sig -> Sig
forall a. a -> Maybe a -> a
fromMaybe Sig
forall {a}. a
e (Maybe Sig -> Sig) -> (String -> Maybe Sig) -> String -> Sig
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ByteString -> Maybe Sig
sig (ByteString -> Maybe Sig)
-> (String -> Maybe ByteString) -> String -> Maybe Sig
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< String -> Maybe ByteString
forall a. ConvertibleStrings a ByteString => a -> Maybe ByteString
decodeHex)
    where
      e :: a
e = String -> a
forall a. HasCallStack => String -> a
error String
"Could not decode signature from hex string"

instance Show Sig where
  showsPrec :: Int -> Sig -> ShowS
showsPrec Int
_ = ByteString -> ShowS
showsHex (ByteString -> ShowS) -> (Sig -> ByteString) -> Sig -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (.get)

instance Read SecKey where
  readPrec :: ReadPrec SecKey
readPrec = ReadPrec SecKey -> ReadPrec SecKey
forall a. ReadPrec a -> ReadPrec a
parens (ReadPrec SecKey -> ReadPrec SecKey)
-> ReadPrec SecKey -> ReadPrec SecKey
forall a b. (a -> b) -> a -> b
$ do
    String String
str <- ReadPrec Lexeme
lexP
    ReadPrec SecKey
-> (SecKey -> ReadPrec SecKey) -> Maybe SecKey -> ReadPrec SecKey
forall b a. b -> (a -> b) -> Maybe a -> b
maybe ReadPrec SecKey
forall a. ReadPrec a
pfail SecKey -> ReadPrec SecKey
forall a. a -> ReadPrec a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe SecKey -> ReadPrec SecKey)
-> Maybe SecKey -> ReadPrec SecKey
forall a b. (a -> b) -> a -> b
$ ByteString -> Maybe SecKey
secKey (ByteString -> Maybe SecKey) -> Maybe ByteString -> Maybe SecKey
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< String -> Maybe ByteString
forall a. ConvertibleStrings a ByteString => a -> Maybe ByteString
decodeHex String
str

instance IsString SecKey where
  fromString :: String -> SecKey
fromString = SecKey -> Maybe SecKey -> SecKey
forall a. a -> Maybe a -> a
fromMaybe SecKey
forall {a}. a
e (Maybe SecKey -> SecKey)
-> (String -> Maybe SecKey) -> String -> SecKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ByteString -> Maybe SecKey
secKey (ByteString -> Maybe SecKey)
-> (String -> Maybe ByteString) -> String -> Maybe SecKey
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< String -> Maybe ByteString
forall a. ConvertibleStrings a ByteString => a -> Maybe ByteString
decodeHex)
    where
      e :: a
e = String -> a
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
_ = ByteString -> ShowS
showsHex (ByteString -> ShowS) -> (SecKey -> ByteString) -> SecKey -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (.get)

instance Read Tweak where
  readPrec :: ReadPrec Tweak
readPrec = ReadPrec Tweak -> ReadPrec Tweak
forall a. ReadPrec a -> ReadPrec a
parens (ReadPrec Tweak -> ReadPrec Tweak)
-> ReadPrec Tweak -> ReadPrec Tweak
forall a b. (a -> b) -> a -> b
$ do
    String String
str <- ReadPrec Lexeme
lexP
    ReadPrec Tweak
-> (Tweak -> ReadPrec Tweak) -> Maybe Tweak -> ReadPrec Tweak
forall b a. b -> (a -> b) -> Maybe a -> b
maybe ReadPrec Tweak
forall a. ReadPrec a
pfail Tweak -> ReadPrec Tweak
forall a. a -> ReadPrec a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Tweak -> ReadPrec Tweak) -> Maybe Tweak -> ReadPrec Tweak
forall a b. (a -> b) -> a -> b
$ ByteString -> Maybe Tweak
tweak (ByteString -> Maybe Tweak) -> Maybe ByteString -> Maybe Tweak
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< String -> Maybe ByteString
forall a. ConvertibleStrings a ByteString => a -> Maybe ByteString
decodeHex String
str

instance IsString Tweak where
  fromString :: String -> Tweak
fromString = Tweak -> Maybe Tweak -> Tweak
forall a. a -> Maybe a -> a
fromMaybe Tweak
forall {a}. a
e (Maybe Tweak -> Tweak)
-> (String -> Maybe Tweak) -> String -> Tweak
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ByteString -> Maybe Tweak
tweak (ByteString -> Maybe Tweak)
-> (String -> Maybe ByteString) -> String -> Maybe Tweak
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< String -> Maybe ByteString
forall a. ConvertibleStrings a ByteString => a -> Maybe ByteString
decodeHex)
    where
      e :: a
e = String -> a
forall a. HasCallStack => String -> a
error String
"Could not decode tweak from hex string"

instance Show Tweak where
  showsPrec :: Int -> Tweak -> ShowS
showsPrec Int
_ = ByteString -> ShowS
showsHex (ByteString -> ShowS) -> (Tweak -> ByteString) -> Tweak -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (.get)

-- | Import 64-byte 'ByteString' as 'Sig'.
sig :: ByteString -> Maybe Sig
sig :: ByteString -> Maybe Sig
sig ByteString
bs
  | ByteString -> Int
BS.length ByteString
bs Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
64 = Sig -> Maybe Sig
forall a. a -> Maybe a
Just (ByteString -> Sig
Sig ByteString
bs)
  | Bool
otherwise = Maybe Sig
forall a. Maybe a
Nothing

-- | Import 64-byte 'ByteString' as 'PubKey'.
pubKey :: ByteString -> Maybe PubKey
pubKey :: ByteString -> Maybe PubKey
pubKey ByteString
bs
  | ByteString -> Int
BS.length ByteString
bs Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
64 = PubKey -> Maybe PubKey
forall a. a -> Maybe a
Just (ByteString -> PubKey
PubKey ByteString
bs)
  | Bool
otherwise = Maybe PubKey
forall a. Maybe a
Nothing

-- | Import 32-byte 'ByteString' as 'Msg'.
msg :: ByteString -> Maybe Msg
msg :: ByteString -> Maybe Msg
msg ByteString
bs
  | ByteString -> Int
BS.length ByteString
bs Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
32 = Msg -> Maybe Msg
forall a. a -> Maybe a
Just (ByteString -> Msg
Msg ByteString
bs)
  | Bool
otherwise = Maybe Msg
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 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
32 = SecKey -> Maybe SecKey
forall a. a -> Maybe a
Just (ByteString -> SecKey
SecKey ByteString
bs)
  | Bool
otherwise = Maybe SecKey
forall a. Maybe a
Nothing

compactSig :: ByteString -> Maybe CompactSig
compactSig :: ByteString -> Maybe CompactSig
compactSig ByteString
bs
  | ByteString -> Int
BS.length ByteString
bs Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
64 = CompactSig -> Maybe CompactSig
forall a. a -> Maybe a
Just (ByteString -> CompactSig
CompactSig ByteString
bs)
  | Bool
otherwise = Maybe CompactSig
forall a. Maybe a
Nothing

-- | Convert signature to a normalized lower-S form. 'Nothing' indicates that it
-- was already normal.
normalizeSig :: Ctx -> Sig -> Maybe Sig
normalizeSig :: Ctx -> Sig -> Maybe Sig
normalizeSig (Ctx ForeignPtr LCtx
fctx) (Sig ByteString
sig) =
  IO (Maybe Sig) -> Maybe Sig
forall a. IO a -> a
unsafePerformIO (IO (Maybe Sig) -> Maybe Sig) -> IO (Maybe Sig) -> Maybe Sig
forall a b. (a -> b) -> a -> b
$ ForeignPtr LCtx -> (Ptr LCtx -> IO (Maybe Sig)) -> IO (Maybe Sig)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr LCtx
fctx ((Ptr LCtx -> IO (Maybe Sig)) -> IO (Maybe Sig))
-> (Ptr LCtx -> IO (Maybe Sig)) -> IO (Maybe Sig)
forall a b. (a -> b) -> a -> b
$ \Ptr LCtx
ctx ->
    ByteString
-> ((Ptr Sig64, CSize) -> IO (Maybe Sig)) -> IO (Maybe Sig)
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
sig (((Ptr Sig64, CSize) -> IO (Maybe Sig)) -> IO (Maybe Sig))
-> ((Ptr Sig64, CSize) -> IO (Maybe Sig)) -> IO (Maybe Sig)
forall a b. (a -> b) -> a -> b
$ \(Ptr Sig64
sig_in, CSize
_) -> do
      Ptr Sig64
sig_out <- Int -> IO (Ptr Sig64)
forall a. Int -> IO (Ptr a)
mallocBytes Int
64
      CInt
ret <- Ptr LCtx -> Ptr Sig64 -> Ptr Sig64 -> IO CInt
ecdsaSignatureNormalize Ptr LCtx
ctx Ptr Sig64
sig_out Ptr Sig64
sig_in
      if CInt -> Bool
isSuccess CInt
ret
        then do
          ByteString
bs <- (Ptr Sig64, CSize) -> IO ByteString
forall a. (Ptr a, CSize) -> IO ByteString
unsafePackByteString (Ptr Sig64
sig_out, CSize
64)
          Maybe Sig -> IO (Maybe Sig)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Sig -> Maybe Sig
forall a. a -> Maybe a
Just (ByteString -> Sig
Sig ByteString
bs))
        else do
          Ptr Sig64 -> IO ()
forall a. Ptr a -> IO ()
free Ptr Sig64
sig_out
          Maybe Sig -> IO (Maybe Sig)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Sig
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 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
32 = Tweak -> Maybe Tweak
forall a. a -> Maybe a
Just (ByteString -> Tweak
Tweak ByteString
bs)
  | Bool
otherwise = Maybe Tweak
forall a. Maybe a
Nothing

-- | Import DER-encoded public key.
importPubKey :: Ctx -> ByteString -> Maybe PubKey
importPubKey :: Ctx -> ByteString -> Maybe PubKey
importPubKey (Ctx ForeignPtr LCtx
fctx) ByteString
bs
  | ByteString -> Bool
BS.null ByteString
bs = Maybe PubKey
forall a. Maybe a
Nothing
  | Bool
otherwise =
      IO (Maybe PubKey) -> Maybe PubKey
forall a. IO a -> a
unsafePerformIO (IO (Maybe PubKey) -> Maybe PubKey)
-> IO (Maybe PubKey) -> Maybe PubKey
forall a b. (a -> b) -> a -> b
$ ForeignPtr LCtx
-> (Ptr LCtx -> IO (Maybe PubKey)) -> IO (Maybe PubKey)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr LCtx
fctx ((Ptr LCtx -> IO (Maybe PubKey)) -> IO (Maybe PubKey))
-> (Ptr LCtx -> IO (Maybe PubKey)) -> IO (Maybe PubKey)
forall a b. (a -> b) -> a -> b
$ \Ptr LCtx
ctx ->
        ByteString
-> ((Ptr CUChar, CSize) -> IO (Maybe PubKey)) -> IO (Maybe PubKey)
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
bs (((Ptr CUChar, CSize) -> IO (Maybe PubKey)) -> IO (Maybe PubKey))
-> ((Ptr CUChar, CSize) -> IO (Maybe PubKey)) -> IO (Maybe PubKey)
forall a b. (a -> b) -> a -> b
$ \(Ptr CUChar
input, CSize
len) -> do
          Ptr PubKey64
pub_key <- Int -> IO (Ptr PubKey64)
forall a. Int -> IO (Ptr a)
mallocBytes Int
64
          CInt
ret <- Ptr LCtx -> Ptr PubKey64 -> Ptr CUChar -> CSize -> IO CInt
ecPubKeyParse Ptr LCtx
ctx Ptr PubKey64
pub_key Ptr CUChar
input CSize
len
          if CInt -> Bool
isSuccess CInt
ret
            then do
              ByteString
out <- (Ptr PubKey64, CSize) -> IO ByteString
forall a. (Ptr a, CSize) -> IO ByteString
unsafePackByteString (Ptr PubKey64
pub_key, CSize
64)
              Maybe PubKey -> IO (Maybe PubKey)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (PubKey -> Maybe PubKey
forall a. a -> Maybe a
Just (ByteString -> PubKey
PubKey ByteString
out))
            else do
              Ptr PubKey64 -> IO ()
forall a. Ptr a -> IO ()
free Ptr PubKey64
pub_key
              Maybe PubKey -> IO (Maybe PubKey)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe PubKey
forall a. Maybe a
Nothing

-- | Encode public key as DER. First argument 'True' for compressed output.
exportPubKey :: Ctx -> Bool -> PubKey -> ByteString
exportPubKey :: Ctx -> Bool -> PubKey -> ByteString
exportPubKey (Ctx ForeignPtr LCtx
fctx) Bool
compress (PubKey ByteString
in_bs) =
  IO ByteString -> ByteString
forall a. IO a -> a
unsafePerformIO (IO ByteString -> ByteString) -> IO ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ ForeignPtr LCtx -> (Ptr LCtx -> IO ByteString) -> IO ByteString
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr LCtx
fctx ((Ptr LCtx -> IO ByteString) -> IO ByteString)
-> (Ptr LCtx -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \Ptr LCtx
ctx ->
    ByteString
-> ((Ptr PubKey64, CSize) -> IO ByteString) -> IO ByteString
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
in_bs (((Ptr PubKey64, CSize) -> IO ByteString) -> IO ByteString)
-> ((Ptr PubKey64, CSize) -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \(Ptr PubKey64
in_ptr, CSize
_) ->
      (Ptr CSize -> IO ByteString) -> IO ByteString
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr CSize -> IO ByteString) -> IO ByteString)
-> (Ptr CSize -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \Ptr CSize
len_ptr ->
        Int -> (Ptr CUChar -> IO ByteString) -> IO ByteString
forall a b. Int -> (Ptr a -> IO b) -> IO b
allocaBytes Int
len ((Ptr CUChar -> IO ByteString) -> IO ByteString)
-> (Ptr CUChar -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \Ptr CUChar
out_ptr -> do
          Ptr CSize -> CSize -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr CSize
len_ptr (CSize -> IO ()) -> CSize -> IO ()
forall a b. (a -> b) -> a -> b
$ Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len
          CInt
ret <- Ptr LCtx
-> Ptr CUChar -> Ptr CSize -> Ptr PubKey64 -> SerFlags -> IO CInt
ecPubKeySerialize Ptr LCtx
ctx Ptr CUChar
out_ptr Ptr CSize
len_ptr Ptr PubKey64
in_ptr SerFlags
flags
          Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (CInt -> Bool
isSuccess CInt
ret) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ String -> IO ()
forall a. HasCallStack => String -> a
error String
"could not serialize public key"
          CSize
final_len <- Ptr CSize -> IO CSize
forall a. Storable a => Ptr a -> IO a
peek Ptr CSize
len_ptr
          (Ptr CUChar, CSize) -> IO ByteString
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 :: Ctx -> Sig -> CompactSig
exportCompactSig :: Ctx -> Sig -> CompactSig
exportCompactSig (Ctx ForeignPtr LCtx
fctx) (Sig ByteString
sig_bs) =
  IO CompactSig -> CompactSig
forall a. IO a -> a
unsafePerformIO (IO CompactSig -> CompactSig) -> IO CompactSig -> CompactSig
forall a b. (a -> b) -> a -> b
$ ForeignPtr LCtx -> (Ptr LCtx -> IO CompactSig) -> IO CompactSig
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr LCtx
fctx ((Ptr LCtx -> IO CompactSig) -> IO CompactSig)
-> (Ptr LCtx -> IO CompactSig) -> IO CompactSig
forall a b. (a -> b) -> a -> b
$ \Ptr LCtx
ctx ->
    ByteString
-> ((Ptr Sig64, CSize) -> IO CompactSig) -> IO CompactSig
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
sig_bs (((Ptr Sig64, CSize) -> IO CompactSig) -> IO CompactSig)
-> ((Ptr Sig64, CSize) -> IO CompactSig) -> IO CompactSig
forall a b. (a -> b) -> a -> b
$ \(Ptr Sig64
sig_ptr, CSize
_) -> do
      Ptr Compact64
out_ptr <- Int -> IO (Ptr Compact64)
forall a. Int -> IO (Ptr a)
mallocBytes Int
64
      CInt
ret <- Ptr LCtx -> Ptr Compact64 -> Ptr Sig64 -> IO CInt
ecdsaSignatureSerializeCompact Ptr LCtx
ctx Ptr Compact64
out_ptr Ptr Sig64
sig_ptr
      Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (CInt -> Bool
isSuccess CInt
ret) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
        Ptr Compact64 -> IO ()
forall a. Ptr a -> IO ()
free Ptr Compact64
out_ptr
        String -> IO ()
forall a. HasCallStack => String -> a
error String
"Could not obtain compact signature"
      ByteString
out_bs <- (Ptr Compact64, CSize) -> IO ByteString
forall a. (Ptr a, CSize) -> IO ByteString
unsafePackByteString (Ptr Compact64
out_ptr, CSize
64)
      CompactSig -> IO CompactSig
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (CompactSig -> IO CompactSig) -> CompactSig -> IO CompactSig
forall a b. (a -> b) -> a -> b
$ ByteString -> CompactSig
CompactSig ByteString
out_bs

importCompactSig :: Ctx -> CompactSig -> Maybe Sig
importCompactSig :: Ctx -> CompactSig -> Maybe Sig
importCompactSig (Ctx ForeignPtr LCtx
fctx) (CompactSig ByteString
compact_sig) =
  IO (Maybe Sig) -> Maybe Sig
forall a. IO a -> a
unsafePerformIO (IO (Maybe Sig) -> Maybe Sig) -> IO (Maybe Sig) -> Maybe Sig
forall a b. (a -> b) -> a -> b
$ ForeignPtr LCtx -> (Ptr LCtx -> IO (Maybe Sig)) -> IO (Maybe Sig)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr LCtx
fctx ((Ptr LCtx -> IO (Maybe Sig)) -> IO (Maybe Sig))
-> (Ptr LCtx -> IO (Maybe Sig)) -> IO (Maybe Sig)
forall a b. (a -> b) -> a -> b
$ \Ptr LCtx
ctx ->
    ByteString
-> ((Ptr Compact64, CSize) -> IO (Maybe Sig)) -> IO (Maybe Sig)
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
compact_sig (((Ptr Compact64, CSize) -> IO (Maybe Sig)) -> IO (Maybe Sig))
-> ((Ptr Compact64, CSize) -> IO (Maybe Sig)) -> IO (Maybe Sig)
forall a b. (a -> b) -> a -> b
$ \(Ptr Compact64
compact_ptr, CSize
_) -> do
      Ptr Sig64
out_sig <- Int -> IO (Ptr Sig64)
forall a. Int -> IO (Ptr a)
mallocBytes Int
64
      CInt
ret <- Ptr LCtx -> Ptr Sig64 -> Ptr Compact64 -> IO CInt
ecdsaSignatureParseCompact Ptr LCtx
ctx Ptr Sig64
out_sig Ptr Compact64
compact_ptr
      if CInt -> Bool
isSuccess CInt
ret
        then do
          ByteString
out_bs <- (Ptr Sig64, CSize) -> IO ByteString
forall a. (Ptr a, CSize) -> IO ByteString
unsafePackByteString (Ptr Sig64
out_sig, CSize
64)
          Maybe Sig -> IO (Maybe Sig)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Sig -> Maybe Sig
forall a. a -> Maybe a
Just (ByteString -> Sig
Sig ByteString
out_bs))
        else do
          Ptr Sig64 -> IO ()
forall a. Ptr a -> IO ()
free Ptr Sig64
out_sig
          Maybe Sig -> IO (Maybe Sig)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Sig
forall a. Maybe a
Nothing

-- | Import DER-encoded signature.
importSig :: Ctx -> ByteString -> Maybe Sig
importSig :: Ctx -> ByteString -> Maybe Sig
importSig (Ctx ForeignPtr LCtx
fctx) ByteString
bs
  | ByteString -> Bool
BS.null ByteString
bs = Maybe Sig
forall a. Maybe a
Nothing
  | Bool
otherwise =
      IO (Maybe Sig) -> Maybe Sig
forall a. IO a -> a
unsafePerformIO (IO (Maybe Sig) -> Maybe Sig) -> IO (Maybe Sig) -> Maybe Sig
forall a b. (a -> b) -> a -> b
$ ForeignPtr LCtx -> (Ptr LCtx -> IO (Maybe Sig)) -> IO (Maybe Sig)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr LCtx
fctx ((Ptr LCtx -> IO (Maybe Sig)) -> IO (Maybe Sig))
-> (Ptr LCtx -> IO (Maybe Sig)) -> IO (Maybe Sig)
forall a b. (a -> b) -> a -> b
$ \Ptr LCtx
ctx ->
        ByteString
-> ((Ptr CUChar, CSize) -> IO (Maybe Sig)) -> IO (Maybe Sig)
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
bs (((Ptr CUChar, CSize) -> IO (Maybe Sig)) -> IO (Maybe Sig))
-> ((Ptr CUChar, CSize) -> IO (Maybe Sig)) -> IO (Maybe Sig)
forall a b. (a -> b) -> a -> b
$ \(Ptr CUChar
in_ptr, CSize
in_len) -> do
          Ptr Sig64
out_sig <- Int -> IO (Ptr Sig64)
forall a. Int -> IO (Ptr a)
mallocBytes Int
64
          CInt
ret <- Ptr LCtx -> Ptr Sig64 -> Ptr CUChar -> CSize -> IO CInt
ecdsaSignatureParseDer Ptr LCtx
ctx Ptr Sig64
out_sig Ptr CUChar
in_ptr CSize
in_len
          if CInt -> Bool
isSuccess CInt
ret
            then do
              ByteString
out_bs <- (Ptr Sig64, CSize) -> IO ByteString
forall a. (Ptr a, CSize) -> IO ByteString
unsafePackByteString (Ptr Sig64
out_sig, CSize
64)
              Maybe Sig -> IO (Maybe Sig)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Sig -> Maybe Sig
forall a. a -> Maybe a
Just (ByteString -> Sig
Sig ByteString
out_bs))
            else do
              Ptr Sig64 -> IO ()
forall a. Ptr a -> IO ()
free Ptr Sig64
out_sig
              Maybe Sig -> IO (Maybe Sig)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Sig
forall a. Maybe a
Nothing

-- | Encode signature as strict DER.
exportSig :: Ctx -> Sig -> ByteString
exportSig :: Ctx -> Sig -> ByteString
exportSig (Ctx ForeignPtr LCtx
fctx) (Sig ByteString
in_sig) =
  IO ByteString -> ByteString
forall a. IO a -> a
unsafePerformIO (IO ByteString -> ByteString) -> IO ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ ForeignPtr LCtx -> (Ptr LCtx -> IO ByteString) -> IO ByteString
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr LCtx
fctx ((Ptr LCtx -> IO ByteString) -> IO ByteString)
-> (Ptr LCtx -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \Ptr LCtx
ctx ->
    ByteString
-> ((Ptr Sig64, CSize) -> IO ByteString) -> IO ByteString
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
in_sig (((Ptr Sig64, CSize) -> IO ByteString) -> IO ByteString)
-> ((Ptr Sig64, CSize) -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \(Ptr Sig64
in_ptr, CSize
_) ->
      (Ptr CSize -> IO ByteString) -> IO ByteString
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr CSize -> IO ByteString) -> IO ByteString)
-> (Ptr CSize -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \Ptr CSize
out_len ->
        Int -> (Ptr CUChar -> IO ByteString) -> IO ByteString
forall a b. Int -> (Ptr a -> IO b) -> IO b
allocaBytes Int
72 ((Ptr CUChar -> IO ByteString) -> IO ByteString)
-> (Ptr CUChar -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \Ptr CUChar
out_ptr -> do
          Ptr CSize -> CSize -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr CSize
out_len CSize
72
          CInt
ret <- Ptr LCtx -> Ptr CUChar -> Ptr CSize -> Ptr Sig64 -> IO CInt
ecdsaSignatureSerializeDer Ptr LCtx
ctx Ptr CUChar
out_ptr Ptr CSize
out_len Ptr Sig64
in_ptr
          Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (CInt -> Bool
isSuccess CInt
ret) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ String -> IO ()
forall a. HasCallStack => String -> a
error String
"could not serialize signature"
          CSize
final_len <- Ptr CSize -> IO CSize
forall a. Storable a => Ptr a -> IO a
peek Ptr CSize
out_len
          (Ptr CUChar, CSize) -> IO ByteString
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 :: Ctx -> PubKey -> Sig -> Msg -> Bool
verifySig :: Ctx -> PubKey -> Sig -> Msg -> Bool
verifySig (Ctx ForeignPtr LCtx
fctx) (PubKey ByteString
pub_key) (Sig ByteString
sig) (Msg ByteString
m) =
  IO Bool -> Bool
forall a. IO a -> a
unsafePerformIO (IO Bool -> Bool) -> IO Bool -> Bool
forall a b. (a -> b) -> a -> b
$ ForeignPtr LCtx -> (Ptr LCtx -> IO Bool) -> IO Bool
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr LCtx
fctx ((Ptr LCtx -> IO Bool) -> IO Bool)
-> (Ptr LCtx -> IO Bool) -> IO Bool
forall a b. (a -> b) -> a -> b
$ \Ptr LCtx
ctx ->
    ByteString -> ((Ptr PubKey64, CSize) -> IO Bool) -> IO Bool
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
pub_key (((Ptr PubKey64, CSize) -> IO Bool) -> IO Bool)
-> ((Ptr PubKey64, CSize) -> IO Bool) -> IO Bool
forall a b. (a -> b) -> a -> b
$ \(Ptr PubKey64
pub_key_ptr, CSize
_) ->
      ByteString -> ((Ptr Sig64, CSize) -> IO Bool) -> IO Bool
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
sig (((Ptr Sig64, CSize) -> IO Bool) -> IO Bool)
-> ((Ptr Sig64, CSize) -> IO Bool) -> IO Bool
forall a b. (a -> b) -> a -> b
$ \(Ptr Sig64
sig_ptr, CSize
_) ->
        ByteString -> ((Ptr Msg32, CSize) -> IO Bool) -> IO Bool
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
m (((Ptr Msg32, CSize) -> IO Bool) -> IO Bool)
-> ((Ptr Msg32, CSize) -> IO Bool) -> IO Bool
forall a b. (a -> b) -> a -> b
$ \(Ptr Msg32
msg_ptr, CSize
_) ->
          CInt -> Bool
isSuccess (CInt -> Bool) -> IO CInt -> IO Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr LCtx -> Ptr Sig64 -> Ptr Msg32 -> Ptr PubKey64 -> IO CInt
ecdsaVerify Ptr LCtx
ctx Ptr Sig64
sig_ptr Ptr Msg32
msg_ptr Ptr PubKey64
pub_key_ptr

signMsg :: Ctx -> SecKey -> Msg -> Sig
signMsg :: Ctx -> SecKey -> Msg -> Sig
signMsg (Ctx ForeignPtr LCtx
fctx) (SecKey ByteString
sec_key) (Msg ByteString
m) =
  IO Sig -> Sig
forall a. IO a -> a
unsafePerformIO (IO Sig -> Sig) -> IO Sig -> Sig
forall a b. (a -> b) -> a -> b
$ ForeignPtr LCtx -> (Ptr LCtx -> IO Sig) -> IO Sig
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr LCtx
fctx ((Ptr LCtx -> IO Sig) -> IO Sig) -> (Ptr LCtx -> IO Sig) -> IO Sig
forall a b. (a -> b) -> a -> b
$ \Ptr LCtx
ctx ->
    ByteString -> ((Ptr SecKey32, CSize) -> IO Sig) -> IO Sig
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
sec_key (((Ptr SecKey32, CSize) -> IO Sig) -> IO Sig)
-> ((Ptr SecKey32, CSize) -> IO Sig) -> IO Sig
forall a b. (a -> b) -> a -> b
$ \(Ptr SecKey32
sec_key_ptr, CSize
_) ->
      ByteString -> ((Ptr Msg32, CSize) -> IO Sig) -> IO Sig
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
m (((Ptr Msg32, CSize) -> IO Sig) -> IO Sig)
-> ((Ptr Msg32, CSize) -> IO Sig) -> IO Sig
forall a b. (a -> b) -> a -> b
$ \(Ptr Msg32
msg_ptr, CSize
_) -> do
        Ptr Sig64
sig_ptr <- Int -> IO (Ptr Sig64)
forall a. Int -> IO (Ptr a)
mallocBytes Int
64
        CInt
ret <- Ptr LCtx
-> Ptr Sig64
-> Ptr Msg32
-> Ptr SecKey32
-> FunPtr (NonceFun Any)
-> Ptr Any
-> IO CInt
forall a.
Ptr LCtx
-> Ptr Sig64
-> Ptr Msg32
-> Ptr SecKey32
-> FunPtr (NonceFun a)
-> Ptr a
-> IO CInt
ecdsaSign Ptr LCtx
ctx Ptr Sig64
sig_ptr Ptr Msg32
msg_ptr Ptr SecKey32
sec_key_ptr FunPtr (NonceFun Any)
forall a. FunPtr a
nullFunPtr Ptr Any
forall a. Ptr a
nullPtr
        Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (CInt -> Bool
isSuccess CInt
ret) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
          Ptr Sig64 -> IO ()
forall a. Ptr a -> IO ()
free Ptr Sig64
sig_ptr
          String -> IO ()
forall a. HasCallStack => String -> a
error String
"could not sign message"
        ByteString -> Sig
Sig (ByteString -> Sig) -> IO ByteString -> IO Sig
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Ptr Sig64, CSize) -> IO ByteString
forall a. (Ptr a, CSize) -> IO ByteString
unsafePackByteString (Ptr Sig64
sig_ptr, CSize
64)

derivePubKey :: Ctx -> SecKey -> PubKey
derivePubKey :: Ctx -> SecKey -> PubKey
derivePubKey (Ctx ForeignPtr LCtx
fctx) (SecKey ByteString
sec_key) =
  IO PubKey -> PubKey
forall a. IO a -> a
unsafePerformIO (IO PubKey -> PubKey) -> IO PubKey -> PubKey
forall a b. (a -> b) -> a -> b
$ ForeignPtr LCtx -> (Ptr LCtx -> IO PubKey) -> IO PubKey
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr LCtx
fctx ((Ptr LCtx -> IO PubKey) -> IO PubKey)
-> (Ptr LCtx -> IO PubKey) -> IO PubKey
forall a b. (a -> b) -> a -> b
$ \Ptr LCtx
ctx ->
    ByteString -> ((Ptr SecKey32, CSize) -> IO PubKey) -> IO PubKey
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
sec_key (((Ptr SecKey32, CSize) -> IO PubKey) -> IO PubKey)
-> ((Ptr SecKey32, CSize) -> IO PubKey) -> IO PubKey
forall a b. (a -> b) -> a -> b
$ \(Ptr SecKey32
sec_key_ptr, CSize
_) -> do
      Ptr PubKey64
pub_key_ptr <- Int -> IO (Ptr PubKey64)
forall a. Int -> IO (Ptr a)
mallocBytes Int
64
      CInt
ret <- Ptr LCtx -> Ptr PubKey64 -> Ptr SecKey32 -> IO CInt
ecPubKeyCreate Ptr LCtx
ctx Ptr PubKey64
pub_key_ptr Ptr SecKey32
sec_key_ptr
      Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (CInt -> Bool
isSuccess CInt
ret) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
        Ptr PubKey64 -> IO ()
forall a. Ptr a -> IO ()
free Ptr PubKey64
pub_key_ptr
        String -> IO ()
forall a. HasCallStack => String -> a
error String
"could not compute public key"
      ByteString -> PubKey
PubKey (ByteString -> PubKey) -> IO ByteString -> IO PubKey
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Ptr PubKey64, CSize) -> IO ByteString
forall a. (Ptr a, CSize) -> IO ByteString
unsafePackByteString (Ptr PubKey64
pub_key_ptr, CSize
64)

-- | Add tweak to secret key.
tweakAddSecKey :: Ctx -> SecKey -> Tweak -> Maybe SecKey
tweakAddSecKey :: Ctx -> SecKey -> Tweak -> Maybe SecKey
tweakAddSecKey (Ctx ForeignPtr LCtx
fctx) (SecKey ByteString
sec_key) (Tweak ByteString
t) =
  IO (Maybe SecKey) -> Maybe SecKey
forall a. IO a -> a
unsafePerformIO (IO (Maybe SecKey) -> Maybe SecKey)
-> IO (Maybe SecKey) -> Maybe SecKey
forall a b. (a -> b) -> a -> b
$ ForeignPtr LCtx
-> (Ptr LCtx -> IO (Maybe SecKey)) -> IO (Maybe SecKey)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr LCtx
fctx ((Ptr LCtx -> IO (Maybe SecKey)) -> IO (Maybe SecKey))
-> (Ptr LCtx -> IO (Maybe SecKey)) -> IO (Maybe SecKey)
forall a b. (a -> b) -> a -> b
$ \Ptr LCtx
ctx ->
    ByteString
-> ((Ptr SecKey32, CSize) -> IO (Maybe SecKey))
-> IO (Maybe SecKey)
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
new_bs (((Ptr SecKey32, CSize) -> IO (Maybe SecKey)) -> IO (Maybe SecKey))
-> ((Ptr SecKey32, CSize) -> IO (Maybe SecKey))
-> IO (Maybe SecKey)
forall a b. (a -> b) -> a -> b
$ \(Ptr SecKey32
sec_key_ptr, CSize
_) ->
      ByteString
-> ((Ptr Tweak32, CSize) -> IO (Maybe SecKey)) -> IO (Maybe SecKey)
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
t (((Ptr Tweak32, CSize) -> IO (Maybe SecKey)) -> IO (Maybe SecKey))
-> ((Ptr Tweak32, CSize) -> IO (Maybe SecKey)) -> IO (Maybe SecKey)
forall a b. (a -> b) -> a -> b
$ \(Ptr Tweak32
tweak_ptr, CSize
_) -> do
        CInt
ret <- Ptr LCtx -> Ptr SecKey32 -> Ptr Tweak32 -> IO CInt
ecSecKeyTweakAdd Ptr LCtx
ctx Ptr SecKey32
sec_key_ptr Ptr Tweak32
tweak_ptr
        if CInt -> Bool
isSuccess CInt
ret
          then Maybe SecKey -> IO (Maybe SecKey)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (SecKey -> Maybe SecKey
forall a. a -> Maybe a
Just (ByteString -> SecKey
SecKey ByteString
new_bs))
          else Maybe SecKey -> IO (Maybe SecKey)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe SecKey
forall a. Maybe a
Nothing
  where
    new_bs :: ByteString
new_bs = ByteString -> ByteString
BS.copy ByteString
sec_key

-- | Multiply secret key by tweak.
tweakMulSecKey :: Ctx -> SecKey -> Tweak -> Maybe SecKey
tweakMulSecKey :: Ctx -> SecKey -> Tweak -> Maybe SecKey
tweakMulSecKey (Ctx ForeignPtr LCtx
fctx) (SecKey ByteString
sec_key) (Tweak ByteString
t) =
  IO (Maybe SecKey) -> Maybe SecKey
forall a. IO a -> a
unsafePerformIO (IO (Maybe SecKey) -> Maybe SecKey)
-> IO (Maybe SecKey) -> Maybe SecKey
forall a b. (a -> b) -> a -> b
$ ForeignPtr LCtx
-> (Ptr LCtx -> IO (Maybe SecKey)) -> IO (Maybe SecKey)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr LCtx
fctx ((Ptr LCtx -> IO (Maybe SecKey)) -> IO (Maybe SecKey))
-> (Ptr LCtx -> IO (Maybe SecKey)) -> IO (Maybe SecKey)
forall a b. (a -> b) -> a -> b
$ \Ptr LCtx
ctx ->
    ByteString
-> ((Ptr SecKey32, CSize) -> IO (Maybe SecKey))
-> IO (Maybe SecKey)
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
new_bs (((Ptr SecKey32, CSize) -> IO (Maybe SecKey)) -> IO (Maybe SecKey))
-> ((Ptr SecKey32, CSize) -> IO (Maybe SecKey))
-> IO (Maybe SecKey)
forall a b. (a -> b) -> a -> b
$ \(Ptr SecKey32
sec_key_ptr, CSize
_) ->
      ByteString
-> ((Ptr Tweak32, CSize) -> IO (Maybe SecKey)) -> IO (Maybe SecKey)
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
t (((Ptr Tweak32, CSize) -> IO (Maybe SecKey)) -> IO (Maybe SecKey))
-> ((Ptr Tweak32, CSize) -> IO (Maybe SecKey)) -> IO (Maybe SecKey)
forall a b. (a -> b) -> a -> b
$ \(Ptr Tweak32
tweak_ptr, CSize
_) -> do
        CInt
ret <- Ptr LCtx -> Ptr SecKey32 -> Ptr Tweak32 -> IO CInt
ecSecKeyTweakMul Ptr LCtx
ctx Ptr SecKey32
sec_key_ptr Ptr Tweak32
tweak_ptr
        if CInt -> Bool
isSuccess CInt
ret
          then Maybe SecKey -> IO (Maybe SecKey)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (SecKey -> Maybe SecKey
forall a. a -> Maybe a
Just (ByteString -> SecKey
SecKey ByteString
new_bs))
          else Maybe SecKey -> IO (Maybe SecKey)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe SecKey
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 :: Ctx -> PubKey -> Tweak -> Maybe PubKey
tweakAddPubKey :: Ctx -> PubKey -> Tweak -> Maybe PubKey
tweakAddPubKey (Ctx ForeignPtr LCtx
fctx) (PubKey ByteString
pub_key) (Tweak ByteString
t) =
  IO (Maybe PubKey) -> Maybe PubKey
forall a. IO a -> a
unsafePerformIO (IO (Maybe PubKey) -> Maybe PubKey)
-> IO (Maybe PubKey) -> Maybe PubKey
forall a b. (a -> b) -> a -> b
$ ForeignPtr LCtx
-> (Ptr LCtx -> IO (Maybe PubKey)) -> IO (Maybe PubKey)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr LCtx
fctx ((Ptr LCtx -> IO (Maybe PubKey)) -> IO (Maybe PubKey))
-> (Ptr LCtx -> IO (Maybe PubKey)) -> IO (Maybe PubKey)
forall a b. (a -> b) -> a -> b
$ \Ptr LCtx
ctx ->
    ByteString
-> ((Ptr PubKey64, CSize) -> IO (Maybe PubKey))
-> IO (Maybe PubKey)
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
new_bs (((Ptr PubKey64, CSize) -> IO (Maybe PubKey)) -> IO (Maybe PubKey))
-> ((Ptr PubKey64, CSize) -> IO (Maybe PubKey))
-> IO (Maybe PubKey)
forall a b. (a -> b) -> a -> b
$ \(Ptr PubKey64
pub_key_ptr, CSize
_) ->
      ByteString
-> ((Ptr Tweak32, CSize) -> IO (Maybe PubKey)) -> IO (Maybe PubKey)
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
t (((Ptr Tweak32, CSize) -> IO (Maybe PubKey)) -> IO (Maybe PubKey))
-> ((Ptr Tweak32, CSize) -> IO (Maybe PubKey)) -> IO (Maybe PubKey)
forall a b. (a -> b) -> a -> b
$ \(Ptr Tweak32
tweak_ptr, CSize
_) -> do
        CInt
ret <- Ptr LCtx -> Ptr PubKey64 -> Ptr Tweak32 -> IO CInt
ecPubKeyTweakAdd Ptr LCtx
ctx Ptr PubKey64
pub_key_ptr Ptr Tweak32
tweak_ptr
        if CInt -> Bool
isSuccess CInt
ret
          then Maybe PubKey -> IO (Maybe PubKey)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (PubKey -> Maybe PubKey
forall a. a -> Maybe a
Just (ByteString -> PubKey
PubKey ByteString
new_bs))
          else Maybe PubKey -> IO (Maybe PubKey)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe PubKey
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 :: Ctx -> PubKey -> Tweak -> Maybe PubKey
tweakMulPubKey :: Ctx -> PubKey -> Tweak -> Maybe PubKey
tweakMulPubKey (Ctx ForeignPtr LCtx
fctx) (PubKey ByteString
pub_key) (Tweak ByteString
t) =
  IO (Maybe PubKey) -> Maybe PubKey
forall a. IO a -> a
unsafePerformIO (IO (Maybe PubKey) -> Maybe PubKey)
-> IO (Maybe PubKey) -> Maybe PubKey
forall a b. (a -> b) -> a -> b
$ ForeignPtr LCtx
-> (Ptr LCtx -> IO (Maybe PubKey)) -> IO (Maybe PubKey)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr LCtx
fctx ((Ptr LCtx -> IO (Maybe PubKey)) -> IO (Maybe PubKey))
-> (Ptr LCtx -> IO (Maybe PubKey)) -> IO (Maybe PubKey)
forall a b. (a -> b) -> a -> b
$ \Ptr LCtx
ctx ->
    ByteString
-> ((Ptr PubKey64, CSize) -> IO (Maybe PubKey))
-> IO (Maybe PubKey)
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
new_bs (((Ptr PubKey64, CSize) -> IO (Maybe PubKey)) -> IO (Maybe PubKey))
-> ((Ptr PubKey64, CSize) -> IO (Maybe PubKey))
-> IO (Maybe PubKey)
forall a b. (a -> b) -> a -> b
$ \(Ptr PubKey64
pub_key_ptr, CSize
_) ->
      ByteString
-> ((Ptr Tweak32, CSize) -> IO (Maybe PubKey)) -> IO (Maybe PubKey)
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
t (((Ptr Tweak32, CSize) -> IO (Maybe PubKey)) -> IO (Maybe PubKey))
-> ((Ptr Tweak32, CSize) -> IO (Maybe PubKey)) -> IO (Maybe PubKey)
forall a b. (a -> b) -> a -> b
$ \(Ptr Tweak32
tweak_ptr, CSize
_) -> do
        CInt
ret <- Ptr LCtx -> Ptr PubKey64 -> Ptr Tweak32 -> IO CInt
ecPubKeyTweakMul Ptr LCtx
ctx Ptr PubKey64
pub_key_ptr Ptr Tweak32
tweak_ptr
        if CInt -> Bool
isSuccess CInt
ret
          then Maybe PubKey -> IO (Maybe PubKey)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (PubKey -> Maybe PubKey
forall a. a -> Maybe a
Just (ByteString -> PubKey
PubKey ByteString
new_bs))
          else Maybe PubKey -> IO (Maybe PubKey)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe PubKey
forall a. Maybe a
Nothing
  where
    new_bs :: ByteString
new_bs = ByteString -> ByteString
BS.copy ByteString
pub_key

-- | Add multiple public keys together.
combinePubKeys :: Ctx -> [PubKey] -> Maybe PubKey
combinePubKeys :: Ctx -> [PubKey] -> Maybe PubKey
combinePubKeys Ctx
_ [] = Maybe PubKey
forall a. Maybe a
Nothing
combinePubKeys (Ctx ForeignPtr LCtx
fctx) [PubKey]
pubs =
  IO (Maybe PubKey) -> Maybe PubKey
forall a. IO a -> a
unsafePerformIO (IO (Maybe PubKey) -> Maybe PubKey)
-> IO (Maybe PubKey) -> Maybe PubKey
forall a b. (a -> b) -> a -> b
$ ForeignPtr LCtx
-> (Ptr LCtx -> IO (Maybe PubKey)) -> IO (Maybe PubKey)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr LCtx
fctx ((Ptr LCtx -> IO (Maybe PubKey)) -> IO (Maybe PubKey))
-> (Ptr LCtx -> IO (Maybe PubKey)) -> IO (Maybe PubKey)
forall a b. (a -> b) -> a -> b
$ \Ptr LCtx
ctx ->
    [Ptr PubKey64]
-> [PubKey]
-> ([Ptr PubKey64] -> IO (Maybe PubKey))
-> IO (Maybe PubKey)
forall {a} {b}. [Ptr a] -> [PubKey] -> ([Ptr a] -> IO b) -> IO b
pointers [] [PubKey]
pubs (([Ptr PubKey64] -> IO (Maybe PubKey)) -> IO (Maybe PubKey))
-> ([Ptr PubKey64] -> IO (Maybe PubKey)) -> IO (Maybe PubKey)
forall a b. (a -> b) -> a -> b
$ \[Ptr PubKey64]
ps ->
      Int
-> (Ptr (Ptr PubKey64) -> IO (Maybe PubKey)) -> IO (Maybe PubKey)
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray ([Ptr PubKey64] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Ptr PubKey64]
ps) ((Ptr (Ptr PubKey64) -> IO (Maybe PubKey)) -> IO (Maybe PubKey))
-> (Ptr (Ptr PubKey64) -> IO (Maybe PubKey)) -> IO (Maybe PubKey)
forall a b. (a -> b) -> a -> b
$ \Ptr (Ptr PubKey64)
a -> do
        Ptr PubKey64
out <- Int -> IO (Ptr PubKey64)
forall a. Int -> IO (Ptr a)
mallocBytes Int
64
        Ptr (Ptr PubKey64) -> [Ptr PubKey64] -> IO ()
forall a. Storable a => Ptr a -> [a] -> IO ()
pokeArray Ptr (Ptr PubKey64)
a [Ptr PubKey64]
ps
        CInt
ret <- Ptr LCtx -> Ptr PubKey64 -> Ptr (Ptr PubKey64) -> CInt -> IO CInt
ecPubKeyCombine Ptr LCtx
ctx Ptr PubKey64
out Ptr (Ptr PubKey64)
a (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> CInt) -> Int -> CInt
forall a b. (a -> b) -> a -> b
$ [Ptr PubKey64] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Ptr PubKey64]
ps)
        if CInt -> Bool
isSuccess CInt
ret
          then do
            ByteString
bs <- (Ptr PubKey64, CSize) -> IO ByteString
forall a. (Ptr a, CSize) -> IO ByteString
unsafePackByteString (Ptr PubKey64
out, CSize
64)
            Maybe PubKey -> IO (Maybe PubKey)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (PubKey -> Maybe PubKey
forall a. a -> Maybe a
Just (ByteString -> PubKey
PubKey ByteString
bs))
          else do
            Ptr PubKey64 -> IO ()
forall a. Ptr a -> IO ()
free Ptr PubKey64
out
            Maybe PubKey -> IO (Maybe PubKey)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe PubKey
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 =
      ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
pub_key (((Ptr a, CSize) -> IO b) -> IO b)
-> ((Ptr a, CSize) -> IO b) -> IO b
forall a b. (a -> b) -> a -> b
$ \(Ptr a
p, CSize
_) ->
        [Ptr a] -> [PubKey] -> ([Ptr a] -> IO b) -> IO b
pointers (Ptr a
p Ptr a -> [Ptr a] -> [Ptr a]
forall a. a -> [a] -> [a]
: [Ptr a]
ps) [PubKey]
pub_keys [Ptr a] -> IO b
f

tweakNegate :: Ctx -> Tweak -> Maybe Tweak
tweakNegate :: Ctx -> Tweak -> Maybe Tweak
tweakNegate (Ctx ForeignPtr LCtx
fctx) (Tweak ByteString
t) =
  IO (Maybe Tweak) -> Maybe Tweak
forall a. IO a -> a
unsafePerformIO (IO (Maybe Tweak) -> Maybe Tweak)
-> IO (Maybe Tweak) -> Maybe Tweak
forall a b. (a -> b) -> a -> b
$ ForeignPtr LCtx
-> (Ptr LCtx -> IO (Maybe Tweak)) -> IO (Maybe Tweak)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr LCtx
fctx ((Ptr LCtx -> IO (Maybe Tweak)) -> IO (Maybe Tweak))
-> (Ptr LCtx -> IO (Maybe Tweak)) -> IO (Maybe Tweak)
forall a b. (a -> b) -> a -> b
$ \Ptr LCtx
ctx ->
    ByteString
-> ((Ptr Tweak32, CSize) -> IO (Maybe Tweak)) -> IO (Maybe Tweak)
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
new (((Ptr Tweak32, CSize) -> IO (Maybe Tweak)) -> IO (Maybe Tweak))
-> ((Ptr Tweak32, CSize) -> IO (Maybe Tweak)) -> IO (Maybe Tweak)
forall a b. (a -> b) -> a -> b
$ \(Ptr Tweak32
out, CSize
_) -> do
      CInt
ret <- Ptr LCtx -> Ptr Tweak32 -> IO CInt
ecTweakNegate Ptr LCtx
ctx Ptr Tweak32
out
      if CInt -> Bool
isSuccess CInt
ret
        then Maybe Tweak -> IO (Maybe Tweak)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Tweak -> Maybe Tweak
forall a. a -> Maybe a
Just (ByteString -> Tweak
Tweak ByteString
new))
        else Maybe Tweak -> IO (Maybe Tweak)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Tweak
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 Gen (Maybe Msg) -> (Maybe Msg -> Bool) -> Gen (Maybe Msg)
forall a. Gen a -> (a -> Bool) -> Gen a
`suchThat` Maybe Msg -> Bool
forall a. Maybe a -> Bool
isJust
      bs_gen :: Gen (Maybe Msg)
bs_gen = ByteString -> Maybe Msg
msg (ByteString -> Maybe Msg)
-> ([Word8] -> ByteString) -> [Word8] -> Maybe Msg
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Word8] -> ByteString
BS.pack ([Word8] -> Maybe Msg) -> Gen [Word8] -> Gen (Maybe Msg)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Gen Word8 -> Gen [Word8]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
32 Gen Word8
forall a. (Bounded a, Random a) => Gen a
arbitraryBoundedRandom
      gen_msg :: Gen Msg
gen_msg = Maybe Msg -> Msg
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe Msg -> Msg) -> Gen (Maybe Msg) -> Gen Msg
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 Gen (Maybe SecKey) -> (Maybe SecKey -> Bool) -> Gen (Maybe SecKey)
forall a. Gen a -> (a -> Bool) -> Gen a
`suchThat` Maybe SecKey -> Bool
forall a. Maybe a -> Bool
isJust
      bs_gen :: Gen (Maybe SecKey)
bs_gen = ByteString -> Maybe SecKey
secKey (ByteString -> Maybe SecKey)
-> ([Word8] -> ByteString) -> [Word8] -> Maybe SecKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Word8] -> ByteString
BS.pack ([Word8] -> Maybe SecKey) -> Gen [Word8] -> Gen (Maybe SecKey)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Gen Word8 -> Gen [Word8]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
32 Gen Word8
forall a. (Bounded a, Random a) => Gen a
arbitraryBoundedRandom
      gen_key :: Gen SecKey
gen_key = Maybe SecKey -> SecKey
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe SecKey -> SecKey) -> Gen (Maybe SecKey) -> Gen SecKey
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen (Maybe SecKey)
valid_bs