{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE MultiWayIf #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE TypeApplications #-}
{-# OPTIONS_GHC -fno-show-valid-hole-fits #-}

-- |
-- Module      : Crypto.Secp256k1
-- License     : UNLICENSE
-- Maintainer  : Keagan McClelland <keagan.mcclelland@gmail.com>
-- Stability   : experimental
-- Portability : POSIX
--
-- Crytpographic functions from Bitcoin’s secp256k1 library.
module Crypto.Secp256k1 (
    -- * Core Types
    SecKey,
    PubKeyXY,
    PubKeyXO,
    KeyPair,
    Signature,
    RecoverableSignature,
    Tweak,

    -- * Parsing and Serialization
    importSecKey,
    importPubKeyXY,
    exportPubKeyXY,
    importPubKeyXO,
    exportPubKeyXO,
    importSignature,
    exportSignatureCompact,
    exportSignatureDer,
    importRecoverableSignature,
    exportRecoverableSignature,
    importTweak,

    -- * ECDSA Operations
    ecdsaVerify,
    ecdsaSign,
    ecdsaSignRecoverable,
    ecdsaRecover,

    -- * Conversions
    recSigToSig,
    derivePubKey,
    keyPairCreate,
    keyPairPubKeyXY,
    keyPairPubKeyXO,
    xyToXO,

    -- * Tweaks
    ecSecKeyTweakAdd,
    ecSecKeyTweakMul,
    keyPairPubKeyXOTweakAdd,
    pubKeyCombine,
    pubKeyNegate,
    secKeyNegate,
    pubKeyTweakAdd,
    pubKeyTweakMul,
    pubKeyXOTweakAdd,
    pubKeyXOTweakAddCheck,

    -- * Schnorr Operations
    schnorrSign,
    SchnorrExtra (..),
    schnorrSignCustom,
    schnorrVerify,

    -- * Other
    taggedSha256,
    ecdh,
) where

import Control.Monad (replicateM, unless, (<=<))
import Control.Monad.Trans.Class (lift)
import Control.Monad.Trans.Cont (ContT (..), evalContT)
import Crypto.Secp256k1.Internal
import Crypto.Secp256k1.Prim (flagsEcUncompressed)
import qualified Crypto.Secp256k1.Prim as Prim
import Data.ByteArray.Sized
import Data.ByteString (ByteString)
import qualified Data.ByteString as BS

-- import qualified Data.ByteString.Base16 as B16
import Data.ByteString.Unsafe (unsafePackCStringLen, unsafePackMallocCStringLen)
import Data.Functor (($>))

-- import Data.Hashable (Hashable (..))
import Data.Maybe (fromJust, fromMaybe, isJust)
import Data.String (IsString (..))

-- import Data.String.Conversions (ConvertibleStrings, cs)

import Crypto.Hash (Digest, SHA256, digestFromByteString)
import Data.Foldable (for_)
import Foreign (
    Bits (..),
    ForeignPtr,
    FunPtr,
    Ptr,
    Storable,
    Word8,
    alloca,
    allocaArray,
    allocaBytes,
    castForeignPtr,
    castPtr,
    finalizerFree,
    free,
    freeHaskellFunPtr,
    malloc,
    mallocBytes,
    newForeignPtr,
    newForeignPtr_,
    nullFunPtr,
    nullPtr,
    peek,
    peekByteOff,
    peekElemOff,
    plusPtr,
    poke,
    pokeArray,
    pokeByteOff,
    pokeElemOff,
    sizeOf,
    withForeignPtr,
 )
import Foreign.C (CInt (..), CSize (..))
import GHC.Generics (Generic)
import GHC.IO.Handle.Text (memcpy)
import System.IO.Unsafe (unsafePerformIO)
import Text.Read (
    Lexeme (String),
    lexP,
    parens,
    pfail,
    readPrec,
 )


newtype SecKey = SecKey {SecKey -> ForeignPtr Seckey32
secKeyFPtr :: ForeignPtr Prim.Seckey32}
newtype PubKeyXY = PubKeyXY {PubKeyXY -> ForeignPtr Pubkey64
pubKeyXYFPtr :: ForeignPtr Prim.Pubkey64}
newtype PubKeyXO = PubKeyXO {PubKeyXO -> ForeignPtr XonlyPubkey64
pubKeyXOFPtr :: ForeignPtr Prim.XonlyPubkey64}
newtype KeyPair = KeyPair {KeyPair -> ForeignPtr Keypair96
keyPairFPtr :: ForeignPtr Prim.Keypair96}
newtype Signature = Signature {Signature -> ForeignPtr Sig64
signatureFPtr :: ForeignPtr Prim.Sig64}
newtype RecoverableSignature = RecoverableSignature {RecoverableSignature -> ForeignPtr RecSig65
recoverableSignatureFPtr :: ForeignPtr Prim.RecSig65}
newtype Tweak = Tweak {Tweak -> ForeignPtr Tweak32
tweakFPtr :: ForeignPtr Prim.Tweak32}


-- | Preinitialized context for signing and verification
ctx :: Prim.Ctx
ctx :: Ctx
ctx = IO Ctx -> Ctx
forall a. IO a -> a
unsafePerformIO (IO Ctx -> Ctx) -> IO Ctx -> Ctx
forall a b. (a -> b) -> a -> b
$ ContextFlags -> IO Ctx
Prim.contextCreate (ContextFlags
Prim.flagsContextSign ContextFlags -> ContextFlags -> ContextFlags
forall a. Bits a => a -> a -> a
.|. ContextFlags
Prim.flagsContextVerify)
{-# NOINLINE ctx #-}


-- | Parses 'SecKey', will be @Nothing@ if the @ByteString@ corresponds to 0{32} or is not 32 bytes in length
importSecKey :: ByteString -> Maybe SecKey
importSecKey :: ByteString -> Maybe SecKey
importSecKey ByteString
bs
    | ByteString -> Int
BS.length ByteString
bs Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
32 = Maybe SecKey
forall a. Maybe a
Nothing
    | Bool
otherwise = 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
$ do
        ByteString
-> ((Ptr Seckey32, CSize) -> IO (Maybe SecKey))
-> IO (Maybe SecKey)
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
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
ptr, CSize
len) -> do
            Ret
ret <- Ctx -> Ptr Seckey32 -> IO Ret
Prim.ecSecKeyVerify Ctx
ctx Ptr Seckey32
ptr
            if Ret -> Bool
isSuccess Ret
ret
                then do
                    Ptr Seckey32
newPtr <- Int -> IO (Ptr Seckey32)
forall a. Int -> IO (Ptr a)
mallocBytes Int
32
                    Ptr Seckey32 -> Ptr Seckey32 -> CSize -> IO (Ptr ())
forall a. Ptr a -> Ptr a -> CSize -> IO (Ptr ())
memcpy Ptr Seckey32
newPtr Ptr Seckey32
ptr CSize
32
                    SecKey -> Maybe SecKey
forall a. a -> Maybe a
Just (SecKey -> Maybe SecKey)
-> (ForeignPtr Seckey32 -> SecKey)
-> ForeignPtr Seckey32
-> Maybe SecKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ForeignPtr Seckey32 -> SecKey
SecKey (ForeignPtr Seckey32 -> Maybe SecKey)
-> IO (ForeignPtr Seckey32) -> IO (Maybe SecKey)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FinalizerPtr Seckey32 -> Ptr Seckey32 -> IO (ForeignPtr Seckey32)
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr FinalizerPtr Seckey32
forall a. FinalizerPtr a
finalizerFree Ptr Seckey32
newPtr
                else Maybe SecKey -> IO (Maybe SecKey)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe SecKey
forall a. Maybe a
Nothing


-- | Parses a 33 or 65 byte 'PubKeyXY', all other lengths will result in @Nothing@
importPubKeyXY :: ByteString -> Maybe PubKeyXY
importPubKeyXY :: ByteString -> Maybe PubKeyXY
importPubKeyXY ByteString
bs = IO (Maybe PubKeyXY) -> Maybe PubKeyXY
forall a. IO a -> a
unsafePerformIO (IO (Maybe PubKeyXY) -> Maybe PubKeyXY)
-> IO (Maybe PubKeyXY) -> Maybe PubKeyXY
forall a b. (a -> b) -> a -> b
$
    ByteString
-> ((Ptr (Bytes Any), CSize) -> IO (Maybe PubKeyXY))
-> IO (Maybe PubKeyXY)
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
bs (((Ptr (Bytes Any), CSize) -> IO (Maybe PubKeyXY))
 -> IO (Maybe PubKeyXY))
-> ((Ptr (Bytes Any), CSize) -> IO (Maybe PubKeyXY))
-> IO (Maybe PubKeyXY)
forall a b. (a -> b) -> a -> b
$ \(Ptr (Bytes Any)
input, CSize
len) -> do
        Ptr Any
pubkeyOutputBuf <- Int -> IO (Ptr Any)
forall a. Int -> IO (Ptr a)
mallocBytes Int
64
        if CSize
len CSize -> CSize -> Bool
forall a. Eq a => a -> a -> Bool
== CSize
33 Bool -> Bool -> Bool
|| CSize
len CSize -> CSize -> Bool
forall a. Eq a => a -> a -> Bool
== CSize
65
            then do
                Ret
ret <- Ctx -> Ptr Pubkey64 -> Ptr (Bytes Any) -> CSize -> IO Ret
forall (n :: Nat).
Ctx -> Ptr Pubkey64 -> Ptr (Bytes n) -> CSize -> IO Ret
Prim.ecPubkeyParse Ctx
ctx (Ptr Any -> Ptr Pubkey64
forall a b. Ptr a -> Ptr b
castPtr Ptr Any
pubkeyOutputBuf) Ptr (Bytes Any)
input CSize
len
                if Ret -> Bool
isSuccess Ret
ret
                    then PubKeyXY -> Maybe PubKeyXY
forall a. a -> Maybe a
Just (PubKeyXY -> Maybe PubKeyXY)
-> (ForeignPtr Pubkey64 -> PubKeyXY)
-> ForeignPtr Pubkey64
-> Maybe PubKeyXY
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ForeignPtr Pubkey64 -> PubKeyXY
PubKeyXY (ForeignPtr Pubkey64 -> Maybe PubKeyXY)
-> IO (ForeignPtr Pubkey64) -> IO (Maybe PubKeyXY)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FinalizerPtr Pubkey64 -> Ptr Pubkey64 -> IO (ForeignPtr Pubkey64)
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr FinalizerPtr Pubkey64
forall a. FinalizerPtr a
finalizerFree (Ptr Any -> Ptr Pubkey64
forall a b. Ptr a -> Ptr b
castPtr Ptr Any
pubkeyOutputBuf)
                    else Ptr Any -> IO ()
forall a. Ptr a -> IO ()
free Ptr Any
pubkeyOutputBuf IO () -> Maybe PubKeyXY -> IO (Maybe PubKeyXY)
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Maybe PubKeyXY
forall a. Maybe a
Nothing
            else Maybe PubKeyXY -> IO (Maybe PubKeyXY)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe PubKeyXY
forall a. Maybe a
Nothing


-- | Serialize 'PubKeyXY'. First argument @True@ for compressed output (33 bytes), @False@ for uncompressed (65 bytes).
exportPubKeyXY :: Bool -> PubKeyXY -> ByteString
exportPubKeyXY :: Bool -> PubKeyXY -> ByteString
exportPubKeyXY Bool
compress (PubKeyXY ForeignPtr Pubkey64
fptr) = IO ByteString -> ByteString
forall a. IO a -> a
unsafePerformIO (IO ByteString -> ByteString) -> IO ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ do
    let flags :: ContextFlags
flags = if Bool
compress then ContextFlags
Prim.flagsEcCompressed else ContextFlags
Prim.flagsEcUncompressed
    let sz :: Int
sz = if Bool
compress then Int
33 else Int
65
    Ptr (Bytes Any)
buf <- Int -> IO (Ptr (Bytes Any))
forall a. Int -> IO (Ptr a)
mallocBytes Int
sz
    (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
written -> do
        -- always succeeds so we don't need to check
        Ret
_ret <- ForeignPtr Pubkey64 -> (Ptr Pubkey64 -> IO Ret) -> IO Ret
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Pubkey64
fptr ((Ptr Pubkey64 -> IO Ret) -> IO Ret)
-> (Ptr Pubkey64 -> IO Ret) -> IO Ret
forall a b. (a -> b) -> a -> b
$ \Ptr Pubkey64
ptr -> Ctx
-> Ptr (Bytes Any)
-> Ptr CSize
-> Ptr Pubkey64
-> ContextFlags
-> IO Ret
forall (n :: Nat).
Ctx
-> Ptr (Bytes n)
-> Ptr CSize
-> Ptr Pubkey64
-> ContextFlags
-> IO Ret
Prim.ecPubkeySerialize Ctx
ctx Ptr (Bytes Any)
buf Ptr CSize
written Ptr Pubkey64
ptr ContextFlags
flags
        CSize
len <- Ptr CSize -> IO CSize
forall a. Storable a => Ptr a -> IO a
peek Ptr CSize
written
        CStringLen -> IO ByteString
unsafePackMallocCStringLen (Ptr (Bytes Any) -> Ptr CChar
forall a b. Ptr a -> Ptr b
castPtr Ptr (Bytes Any)
buf, CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
len)


-- | Parses 'PubKeyXO' from @ByteString@, will be @Nothing@ if the pubkey corresponds to the Point at Infinity or the
-- the @ByteString@ is not 32 bytes long
importPubKeyXO :: ByteString -> Maybe PubKeyXO
importPubKeyXO :: ByteString -> Maybe PubKeyXO
importPubKeyXO ByteString
bs
    | ByteString -> Int
BS.length ByteString
bs Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
32 = Maybe PubKeyXO
forall a. Maybe a
Nothing
    | Bool
otherwise = IO (Maybe PubKeyXO) -> Maybe PubKeyXO
forall a. IO a -> a
unsafePerformIO (IO (Maybe PubKeyXO) -> Maybe PubKeyXO)
-> IO (Maybe PubKeyXO) -> Maybe PubKeyXO
forall a b. (a -> b) -> a -> b
$ do
        Ptr XonlyPubkey64
outBuf <- Int -> IO (Ptr XonlyPubkey64)
forall a. Int -> IO (Ptr a)
mallocBytes Int
64
        ByteString
-> ((Ptr (Bytes 32), CSize) -> IO (Maybe PubKeyXO))
-> IO (Maybe PubKeyXO)
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
bs (((Ptr (Bytes 32), CSize) -> IO (Maybe PubKeyXO))
 -> IO (Maybe PubKeyXO))
-> ((Ptr (Bytes 32), CSize) -> IO (Maybe PubKeyXO))
-> IO (Maybe PubKeyXO)
forall a b. (a -> b) -> a -> b
$ \(Ptr (Bytes 32)
ptr, CSize
_) -> do
            Ret
ret <- Ctx -> Ptr XonlyPubkey64 -> Ptr (Bytes 32) -> IO Ret
Prim.xonlyPubkeyParse Ctx
ctx Ptr XonlyPubkey64
outBuf Ptr (Bytes 32)
ptr
            if Ret -> Bool
isSuccess Ret
ret
                then PubKeyXO -> Maybe PubKeyXO
forall a. a -> Maybe a
Just (PubKeyXO -> Maybe PubKeyXO)
-> (ForeignPtr XonlyPubkey64 -> PubKeyXO)
-> ForeignPtr XonlyPubkey64
-> Maybe PubKeyXO
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ForeignPtr XonlyPubkey64 -> PubKeyXO
PubKeyXO (ForeignPtr XonlyPubkey64 -> Maybe PubKeyXO)
-> IO (ForeignPtr XonlyPubkey64) -> IO (Maybe PubKeyXO)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FinalizerPtr XonlyPubkey64
-> Ptr XonlyPubkey64 -> IO (ForeignPtr XonlyPubkey64)
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr FinalizerPtr XonlyPubkey64
forall a. FinalizerPtr a
finalizerFree Ptr XonlyPubkey64
outBuf
                else Maybe PubKeyXO -> IO (Maybe PubKeyXO)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe PubKeyXO
forall a. Maybe a
Nothing


-- | Serializes 'PubKeyXO' to 32 byte @ByteString@
exportPubKeyXO :: PubKeyXO -> ByteString
exportPubKeyXO :: PubKeyXO -> ByteString
exportPubKeyXO (PubKeyXO ForeignPtr XonlyPubkey64
pkFPtr) = IO ByteString -> ByteString
forall a. IO a -> a
unsafePerformIO (IO ByteString -> ByteString) -> IO ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ do
    Ptr (Bytes 32)
outBuf <- Int -> IO (Ptr (Bytes 32))
forall a. Int -> IO (Ptr a)
mallocBytes Int
32
    Ret
_ret <- ForeignPtr XonlyPubkey64 -> (Ptr XonlyPubkey64 -> IO Ret) -> IO Ret
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr XonlyPubkey64
pkFPtr ((Ptr XonlyPubkey64 -> IO Ret) -> IO Ret)
-> (Ptr XonlyPubkey64 -> IO Ret) -> IO Ret
forall a b. (a -> b) -> a -> b
$ Ctx -> Ptr (Bytes 32) -> Ptr XonlyPubkey64 -> IO Ret
Prim.xonlyPubkeySerialize Ctx
ctx Ptr (Bytes 32)
outBuf
    (Ptr (Bytes 32), CSize) -> IO ByteString
forall a. (Ptr a, CSize) -> IO ByteString
unsafePackByteString (Ptr (Bytes 32)
outBuf, CSize
32)


-- | Parses 'Signature' from DER (71 | 72 | 73 bytes) or Compact (64 bytes) representations.
importSignature :: ByteString -> Maybe Signature
importSignature :: ByteString -> Maybe Signature
importSignature ByteString
bs = IO (Maybe Signature) -> Maybe Signature
forall a. IO a -> a
unsafePerformIO (IO (Maybe Signature) -> Maybe Signature)
-> IO (Maybe Signature) -> Maybe Signature
forall a b. (a -> b) -> a -> b
$
    ByteString
-> ((Ptr (Bytes 64), CSize) -> IO (Maybe Signature))
-> IO (Maybe Signature)
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
bs (((Ptr (Bytes 64), CSize) -> IO (Maybe Signature))
 -> IO (Maybe Signature))
-> ((Ptr (Bytes 64), CSize) -> IO (Maybe Signature))
-> IO (Maybe Signature)
forall a b. (a -> b) -> a -> b
$ \(Ptr (Bytes 64)
inBuf, CSize
len) -> do
        Ptr Sig64
outBuf <- Int -> IO (Ptr Sig64)
forall a. Int -> IO (Ptr a)
mallocBytes Int
64
        Ret
ret <-
            if
                    -- compact
                    | CSize
len CSize -> CSize -> Bool
forall a. Eq a => a -> a -> Bool
== CSize
64 -> Ctx -> Ptr Sig64 -> Ptr (Bytes 64) -> IO Ret
Prim.ecdsaSignatureParseCompact Ctx
ctx Ptr Sig64
outBuf Ptr (Bytes 64)
inBuf
                    -- der
                    | CSize
len CSize -> CSize -> Bool
forall a. Ord a => a -> a -> Bool
>= CSize
71 Bool -> Bool -> Bool
&& CSize
len CSize -> CSize -> Bool
forall a. Ord a => a -> a -> Bool
<= CSize
73 -> Ctx -> Ptr Sig64 -> Ptr (Bytes 64) -> CSize -> IO Ret
forall (n :: Nat).
Ctx -> Ptr Sig64 -> Ptr (Bytes n) -> CSize -> IO Ret
Prim.ecdsaSignatureParseDer Ctx
ctx Ptr Sig64
outBuf Ptr (Bytes 64)
inBuf CSize
len
                    -- invalid
                    | Bool
otherwise -> Ret -> IO Ret
forall (f :: * -> *) a. Applicative f => a -> f a
pure Ret
0
        if Ret -> Bool
isSuccess Ret
ret
            then Signature -> Maybe Signature
forall a. a -> Maybe a
Just (Signature -> Maybe Signature)
-> (ForeignPtr Sig64 -> Signature)
-> ForeignPtr Sig64
-> Maybe Signature
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ForeignPtr Sig64 -> Signature
Signature (ForeignPtr Sig64 -> Maybe Signature)
-> IO (ForeignPtr Sig64) -> IO (Maybe Signature)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FinalizerPtr Sig64 -> Ptr Sig64 -> IO (ForeignPtr Sig64)
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr FinalizerPtr Sig64
forall a. FinalizerPtr a
finalizerFree (Ptr Sig64 -> Ptr Sig64
forall a b. Ptr a -> Ptr b
castPtr Ptr Sig64
outBuf)
            else Ptr Sig64 -> IO ()
forall a. Ptr a -> IO ()
free Ptr Sig64
outBuf IO () -> Maybe Signature -> IO (Maybe Signature)
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Maybe Signature
forall a. Maybe a
Nothing


-- | Serializes 'Signature' to Compact (64 byte) representation
exportSignatureCompact :: Signature -> ByteString
exportSignatureCompact :: Signature -> ByteString
exportSignatureCompact (Signature ForeignPtr Sig64
fptr) = IO ByteString -> ByteString
forall a. IO a -> a
unsafePerformIO (IO ByteString -> ByteString) -> IO ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ do
    Ptr (Bytes 64)
outBuf <- Int -> IO (Ptr (Bytes 64))
forall a. Int -> IO (Ptr a)
mallocBytes Int
64
    -- always succeeds
    Ret
_ret <- ForeignPtr Sig64 -> (Ptr Sig64 -> IO Ret) -> IO Ret
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Sig64
fptr ((Ptr Sig64 -> IO Ret) -> IO Ret)
-> (Ptr Sig64 -> IO Ret) -> IO Ret
forall a b. (a -> b) -> a -> b
$ Ctx -> Ptr (Bytes 64) -> Ptr Sig64 -> IO Ret
Prim.ecdsaSignatureSerializeCompact Ctx
ctx Ptr (Bytes 64)
outBuf
    (Ptr (Bytes 64), CSize) -> IO ByteString
forall a. (Ptr a, CSize) -> IO ByteString
unsafePackByteString (Ptr (Bytes 64)
outBuf, CSize
64)


-- | Serializes 'Signature' to DER (71 | 72 bytes) representation
exportSignatureDer :: Signature -> ByteString
exportSignatureDer :: Signature -> ByteString
exportSignatureDer (Signature ForeignPtr Sig64
fptr) = IO ByteString -> ByteString
forall a. IO a -> a
unsafePerformIO (IO ByteString -> ByteString) -> IO ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ do
    -- as of Q4'2015 73 byte sigs became nonstandard so we will never create one that big
    Ptr (Bytes Any)
outBuf <- Int -> IO (Ptr (Bytes Any))
forall a. Int -> IO (Ptr a)
mallocBytes Int
72
    (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
written -> do
        -- always succeeds
        Ret
_ret <- ForeignPtr Sig64 -> (Ptr Sig64 -> IO Ret) -> IO Ret
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Sig64
fptr ((Ptr Sig64 -> IO Ret) -> IO Ret)
-> (Ptr Sig64 -> IO Ret) -> IO Ret
forall a b. (a -> b) -> a -> b
$ Ctx -> Ptr (Bytes Any) -> Ptr CSize -> Ptr Sig64 -> IO Ret
forall (n :: Nat).
Ctx -> Ptr (Bytes n) -> Ptr CSize -> Ptr Sig64 -> IO Ret
Prim.ecdsaSignatureSerializeDer Ctx
ctx Ptr (Bytes Any)
outBuf Ptr CSize
written
        CSize
len <- Ptr CSize -> IO CSize
forall a. Storable a => Ptr a -> IO a
peek Ptr CSize
written
        (Ptr (Bytes Any), CSize) -> IO ByteString
forall a. (Ptr a, CSize) -> IO ByteString
unsafePackByteString (Ptr (Bytes Any)
outBuf, CSize
len)


-- | Parses 'RecoverableSignature' from Compact (65 byte) representation
importRecoverableSignature :: ByteString -> Maybe RecoverableSignature
importRecoverableSignature :: ByteString -> Maybe RecoverableSignature
importRecoverableSignature ByteString
bs
    | ByteString -> Int
BS.length ByteString
bs Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
65 = Maybe RecoverableSignature
forall a. Maybe a
Nothing
    | Bool
otherwise = IO (Maybe RecoverableSignature) -> Maybe RecoverableSignature
forall a. IO a -> a
unsafePerformIO (IO (Maybe RecoverableSignature) -> Maybe RecoverableSignature)
-> (ContT
      (Maybe RecoverableSignature) IO (Maybe RecoverableSignature)
    -> IO (Maybe RecoverableSignature))
-> ContT
     (Maybe RecoverableSignature) IO (Maybe RecoverableSignature)
-> Maybe RecoverableSignature
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ContT (Maybe RecoverableSignature) IO (Maybe RecoverableSignature)
-> IO (Maybe RecoverableSignature)
forall (m :: * -> *) r. Monad m => ContT r m r -> m r
evalContT (ContT (Maybe RecoverableSignature) IO (Maybe RecoverableSignature)
 -> Maybe RecoverableSignature)
-> ContT
     (Maybe RecoverableSignature) IO (Maybe RecoverableSignature)
-> Maybe RecoverableSignature
forall a b. (a -> b) -> a -> b
$ do
        Ptr RecSig65
outBuf <- IO (Ptr RecSig65)
-> ContT (Maybe RecoverableSignature) IO (Ptr RecSig65)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Int -> IO (Ptr RecSig65)
forall a. Int -> IO (Ptr a)
mallocBytes Int
65)
        (Ptr (Bytes 64)
ptr, CSize
len) <- (((Ptr (Bytes 64), CSize) -> IO (Maybe RecoverableSignature))
 -> IO (Maybe RecoverableSignature))
-> ContT (Maybe RecoverableSignature) IO (Ptr (Bytes 64), CSize)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (ByteString
-> ((Ptr (Bytes 64), CSize) -> IO (Maybe RecoverableSignature))
-> IO (Maybe RecoverableSignature)
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
bs)
        Word8
recId <- IO Word8 -> ContT (Maybe RecoverableSignature) IO Word8
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (forall a b. Storable a => Ptr b -> Int -> IO a
peekByteOff @Word8 Ptr (Bytes 64)
ptr Int
64)
        let recIdCInt :: Ret
recIdCInt = Word8 -> Ret
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
recId
        Ret
ret <- IO Ret -> ContT (Maybe RecoverableSignature) IO Ret
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Ctx -> Ptr RecSig65 -> Ptr (Bytes 64) -> Ret -> IO Ret
Prim.ecdsaRecoverableSignatureParseCompact Ctx
ctx Ptr RecSig65
outBuf Ptr (Bytes 64)
ptr Ret
recIdCInt)
        IO (Maybe RecoverableSignature)
-> ContT
     (Maybe RecoverableSignature) IO (Maybe RecoverableSignature)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (IO (Maybe RecoverableSignature)
 -> ContT
      (Maybe RecoverableSignature) IO (Maybe RecoverableSignature))
-> IO (Maybe RecoverableSignature)
-> ContT
     (Maybe RecoverableSignature) IO (Maybe RecoverableSignature)
forall a b. (a -> b) -> a -> b
$
            if Ret -> Bool
isSuccess Ret
ret
                then RecoverableSignature -> Maybe RecoverableSignature
forall a. a -> Maybe a
Just (RecoverableSignature -> Maybe RecoverableSignature)
-> (ForeignPtr RecSig65 -> RecoverableSignature)
-> ForeignPtr RecSig65
-> Maybe RecoverableSignature
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ForeignPtr RecSig65 -> RecoverableSignature
RecoverableSignature (ForeignPtr RecSig65 -> Maybe RecoverableSignature)
-> IO (ForeignPtr RecSig65) -> IO (Maybe RecoverableSignature)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FinalizerPtr RecSig65 -> Ptr RecSig65 -> IO (ForeignPtr RecSig65)
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr FinalizerPtr RecSig65
forall a. FinalizerPtr a
finalizerFree Ptr RecSig65
outBuf
                else Ptr RecSig65 -> IO ()
forall a. Ptr a -> IO ()
free Ptr RecSig65
outBuf IO ()
-> Maybe RecoverableSignature -> IO (Maybe RecoverableSignature)
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Maybe RecoverableSignature
forall a. Maybe a
Nothing


-- | Serializes 'RecoverableSignature' to Compact (65 byte) representation
exportRecoverableSignature :: RecoverableSignature -> ByteString
exportRecoverableSignature :: RecoverableSignature -> ByteString
exportRecoverableSignature RecoverableSignature{ForeignPtr RecSig65
recoverableSignatureFPtr :: ForeignPtr RecSig65
recoverableSignatureFPtr :: RecoverableSignature -> ForeignPtr RecSig65
..} = IO ByteString -> ByteString
forall a. IO a -> a
unsafePerformIO (IO ByteString -> ByteString)
-> (ContT ByteString IO ByteString -> IO ByteString)
-> ContT ByteString IO ByteString
-> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ContT ByteString IO ByteString -> IO ByteString
forall (m :: * -> *) r. Monad m => ContT r m r -> m r
evalContT (ContT ByteString IO ByteString -> ByteString)
-> ContT ByteString IO ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ do
    Ptr RecSig65
recSigPtr <- ((Ptr RecSig65 -> IO ByteString) -> IO ByteString)
-> ContT ByteString IO (Ptr RecSig65)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (ForeignPtr RecSig65
-> (Ptr RecSig65 -> IO ByteString) -> IO ByteString
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr RecSig65
recoverableSignatureFPtr)
    IO ByteString -> ContT ByteString IO ByteString
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (IO ByteString -> ContT ByteString IO ByteString)
-> IO ByteString -> ContT ByteString IO ByteString
forall a b. (a -> b) -> a -> b
$ do
        Ptr (Bytes 64)
outBuf <- Int -> IO (Ptr (Bytes 64))
forall a. Int -> IO (Ptr a)
mallocBytes Int
65
        Ptr Ret
recIdPtr <- IO (Ptr Ret)
forall a. Storable a => IO (Ptr a)
malloc
        Ret
_ret <- Ctx -> Ptr (Bytes 64) -> Ptr Ret -> Ptr RecSig65 -> IO Ret
Prim.ecdsaRecoverableSignatureSerializeCompact Ctx
ctx Ptr (Bytes 64)
outBuf Ptr Ret
recIdPtr Ptr RecSig65
recSigPtr
        Ret
recId <- Ptr Ret -> IO Ret
forall a. Storable a => Ptr a -> IO a
peek Ptr Ret
recIdPtr
        (Ptr (Bytes 64), CSize) -> IO ByteString
forall a. (Ptr a, CSize) -> IO ByteString
unsafePackByteString (Ptr (Bytes 64)
outBuf, CSize
65)


-- | Parses 'Tweak' from 32 byte @ByteString@. If the @ByteString@ is an invalid 'SecKey' then this will yield @Nothing@
importTweak :: ByteString -> Maybe Tweak
importTweak :: ByteString -> Maybe Tweak
importTweak = (SecKey -> Tweak) -> Maybe SecKey -> Maybe Tweak
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (ForeignPtr Tweak32 -> Tweak
Tweak (ForeignPtr Tweak32 -> Tweak)
-> (SecKey -> ForeignPtr Tweak32) -> SecKey -> Tweak
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ForeignPtr Seckey32 -> ForeignPtr Tweak32
forall a b. ForeignPtr a -> ForeignPtr b
castForeignPtr (ForeignPtr Seckey32 -> ForeignPtr Tweak32)
-> (SecKey -> ForeignPtr Seckey32) -> SecKey -> ForeignPtr Tweak32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SecKey -> ForeignPtr Seckey32
secKeyFPtr) (Maybe SecKey -> Maybe Tweak)
-> (ByteString -> Maybe SecKey) -> ByteString -> Maybe Tweak
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Maybe SecKey
importSecKey


-- | Verify message signature. 'True' means that the signature is correct.
ecdsaVerify :: ByteString -> PubKeyXY -> Signature -> Bool
ecdsaVerify :: ByteString -> PubKeyXY -> Signature -> Bool
ecdsaVerify ByteString
msgHash (PubKeyXY ForeignPtr Pubkey64
pkFPtr) (Signature ForeignPtr Sig64
sigFPtr) = IO Bool -> Bool
forall a. IO a -> a
unsafePerformIO (IO Bool -> Bool) -> IO Bool -> Bool
forall a b. (a -> b) -> a -> b
$
    ContT Bool IO Bool -> IO Bool
forall (m :: * -> *) r. Monad m => ContT r m r -> m r
evalContT (ContT Bool IO Bool -> IO Bool) -> ContT Bool IO Bool -> IO Bool
forall a b. (a -> b) -> a -> b
$ do
        Ptr Pubkey64
pkPtr <- ((Ptr Pubkey64 -> IO Bool) -> IO Bool)
-> ContT Bool IO (Ptr Pubkey64)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (ForeignPtr Pubkey64 -> (Ptr Pubkey64 -> IO Bool) -> IO Bool
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Pubkey64
pkFPtr)
        Ptr Sig64
sigPtr <- ((Ptr Sig64 -> IO Bool) -> IO Bool) -> ContT Bool IO (Ptr Sig64)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (ForeignPtr Sig64 -> (Ptr Sig64 -> IO Bool) -> IO Bool
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Sig64
sigFPtr)
        (Ptr Msg32
msgHashPtr, CSize
n) <- (((Ptr Msg32, CSize) -> IO Bool) -> IO Bool)
-> ContT Bool IO (Ptr Msg32, CSize)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (ByteString -> ((Ptr Msg32, CSize) -> IO Bool) -> IO Bool
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
msgHash)
        IO Bool -> ContT Bool IO Bool
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (IO Bool -> ContT Bool IO Bool) -> IO Bool -> ContT Bool IO Bool
forall a b. (a -> b) -> a -> b
$ Ret -> Bool
isSuccess (Ret -> Bool) -> IO Ret -> IO Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ctx -> Ptr Sig64 -> Ptr Msg32 -> Ptr Pubkey64 -> IO Ret
Prim.ecdsaVerify Ctx
ctx Ptr Sig64
sigPtr Ptr Msg32
msgHashPtr Ptr Pubkey64
pkPtr


-- | Signs @ByteString@ with 'SecKey' only if @ByteString@ is 32 bytes.
ecdsaSign :: SecKey -> ByteString -> Maybe Signature
ecdsaSign :: SecKey -> ByteString -> Maybe Signature
ecdsaSign (SecKey ForeignPtr Seckey32
skFPtr) ByteString
msgHash
    | ByteString -> Int
BS.length ByteString
msgHash Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
32 = Maybe Signature
forall a. Maybe a
Nothing
    | Bool
otherwise = IO (Maybe Signature) -> Maybe Signature
forall a. IO a -> a
unsafePerformIO (IO (Maybe Signature) -> Maybe Signature)
-> IO (Maybe Signature) -> Maybe Signature
forall a b. (a -> b) -> a -> b
$
        ContT (Maybe Signature) IO (Maybe Signature)
-> IO (Maybe Signature)
forall (m :: * -> *) r. Monad m => ContT r m r -> m r
evalContT (ContT (Maybe Signature) IO (Maybe Signature)
 -> IO (Maybe Signature))
-> ContT (Maybe Signature) IO (Maybe Signature)
-> IO (Maybe Signature)
forall a b. (a -> b) -> a -> b
$ do
            Ptr Seckey32
skPtr <- ((Ptr Seckey32 -> IO (Maybe Signature)) -> IO (Maybe Signature))
-> ContT (Maybe Signature) IO (Ptr Seckey32)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (ForeignPtr Seckey32
-> (Ptr Seckey32 -> IO (Maybe Signature)) -> IO (Maybe Signature)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Seckey32
skFPtr)
            (Ptr Msg32
msgHashPtr, CSize
_) <- (((Ptr Msg32, CSize) -> IO (Maybe Signature))
 -> IO (Maybe Signature))
-> ContT (Maybe Signature) IO (Ptr Msg32, CSize)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (ByteString
-> ((Ptr Msg32, CSize) -> IO (Maybe Signature))
-> IO (Maybe Signature)
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
msgHash)
            Ptr Sig64
sigBuf <- IO (Ptr Sig64) -> ContT (Maybe Signature) IO (Ptr Sig64)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (IO (Ptr Sig64) -> ContT (Maybe Signature) IO (Ptr Sig64))
-> IO (Ptr Sig64) -> ContT (Maybe Signature) IO (Ptr Sig64)
forall a b. (a -> b) -> a -> b
$ Int -> IO (Ptr Sig64)
forall a. Int -> IO (Ptr a)
mallocBytes Int
64
            Ret
ret <- IO Ret -> ContT (Maybe Signature) IO Ret
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (IO Ret -> ContT (Maybe Signature) IO Ret)
-> IO Ret -> ContT (Maybe Signature) IO Ret
forall a b. (a -> b) -> a -> b
$ Ctx
-> Ptr Sig64
-> Ptr Msg32
-> Ptr Seckey32
-> FunPtr (NonceFun Any)
-> Ptr Any
-> IO Ret
forall a.
Ctx
-> Ptr Sig64
-> Ptr Msg32
-> Ptr Seckey32
-> FunPtr (NonceFun a)
-> Ptr a
-> IO Ret
Prim.ecdsaSign Ctx
ctx Ptr Sig64
sigBuf Ptr Msg32
msgHashPtr Ptr Seckey32
skPtr FunPtr (NonceFun Any)
forall a. FunPtr (NonceFun a)
Prim.nonceFunctionDefault Ptr Any
forall a. Ptr a
nullPtr
            IO (Maybe Signature)
-> ContT (Maybe Signature) IO (Maybe Signature)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (IO (Maybe Signature)
 -> ContT (Maybe Signature) IO (Maybe Signature))
-> IO (Maybe Signature)
-> ContT (Maybe Signature) IO (Maybe Signature)
forall a b. (a -> b) -> a -> b
$
                if Ret -> Bool
isSuccess Ret
ret
                    then Signature -> Maybe Signature
forall a. a -> Maybe a
Just (Signature -> Maybe Signature)
-> (ForeignPtr Sig64 -> Signature)
-> ForeignPtr Sig64
-> Maybe Signature
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ForeignPtr Sig64 -> Signature
Signature (ForeignPtr Sig64 -> Maybe Signature)
-> IO (ForeignPtr Sig64) -> IO (Maybe Signature)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FinalizerPtr Sig64 -> Ptr Sig64 -> IO (ForeignPtr Sig64)
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr FinalizerPtr Sig64
forall a. FinalizerPtr a
finalizerFree Ptr Sig64
sigBuf
                    else Ptr Sig64 -> IO ()
forall a. Ptr a -> IO ()
free Ptr Sig64
sigBuf IO () -> Maybe Signature -> IO (Maybe Signature)
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Maybe Signature
forall a. Maybe a
Nothing


-- | Signs @ByteString@ with 'SecKey' only if @ByteString@ is 32 bytes. Retains ability to compute 'PubKeyXY' from the
-- 'RecoverableSignature' and the original message (@ByteString@)
ecdsaSignRecoverable :: SecKey -> ByteString -> Maybe RecoverableSignature
ecdsaSignRecoverable :: SecKey -> ByteString -> Maybe RecoverableSignature
ecdsaSignRecoverable SecKey{ForeignPtr Seckey32
secKeyFPtr :: ForeignPtr Seckey32
secKeyFPtr :: SecKey -> ForeignPtr Seckey32
..} ByteString
bs
    | ByteString -> Int
BS.length ByteString
bs Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
32 = Maybe RecoverableSignature
forall a. Maybe a
Nothing
    | Bool
otherwise = IO (Maybe RecoverableSignature) -> Maybe RecoverableSignature
forall a. IO a -> a
unsafePerformIO (IO (Maybe RecoverableSignature) -> Maybe RecoverableSignature)
-> (ContT
      (Maybe RecoverableSignature) IO (Maybe RecoverableSignature)
    -> IO (Maybe RecoverableSignature))
-> ContT
     (Maybe RecoverableSignature) IO (Maybe RecoverableSignature)
-> Maybe RecoverableSignature
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ContT (Maybe RecoverableSignature) IO (Maybe RecoverableSignature)
-> IO (Maybe RecoverableSignature)
forall (m :: * -> *) r. Monad m => ContT r m r -> m r
evalContT (ContT (Maybe RecoverableSignature) IO (Maybe RecoverableSignature)
 -> Maybe RecoverableSignature)
-> ContT
     (Maybe RecoverableSignature) IO (Maybe RecoverableSignature)
-> Maybe RecoverableSignature
forall a b. (a -> b) -> a -> b
$ do
        (Ptr Msg32
msgHashPtr, CSize
_) <- (((Ptr Msg32, CSize) -> IO (Maybe RecoverableSignature))
 -> IO (Maybe RecoverableSignature))
-> ContT (Maybe RecoverableSignature) IO (Ptr Msg32, CSize)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (ByteString
-> ((Ptr Msg32, CSize) -> IO (Maybe RecoverableSignature))
-> IO (Maybe RecoverableSignature)
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
bs)
        Ptr Seckey32
secKeyPtr <- ((Ptr Seckey32 -> IO (Maybe RecoverableSignature))
 -> IO (Maybe RecoverableSignature))
-> ContT (Maybe RecoverableSignature) IO (Ptr Seckey32)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (ForeignPtr Seckey32
-> (Ptr Seckey32 -> IO (Maybe RecoverableSignature))
-> IO (Maybe RecoverableSignature)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Seckey32
secKeyFPtr)
        IO (Maybe RecoverableSignature)
-> ContT
     (Maybe RecoverableSignature) IO (Maybe RecoverableSignature)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (IO (Maybe RecoverableSignature)
 -> ContT
      (Maybe RecoverableSignature) IO (Maybe RecoverableSignature))
-> IO (Maybe RecoverableSignature)
-> ContT
     (Maybe RecoverableSignature) IO (Maybe RecoverableSignature)
forall a b. (a -> b) -> a -> b
$ do
            Ptr RecSig65
recSigBuf <- Int -> IO (Ptr RecSig65)
forall a. Int -> IO (Ptr a)
mallocBytes Int
65
            Ret
ret <- Ctx
-> Ptr RecSig65
-> Ptr Msg32
-> Ptr Seckey32
-> FunPtr (NonceFun Any)
-> Ptr Any
-> IO Ret
forall a.
Ctx
-> Ptr RecSig65
-> Ptr Msg32
-> Ptr Seckey32
-> FunPtr (NonceFun a)
-> Ptr a
-> IO Ret
Prim.ecdsaSignRecoverable Ctx
ctx Ptr RecSig65
recSigBuf Ptr Msg32
msgHashPtr Ptr Seckey32
secKeyPtr FunPtr (NonceFun Any)
forall a. FunPtr (NonceFun a)
Prim.nonceFunctionDefault Ptr Any
forall a. Ptr a
nullPtr
            if Ret -> Bool
isSuccess Ret
ret
                then RecoverableSignature -> Maybe RecoverableSignature
forall a. a -> Maybe a
Just (RecoverableSignature -> Maybe RecoverableSignature)
-> (ForeignPtr RecSig65 -> RecoverableSignature)
-> ForeignPtr RecSig65
-> Maybe RecoverableSignature
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ForeignPtr RecSig65 -> RecoverableSignature
RecoverableSignature (ForeignPtr RecSig65 -> Maybe RecoverableSignature)
-> IO (ForeignPtr RecSig65) -> IO (Maybe RecoverableSignature)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FinalizerPtr RecSig65 -> Ptr RecSig65 -> IO (ForeignPtr RecSig65)
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr FinalizerPtr RecSig65
forall a. FinalizerPtr a
finalizerFree Ptr RecSig65
recSigBuf
                else Ptr RecSig65 -> IO ()
forall a. Ptr a -> IO ()
free Ptr RecSig65
recSigBuf IO ()
-> Maybe RecoverableSignature -> IO (Maybe RecoverableSignature)
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Maybe RecoverableSignature
forall a. Maybe a
Nothing


-- | Computes 'PubKeyXY' from 'RecoverableSignature' and the original message that was signed (must be 32 bytes).
ecdsaRecover :: RecoverableSignature -> ByteString -> Maybe PubKeyXY
ecdsaRecover :: RecoverableSignature -> ByteString -> Maybe PubKeyXY
ecdsaRecover RecoverableSignature{ForeignPtr RecSig65
recoverableSignatureFPtr :: ForeignPtr RecSig65
recoverableSignatureFPtr :: RecoverableSignature -> ForeignPtr RecSig65
..} ByteString
msgHash
    | ByteString -> Int
BS.length ByteString
msgHash Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
32 = Maybe PubKeyXY
forall a. Maybe a
Nothing
    | Bool
otherwise = IO (Maybe PubKeyXY) -> Maybe PubKeyXY
forall a. IO a -> a
unsafePerformIO (IO (Maybe PubKeyXY) -> Maybe PubKeyXY)
-> (ContT (Maybe PubKeyXY) IO (Maybe PubKeyXY)
    -> IO (Maybe PubKeyXY))
-> ContT (Maybe PubKeyXY) IO (Maybe PubKeyXY)
-> Maybe PubKeyXY
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ContT (Maybe PubKeyXY) IO (Maybe PubKeyXY) -> IO (Maybe PubKeyXY)
forall (m :: * -> *) r. Monad m => ContT r m r -> m r
evalContT (ContT (Maybe PubKeyXY) IO (Maybe PubKeyXY) -> Maybe PubKeyXY)
-> ContT (Maybe PubKeyXY) IO (Maybe PubKeyXY) -> Maybe PubKeyXY
forall a b. (a -> b) -> a -> b
$ do
        Ptr RecSig65
recSigPtr <- ((Ptr RecSig65 -> IO (Maybe PubKeyXY)) -> IO (Maybe PubKeyXY))
-> ContT (Maybe PubKeyXY) IO (Ptr RecSig65)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (ForeignPtr RecSig65
-> (Ptr RecSig65 -> IO (Maybe PubKeyXY)) -> IO (Maybe PubKeyXY)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr RecSig65
recoverableSignatureFPtr)
        (Ptr Msg32
msgHashPtr, CSize
_) <- (((Ptr Msg32, CSize) -> IO (Maybe PubKeyXY))
 -> IO (Maybe PubKeyXY))
-> ContT (Maybe PubKeyXY) IO (Ptr Msg32, CSize)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (ByteString
-> ((Ptr Msg32, CSize) -> IO (Maybe PubKeyXY))
-> IO (Maybe PubKeyXY)
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
msgHash)
        IO (Maybe PubKeyXY) -> ContT (Maybe PubKeyXY) IO (Maybe PubKeyXY)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (IO (Maybe PubKeyXY) -> ContT (Maybe PubKeyXY) IO (Maybe PubKeyXY))
-> IO (Maybe PubKeyXY)
-> ContT (Maybe PubKeyXY) IO (Maybe PubKeyXY)
forall a b. (a -> b) -> a -> b
$ do
            Ptr Pubkey64
pubKeyBuf <- Int -> IO (Ptr Pubkey64)
forall a. Int -> IO (Ptr a)
mallocBytes Int
64
            Ret
ret <- Ctx -> Ptr Pubkey64 -> Ptr RecSig65 -> Ptr Msg32 -> IO Ret
Prim.ecdsaRecover Ctx
ctx Ptr Pubkey64
pubKeyBuf Ptr RecSig65
recSigPtr Ptr Msg32
msgHashPtr
            if Ret -> Bool
isSuccess Ret
ret
                then PubKeyXY -> Maybe PubKeyXY
forall a. a -> Maybe a
Just (PubKeyXY -> Maybe PubKeyXY)
-> (ForeignPtr Pubkey64 -> PubKeyXY)
-> ForeignPtr Pubkey64
-> Maybe PubKeyXY
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ForeignPtr Pubkey64 -> PubKeyXY
PubKeyXY (ForeignPtr Pubkey64 -> Maybe PubKeyXY)
-> IO (ForeignPtr Pubkey64) -> IO (Maybe PubKeyXY)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FinalizerPtr Pubkey64 -> Ptr Pubkey64 -> IO (ForeignPtr Pubkey64)
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr FinalizerPtr Pubkey64
forall a. FinalizerPtr a
finalizerFree Ptr Pubkey64
pubKeyBuf
                else Ptr Pubkey64 -> IO ()
forall a. Ptr a -> IO ()
free Ptr Pubkey64
pubKeyBuf IO () -> Maybe PubKeyXY -> IO (Maybe PubKeyXY)
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Maybe PubKeyXY
forall a. Maybe a
Nothing


-- | Forgets the recovery id of a signature
recSigToSig :: RecoverableSignature -> Signature
recSigToSig :: RecoverableSignature -> Signature
recSigToSig RecoverableSignature{ForeignPtr RecSig65
recoverableSignatureFPtr :: ForeignPtr RecSig65
recoverableSignatureFPtr :: RecoverableSignature -> ForeignPtr RecSig65
..} = IO Signature -> Signature
forall a. IO a -> a
unsafePerformIO (IO Signature -> Signature)
-> (ContT Signature IO Signature -> IO Signature)
-> ContT Signature IO Signature
-> Signature
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ContT Signature IO Signature -> IO Signature
forall (m :: * -> *) r. Monad m => ContT r m r -> m r
evalContT (ContT Signature IO Signature -> Signature)
-> ContT Signature IO Signature -> Signature
forall a b. (a -> b) -> a -> b
$ do
    Ptr RecSig65
recSigPtr <- ((Ptr RecSig65 -> IO Signature) -> IO Signature)
-> ContT Signature IO (Ptr RecSig65)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (ForeignPtr RecSig65
-> (Ptr RecSig65 -> IO Signature) -> IO Signature
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr RecSig65
recoverableSignatureFPtr)
    IO Signature -> ContT Signature IO Signature
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (IO Signature -> ContT Signature IO Signature)
-> IO Signature -> ContT Signature IO Signature
forall a b. (a -> b) -> a -> b
$ do
        Ptr Sig64
sigBuf <- Int -> IO (Ptr Sig64)
forall a. Int -> IO (Ptr a)
mallocBytes Int
64
        Ret
_ret <- Ctx -> Ptr Sig64 -> Ptr RecSig65 -> IO Ret
Prim.ecdsaRecoverableSignatureConvert Ctx
ctx Ptr Sig64
sigBuf Ptr RecSig65
recSigPtr
        ForeignPtr Sig64 -> Signature
Signature (ForeignPtr Sig64 -> Signature)
-> IO (ForeignPtr Sig64) -> IO Signature
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FinalizerPtr Sig64 -> Ptr Sig64 -> IO (ForeignPtr Sig64)
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr FinalizerPtr Sig64
forall a. FinalizerPtr a
finalizerFree Ptr Sig64
sigBuf


-- | Use 'SecKey' to compute the corresponding 'PubKeyXY'
derivePubKey :: SecKey -> PubKeyXY
derivePubKey :: SecKey -> PubKeyXY
derivePubKey (SecKey ForeignPtr Seckey32
skFPtr) = IO PubKeyXY -> PubKeyXY
forall a. IO a -> a
unsafePerformIO (IO PubKeyXY -> PubKeyXY) -> IO PubKeyXY -> PubKeyXY
forall a b. (a -> b) -> a -> b
$ do
    Ptr Pubkey64
outBuf <- Int -> IO (Ptr Pubkey64)
forall a. Int -> IO (Ptr a)
mallocBytes Int
64
    Ret
ret <- ForeignPtr Seckey32 -> (Ptr Seckey32 -> IO Ret) -> IO Ret
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Seckey32
skFPtr ((Ptr Seckey32 -> IO Ret) -> IO Ret)
-> (Ptr Seckey32 -> IO Ret) -> IO Ret
forall a b. (a -> b) -> a -> b
$ Ctx -> Ptr Pubkey64 -> Ptr Seckey32 -> IO Ret
Prim.ecPubkeyCreate Ctx
ctx Ptr Pubkey64
outBuf
    Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Ret -> Bool
isSuccess Ret
ret) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
        Ptr Pubkey64 -> IO ()
forall a. Ptr a -> IO ()
free Ptr Pubkey64
outBuf
        [Char] -> IO ()
forall a. HasCallStack => [Char] -> a
error [Char]
"Bug: Invalid SecKey Constructed"
    ForeignPtr Pubkey64 -> PubKeyXY
PubKeyXY (ForeignPtr Pubkey64 -> PubKeyXY)
-> IO (ForeignPtr Pubkey64) -> IO PubKeyXY
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FinalizerPtr Pubkey64 -> Ptr Pubkey64 -> IO (ForeignPtr Pubkey64)
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr FinalizerPtr Pubkey64
forall a. FinalizerPtr a
finalizerFree Ptr Pubkey64
outBuf


-- | Compute a shared secret using ECDH and SHA256. This algorithm uses your own 'SecKey', your counterparty's 'PubKeyXY'
-- and results in a 32 byte SHA256 Digest.
ecdh :: SecKey -> PubKeyXY -> Digest SHA256
ecdh :: SecKey -> PubKeyXY -> Digest SHA256
ecdh SecKey{ForeignPtr Seckey32
secKeyFPtr :: ForeignPtr Seckey32
secKeyFPtr :: SecKey -> ForeignPtr Seckey32
..} PubKeyXY{ForeignPtr Pubkey64
pubKeyXYFPtr :: ForeignPtr Pubkey64
pubKeyXYFPtr :: PubKeyXY -> ForeignPtr Pubkey64
..} = IO (Digest SHA256) -> Digest SHA256
forall a. IO a -> a
unsafePerformIO (IO (Digest SHA256) -> Digest SHA256)
-> (ContT (Digest SHA256) IO (Digest SHA256) -> IO (Digest SHA256))
-> ContT (Digest SHA256) IO (Digest SHA256)
-> Digest SHA256
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ContT (Digest SHA256) IO (Digest SHA256) -> IO (Digest SHA256)
forall (m :: * -> *) r. Monad m => ContT r m r -> m r
evalContT (ContT (Digest SHA256) IO (Digest SHA256) -> Digest SHA256)
-> ContT (Digest SHA256) IO (Digest SHA256) -> Digest SHA256
forall a b. (a -> b) -> a -> b
$ do
    Ptr (Bytes Any)
outBuf <- IO (Ptr (Bytes Any)) -> ContT (Digest SHA256) IO (Ptr (Bytes Any))
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Int -> IO (Ptr (Bytes Any))
forall a. Int -> IO (Ptr a)
mallocBytes Int
32)
    Ptr Seckey32
sk <- ((Ptr Seckey32 -> IO (Digest SHA256)) -> IO (Digest SHA256))
-> ContT (Digest SHA256) IO (Ptr Seckey32)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (ForeignPtr Seckey32
-> (Ptr Seckey32 -> IO (Digest SHA256)) -> IO (Digest SHA256)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Seckey32
secKeyFPtr)
    Ptr Pubkey64
pk <- ((Ptr Pubkey64 -> IO (Digest SHA256)) -> IO (Digest SHA256))
-> ContT (Digest SHA256) IO (Ptr Pubkey64)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (ForeignPtr Pubkey64
-> (Ptr Pubkey64 -> IO (Digest SHA256)) -> IO (Digest SHA256)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Pubkey64
pubKeyXYFPtr)
    Ret
ret <- IO Ret -> ContT (Digest SHA256) IO Ret
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Ctx
-> Ptr (Bytes Any)
-> Ptr Pubkey64
-> Ptr Seckey32
-> FunPtr (EcdhHashFun Any)
-> Ptr Any
-> IO Ret
forall (n :: Nat) a.
Ctx
-> Ptr (Bytes n)
-> Ptr Pubkey64
-> Ptr Seckey32
-> FunPtr (EcdhHashFun a)
-> Ptr a
-> IO Ret
Prim.ecdh Ctx
ctx Ptr (Bytes Any)
outBuf Ptr Pubkey64
pk Ptr Seckey32
sk FunPtr (EcdhHashFun Any)
forall a. FunPtr (EcdhHashFun a)
Prim.ecdhHashFunctionSha256 Ptr Any
forall a. Ptr a
nullPtr)
    if Ret -> Bool
isSuccess Ret
ret
        then do
            ByteString
bs <- IO ByteString -> ContT (Digest SHA256) IO ByteString
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (IO ByteString -> ContT (Digest SHA256) IO ByteString)
-> IO ByteString -> ContT (Digest SHA256) IO ByteString
forall a b. (a -> b) -> a -> b
$ (Ptr (Bytes Any), CSize) -> IO ByteString
forall a. (Ptr a, CSize) -> IO ByteString
unsafePackByteString (Ptr (Bytes Any)
outBuf, CSize
32)
            let Just Digest SHA256
digest = ByteString -> Maybe (Digest SHA256)
forall a ba.
(HashAlgorithm a, ByteArrayAccess ba) =>
ba -> Maybe (Digest a)
digestFromByteString ByteString
bs
            Digest SHA256 -> ContT (Digest SHA256) IO (Digest SHA256)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Digest SHA256
digest
        else IO () -> ContT (Digest SHA256) IO ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Ptr (Bytes Any) -> IO ()
forall a. Ptr a -> IO ()
free Ptr (Bytes Any)
outBuf) ContT (Digest SHA256) IO ()
-> ContT (Digest SHA256) IO (Digest SHA256)
-> ContT (Digest SHA256) IO (Digest SHA256)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> [Char] -> ContT (Digest SHA256) IO (Digest SHA256)
forall a. HasCallStack => [Char] -> a
error [Char]
"Bug: Invalid Scalar or Overflow"


-- -- | Add 'Tweak' to 'SecKey'.
ecSecKeyTweakAdd :: SecKey -> Tweak -> Maybe SecKey
ecSecKeyTweakAdd :: SecKey -> Tweak -> Maybe SecKey
ecSecKeyTweakAdd SecKey{ForeignPtr Seckey32
secKeyFPtr :: ForeignPtr Seckey32
secKeyFPtr :: SecKey -> ForeignPtr Seckey32
..} Tweak{ForeignPtr Tweak32
tweakFPtr :: ForeignPtr Tweak32
tweakFPtr :: Tweak -> ForeignPtr Tweak32
..} = IO (Maybe SecKey) -> Maybe SecKey
forall a. IO a -> a
unsafePerformIO (IO (Maybe SecKey) -> Maybe SecKey)
-> (ContT (Maybe SecKey) IO (Maybe SecKey) -> IO (Maybe SecKey))
-> ContT (Maybe SecKey) IO (Maybe SecKey)
-> Maybe SecKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ContT (Maybe SecKey) IO (Maybe SecKey) -> IO (Maybe SecKey)
forall (m :: * -> *) r. Monad m => ContT r m r -> m r
evalContT (ContT (Maybe SecKey) IO (Maybe SecKey) -> Maybe SecKey)
-> ContT (Maybe SecKey) IO (Maybe SecKey) -> Maybe SecKey
forall a b. (a -> b) -> a -> b
$ do
    Ptr Seckey32
skPtr <- ((Ptr Seckey32 -> IO (Maybe SecKey)) -> IO (Maybe SecKey))
-> ContT (Maybe SecKey) IO (Ptr Seckey32)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (ForeignPtr Seckey32
-> (Ptr Seckey32 -> IO (Maybe SecKey)) -> IO (Maybe SecKey)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Seckey32
secKeyFPtr)
    Ptr Seckey32
skOut <- IO (Ptr Seckey32) -> ContT (Maybe SecKey) IO (Ptr Seckey32)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Int -> IO (Ptr Seckey32)
forall a. Int -> IO (Ptr a)
mallocBytes Int
32)
    IO (Ptr ()) -> ContT (Maybe SecKey) IO (Ptr ())
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Ptr Seckey32 -> Ptr Seckey32 -> CSize -> IO (Ptr ())
forall a. Ptr a -> Ptr a -> CSize -> IO (Ptr ())
memcpy Ptr Seckey32
skOut Ptr Seckey32
skPtr CSize
32)
    Ptr Tweak32
twkPtr <- ((Ptr Tweak32 -> IO (Maybe SecKey)) -> IO (Maybe SecKey))
-> ContT (Maybe SecKey) IO (Ptr Tweak32)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (ForeignPtr Tweak32
-> (Ptr Tweak32 -> IO (Maybe SecKey)) -> IO (Maybe SecKey)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Tweak32
tweakFPtr)
    Ret
ret <- IO Ret -> ContT (Maybe SecKey) IO Ret
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Ctx -> Ptr Seckey32 -> Ptr Tweak32 -> IO Ret
Prim.ecSeckeyTweakAdd Ctx
ctx Ptr Seckey32
skOut Ptr Tweak32
twkPtr)
    IO (Maybe SecKey) -> ContT (Maybe SecKey) IO (Maybe SecKey)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (IO (Maybe SecKey) -> ContT (Maybe SecKey) IO (Maybe SecKey))
-> IO (Maybe SecKey) -> ContT (Maybe SecKey) IO (Maybe SecKey)
forall a b. (a -> b) -> a -> b
$
        if Ret -> Bool
isSuccess Ret
ret
            then SecKey -> Maybe SecKey
forall a. a -> Maybe a
Just (SecKey -> Maybe SecKey)
-> (ForeignPtr Seckey32 -> SecKey)
-> ForeignPtr Seckey32
-> Maybe SecKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ForeignPtr Seckey32 -> SecKey
SecKey (ForeignPtr Seckey32 -> Maybe SecKey)
-> IO (ForeignPtr Seckey32) -> IO (Maybe SecKey)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FinalizerPtr Seckey32 -> Ptr Seckey32 -> IO (ForeignPtr Seckey32)
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr FinalizerPtr Seckey32
forall a. FinalizerPtr a
finalizerFree Ptr Seckey32
skOut
            else Ptr Seckey32 -> IO ()
forall a. Ptr a -> IO ()
free Ptr Seckey32
skOut IO () -> Maybe SecKey -> IO (Maybe SecKey)
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Maybe SecKey
forall a. Maybe a
Nothing


-- | Multiply 'SecKey' by 'Tweak'.
ecSecKeyTweakMul :: SecKey -> Tweak -> Maybe SecKey
ecSecKeyTweakMul :: SecKey -> Tweak -> Maybe SecKey
ecSecKeyTweakMul SecKey{ForeignPtr Seckey32
secKeyFPtr :: ForeignPtr Seckey32
secKeyFPtr :: SecKey -> ForeignPtr Seckey32
..} Tweak{ForeignPtr Tweak32
tweakFPtr :: ForeignPtr Tweak32
tweakFPtr :: Tweak -> ForeignPtr Tweak32
..} = IO (Maybe SecKey) -> Maybe SecKey
forall a. IO a -> a
unsafePerformIO (IO (Maybe SecKey) -> Maybe SecKey)
-> (ContT (Maybe SecKey) IO (Maybe SecKey) -> IO (Maybe SecKey))
-> ContT (Maybe SecKey) IO (Maybe SecKey)
-> Maybe SecKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ContT (Maybe SecKey) IO (Maybe SecKey) -> IO (Maybe SecKey)
forall (m :: * -> *) r. Monad m => ContT r m r -> m r
evalContT (ContT (Maybe SecKey) IO (Maybe SecKey) -> Maybe SecKey)
-> ContT (Maybe SecKey) IO (Maybe SecKey) -> Maybe SecKey
forall a b. (a -> b) -> a -> b
$ do
    Ptr Seckey32
skPtr <- ((Ptr Seckey32 -> IO (Maybe SecKey)) -> IO (Maybe SecKey))
-> ContT (Maybe SecKey) IO (Ptr Seckey32)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (ForeignPtr Seckey32
-> (Ptr Seckey32 -> IO (Maybe SecKey)) -> IO (Maybe SecKey)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Seckey32
secKeyFPtr)
    Ptr Seckey32
skOut <- IO (Ptr Seckey32) -> ContT (Maybe SecKey) IO (Ptr Seckey32)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Int -> IO (Ptr Seckey32)
forall a. Int -> IO (Ptr a)
mallocBytes Int
32)
    IO (Ptr ()) -> ContT (Maybe SecKey) IO (Ptr ())
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Ptr Seckey32 -> Ptr Seckey32 -> CSize -> IO (Ptr ())
forall a. Ptr a -> Ptr a -> CSize -> IO (Ptr ())
memcpy Ptr Seckey32
skOut Ptr Seckey32
skPtr CSize
32)
    Ptr Tweak32
twkPtr <- ((Ptr Tweak32 -> IO (Maybe SecKey)) -> IO (Maybe SecKey))
-> ContT (Maybe SecKey) IO (Ptr Tweak32)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (ForeignPtr Tweak32
-> (Ptr Tweak32 -> IO (Maybe SecKey)) -> IO (Maybe SecKey)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Tweak32
tweakFPtr)
    Ret
ret <- IO Ret -> ContT (Maybe SecKey) IO Ret
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Ctx -> Ptr Seckey32 -> Ptr Tweak32 -> IO Ret
Prim.ecSeckeyTweakMul Ctx
ctx Ptr Seckey32
skOut Ptr Tweak32
twkPtr)
    IO (Maybe SecKey) -> ContT (Maybe SecKey) IO (Maybe SecKey)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (IO (Maybe SecKey) -> ContT (Maybe SecKey) IO (Maybe SecKey))
-> IO (Maybe SecKey) -> ContT (Maybe SecKey) IO (Maybe SecKey)
forall a b. (a -> b) -> a -> b
$
        if Ret -> Bool
isSuccess Ret
ret
            then SecKey -> Maybe SecKey
forall a. a -> Maybe a
Just (SecKey -> Maybe SecKey)
-> (ForeignPtr Seckey32 -> SecKey)
-> ForeignPtr Seckey32
-> Maybe SecKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ForeignPtr Seckey32 -> SecKey
SecKey (ForeignPtr Seckey32 -> Maybe SecKey)
-> IO (ForeignPtr Seckey32) -> IO (Maybe SecKey)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FinalizerPtr Seckey32 -> Ptr Seckey32 -> IO (ForeignPtr Seckey32)
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr FinalizerPtr Seckey32
forall a. FinalizerPtr a
finalizerFree Ptr Seckey32
skOut
            else Ptr Seckey32 -> IO ()
forall a. Ptr a -> IO ()
free Ptr Seckey32
skOut IO () -> Maybe SecKey -> IO (Maybe SecKey)
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Maybe SecKey
forall a. Maybe a
Nothing


-- | Compute 'KeyPair' structure from 'SecKey'
keyPairCreate :: SecKey -> KeyPair
keyPairCreate :: SecKey -> KeyPair
keyPairCreate SecKey{ForeignPtr Seckey32
secKeyFPtr :: ForeignPtr Seckey32
secKeyFPtr :: SecKey -> ForeignPtr Seckey32
..} = IO KeyPair -> KeyPair
forall a. IO a -> a
unsafePerformIO (IO KeyPair -> KeyPair) -> IO KeyPair -> KeyPair
forall a b. (a -> b) -> a -> b
$ do
    Ptr Keypair96
keyPairBuf <- Int -> IO (Ptr Keypair96)
forall a. Int -> IO (Ptr a)
mallocBytes Int
96
    Ret
ret <- ForeignPtr Seckey32 -> (Ptr Seckey32 -> IO Ret) -> IO Ret
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Seckey32
secKeyFPtr ((Ptr Seckey32 -> IO Ret) -> IO Ret)
-> (Ptr Seckey32 -> IO Ret) -> IO Ret
forall a b. (a -> b) -> a -> b
$ Ctx -> Ptr Keypair96 -> Ptr Seckey32 -> IO Ret
Prim.keypairCreate Ctx
ctx Ptr Keypair96
keyPairBuf
    Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Ret -> Bool
isSuccess Ret
ret) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
        Ptr Keypair96 -> IO ()
forall a. Ptr a -> IO ()
free Ptr Keypair96
keyPairBuf
        [Char] -> IO ()
forall a. HasCallStack => [Char] -> a
error [Char]
"Bug: Invalid SecKey Constructed"
    ForeignPtr Keypair96 -> KeyPair
KeyPair (ForeignPtr Keypair96 -> KeyPair)
-> IO (ForeignPtr Keypair96) -> IO KeyPair
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FinalizerPtr Keypair96
-> Ptr Keypair96 -> IO (ForeignPtr Keypair96)
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr FinalizerPtr Keypair96
forall a. FinalizerPtr a
finalizerFree Ptr Keypair96
keyPairBuf


-- | Project 'PubKeyXY' from 'KeyPair'
keyPairPubKeyXY :: KeyPair -> PubKeyXY
keyPairPubKeyXY :: KeyPair -> PubKeyXY
keyPairPubKeyXY KeyPair{ForeignPtr Keypair96
keyPairFPtr :: ForeignPtr Keypair96
keyPairFPtr :: KeyPair -> ForeignPtr Keypair96
..} = IO PubKeyXY -> PubKeyXY
forall a. IO a -> a
unsafePerformIO (IO PubKeyXY -> PubKeyXY) -> IO PubKeyXY -> PubKeyXY
forall a b. (a -> b) -> a -> b
$ do
    Ptr Pubkey64
pubKeyBuf <- Int -> IO (Ptr Pubkey64)
forall a. Int -> IO (Ptr a)
mallocBytes Int
64
    Ret
ret <- ForeignPtr Keypair96 -> (Ptr Keypair96 -> IO Ret) -> IO Ret
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Keypair96
keyPairFPtr ((Ptr Keypair96 -> IO Ret) -> IO Ret)
-> (Ptr Keypair96 -> IO Ret) -> IO Ret
forall a b. (a -> b) -> a -> b
$ Ctx -> Ptr Pubkey64 -> Ptr Keypair96 -> IO Ret
Prim.keypairPub Ctx
ctx Ptr Pubkey64
pubKeyBuf
    Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Ret -> Bool
isSuccess Ret
ret) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
        Ptr Pubkey64 -> IO ()
forall a. Ptr a -> IO ()
free Ptr Pubkey64
pubKeyBuf
        [Char] -> IO ()
forall a. HasCallStack => [Char] -> a
error [Char]
"Bug: Invalid KeyPair Constructed"
    ForeignPtr Pubkey64 -> PubKeyXY
PubKeyXY (ForeignPtr Pubkey64 -> PubKeyXY)
-> IO (ForeignPtr Pubkey64) -> IO PubKeyXY
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FinalizerPtr Pubkey64 -> Ptr Pubkey64 -> IO (ForeignPtr Pubkey64)
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr FinalizerPtr Pubkey64
forall a. FinalizerPtr a
finalizerFree Ptr Pubkey64
pubKeyBuf


-- | Project 'SecKey' from 'KeyPair'
keyPairSecKey :: KeyPair -> SecKey
keyPairSecKey :: KeyPair -> SecKey
keyPairSecKey KeyPair{ForeignPtr Keypair96
keyPairFPtr :: ForeignPtr Keypair96
keyPairFPtr :: KeyPair -> ForeignPtr Keypair96
..} = IO SecKey -> SecKey
forall a. IO a -> a
unsafePerformIO (IO SecKey -> SecKey) -> IO SecKey -> SecKey
forall a b. (a -> b) -> a -> b
$ do
    Ptr Seckey32
secKeyBuf <- Int -> IO (Ptr Seckey32)
forall a. Int -> IO (Ptr a)
mallocBytes Int
32
    Ret
ret <- ForeignPtr Keypair96 -> (Ptr Keypair96 -> IO Ret) -> IO Ret
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Keypair96
keyPairFPtr ((Ptr Keypair96 -> IO Ret) -> IO Ret)
-> (Ptr Keypair96 -> IO Ret) -> IO Ret
forall a b. (a -> b) -> a -> b
$ Ctx -> Ptr Seckey32 -> Ptr Keypair96 -> IO Ret
Prim.keypairSec Ctx
ctx Ptr Seckey32
secKeyBuf
    Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Ret -> Bool
isSuccess Ret
ret) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
        Ptr Seckey32 -> IO ()
forall a. Ptr a -> IO ()
free Ptr Seckey32
secKeyBuf
        [Char] -> IO ()
forall a. HasCallStack => [Char] -> a
error [Char]
"Bug: Invalid KeyPair Constructed"
    ForeignPtr Seckey32 -> SecKey
SecKey (ForeignPtr Seckey32 -> SecKey)
-> IO (ForeignPtr Seckey32) -> IO SecKey
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FinalizerPtr Seckey32 -> Ptr Seckey32 -> IO (ForeignPtr Seckey32)
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr FinalizerPtr Seckey32
forall a. FinalizerPtr a
finalizerFree Ptr Seckey32
secKeyBuf


-- | Project 'PubKeyXO' from 'KeyPair' as well as parity bit. @True@ indicates that the public key is the same as it
-- would be if you had serialized the 'PubKeyXO' and it was prefixed with 'Prim.flagsTagPubkeyOdd'. @False@ indicates
-- it would be prefixed by 'Prim.flagsTagPubkeyEven'
keyPairPubKeyXO :: KeyPair -> (PubKeyXO, Bool)
keyPairPubKeyXO :: KeyPair -> (PubKeyXO, Bool)
keyPairPubKeyXO KeyPair{ForeignPtr Keypair96
keyPairFPtr :: ForeignPtr Keypair96
keyPairFPtr :: KeyPair -> ForeignPtr Keypair96
..} = IO (PubKeyXO, Bool) -> (PubKeyXO, Bool)
forall a. IO a -> a
unsafePerformIO (IO (PubKeyXO, Bool) -> (PubKeyXO, Bool))
-> IO (PubKeyXO, Bool) -> (PubKeyXO, Bool)
forall a b. (a -> b) -> a -> b
$ do
    Ptr XonlyPubkey64
pubKeyBuf <- Int -> IO (Ptr XonlyPubkey64)
forall a. Int -> IO (Ptr a)
mallocBytes Int
64
    Ptr Ret
parityPtr <- IO (Ptr Ret)
forall a. Storable a => IO (Ptr a)
malloc
    Ret
ret <- ForeignPtr Keypair96 -> (Ptr Keypair96 -> IO Ret) -> IO Ret
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Keypair96
keyPairFPtr ((Ptr Keypair96 -> IO Ret) -> IO Ret)
-> (Ptr Keypair96 -> IO Ret) -> IO Ret
forall a b. (a -> b) -> a -> b
$ Ctx -> Ptr XonlyPubkey64 -> Ptr Ret -> Ptr Keypair96 -> IO Ret
Prim.keypairXonlyPub Ctx
ctx Ptr XonlyPubkey64
pubKeyBuf Ptr Ret
parityPtr
    Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Ret -> Bool
isSuccess Ret
ret) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
        Ptr XonlyPubkey64 -> IO ()
forall a. Ptr a -> IO ()
free Ptr XonlyPubkey64
pubKeyBuf
        Ptr Ret -> IO ()
forall a. Ptr a -> IO ()
free Ptr Ret
parityPtr
        [Char] -> IO ()
forall a. HasCallStack => [Char] -> a
error [Char]
"Bug: Invalid KeyPair Constructed"
    Ret
parity <- Ptr Ret -> IO Ret
forall a. Storable a => Ptr a -> IO a
peek Ptr Ret
parityPtr
    Bool
negated <- case Ret
parity of
        Ret
0 -> Bool -> IO Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
False
        Ret
1 -> Bool -> IO Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
True
        Ret
_ -> do
            Ptr XonlyPubkey64 -> IO ()
forall a. Ptr a -> IO ()
free Ptr XonlyPubkey64
pubKeyBuf
            Ptr Ret -> IO ()
forall a. Ptr a -> IO ()
free Ptr Ret
parityPtr
            [Char] -> IO Bool
forall a. HasCallStack => [Char] -> a
error [Char]
"Bug: Invalid pk_parity result from Prim"
    (,Bool
negated) (PubKeyXO -> (PubKeyXO, Bool))
-> (ForeignPtr XonlyPubkey64 -> PubKeyXO)
-> ForeignPtr XonlyPubkey64
-> (PubKeyXO, Bool)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ForeignPtr XonlyPubkey64 -> PubKeyXO
PubKeyXO (ForeignPtr XonlyPubkey64 -> (PubKeyXO, Bool))
-> IO (ForeignPtr XonlyPubkey64) -> IO (PubKeyXO, Bool)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FinalizerPtr XonlyPubkey64
-> Ptr XonlyPubkey64 -> IO (ForeignPtr XonlyPubkey64)
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr FinalizerPtr XonlyPubkey64
forall a. FinalizerPtr a
finalizerFree Ptr XonlyPubkey64
pubKeyBuf


-- | Tweak a 'KeyPair' with a 'Tweak'. If the resulting 'KeyPair' is invalid (0, Infinity), then the result is @Nothing@
keyPairPubKeyXOTweakAdd :: KeyPair -> Tweak -> Maybe KeyPair
keyPairPubKeyXOTweakAdd :: KeyPair -> Tweak -> Maybe KeyPair
keyPairPubKeyXOTweakAdd KeyPair{ForeignPtr Keypair96
keyPairFPtr :: ForeignPtr Keypair96
keyPairFPtr :: KeyPair -> ForeignPtr Keypair96
..} Tweak{ForeignPtr Tweak32
tweakFPtr :: ForeignPtr Tweak32
tweakFPtr :: Tweak -> ForeignPtr Tweak32
..} = IO (Maybe KeyPair) -> Maybe KeyPair
forall a. IO a -> a
unsafePerformIO (IO (Maybe KeyPair) -> Maybe KeyPair)
-> (ContT (Maybe KeyPair) IO (Maybe KeyPair) -> IO (Maybe KeyPair))
-> ContT (Maybe KeyPair) IO (Maybe KeyPair)
-> Maybe KeyPair
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ContT (Maybe KeyPair) IO (Maybe KeyPair) -> IO (Maybe KeyPair)
forall (m :: * -> *) r. Monad m => ContT r m r -> m r
evalContT (ContT (Maybe KeyPair) IO (Maybe KeyPair) -> Maybe KeyPair)
-> ContT (Maybe KeyPair) IO (Maybe KeyPair) -> Maybe KeyPair
forall a b. (a -> b) -> a -> b
$ do
    Ptr Keypair96
keyPairPtr <- ((Ptr Keypair96 -> IO (Maybe KeyPair)) -> IO (Maybe KeyPair))
-> ContT (Maybe KeyPair) IO (Ptr Keypair96)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (ForeignPtr Keypair96
-> (Ptr Keypair96 -> IO (Maybe KeyPair)) -> IO (Maybe KeyPair)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Keypair96
keyPairFPtr)
    Ptr Tweak32
tweakPtr <- ((Ptr Tweak32 -> IO (Maybe KeyPair)) -> IO (Maybe KeyPair))
-> ContT (Maybe KeyPair) IO (Ptr Tweak32)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (ForeignPtr Tweak32
-> (Ptr Tweak32 -> IO (Maybe KeyPair)) -> IO (Maybe KeyPair)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Tweak32
tweakFPtr)
    IO (Maybe KeyPair) -> ContT (Maybe KeyPair) IO (Maybe KeyPair)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (IO (Maybe KeyPair) -> ContT (Maybe KeyPair) IO (Maybe KeyPair))
-> IO (Maybe KeyPair) -> ContT (Maybe KeyPair) IO (Maybe KeyPair)
forall a b. (a -> b) -> a -> b
$ do
        Ptr Keypair96
keyPairOut <- (Int -> IO (Ptr Keypair96)
forall a. Int -> IO (Ptr a)
mallocBytes Int
96)
        Ptr ()
_ <- (Ptr Keypair96 -> Ptr Keypair96 -> CSize -> IO (Ptr ())
forall a. Ptr a -> Ptr a -> CSize -> IO (Ptr ())
memcpy Ptr Keypair96
keyPairOut Ptr Keypair96
keyPairPtr CSize
96)
        Ret
ret <- Ctx -> Ptr Keypair96 -> Ptr Tweak32 -> IO Ret
Prim.keypairXonlyTweakAdd Ctx
ctx Ptr Keypair96
keyPairOut Ptr Tweak32
tweakPtr
        if Ret -> Bool
isSuccess Ret
ret
            then KeyPair -> Maybe KeyPair
forall a. a -> Maybe a
Just (KeyPair -> Maybe KeyPair)
-> (ForeignPtr Keypair96 -> KeyPair)
-> ForeignPtr Keypair96
-> Maybe KeyPair
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ForeignPtr Keypair96 -> KeyPair
KeyPair (ForeignPtr Keypair96 -> Maybe KeyPair)
-> IO (ForeignPtr Keypair96) -> IO (Maybe KeyPair)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FinalizerPtr Keypair96
-> Ptr Keypair96 -> IO (ForeignPtr Keypair96)
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr FinalizerPtr Keypair96
forall a. FinalizerPtr a
finalizerFree Ptr Keypair96
keyPairOut
            else Ptr Keypair96 -> IO ()
forall a. Ptr a -> IO ()
free Ptr Keypair96
keyPairOut IO () -> Maybe KeyPair -> IO (Maybe KeyPair)
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Maybe KeyPair
forall a. Maybe a
Nothing


-- | Compute a schnorr signature using a 'KeyPair'. The @ByteString@ must be 32 bytes long to get a @Just@ out of this
-- function
schnorrSign :: KeyPair -> ByteString -> Maybe Signature
schnorrSign :: KeyPair -> ByteString -> Maybe Signature
schnorrSign KeyPair{ForeignPtr Keypair96
keyPairFPtr :: ForeignPtr Keypair96
keyPairFPtr :: KeyPair -> ForeignPtr Keypair96
..} ByteString
bs
    | ByteString -> Int
BS.length ByteString
bs Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
32 = Maybe Signature
forall a. Maybe a
Nothing
    | Bool
otherwise = IO (Maybe Signature) -> Maybe Signature
forall a. IO a -> a
unsafePerformIO (IO (Maybe Signature) -> Maybe Signature)
-> (ContT (Maybe Signature) IO (Maybe Signature)
    -> IO (Maybe Signature))
-> ContT (Maybe Signature) IO (Maybe Signature)
-> Maybe Signature
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ContT (Maybe Signature) IO (Maybe Signature)
-> IO (Maybe Signature)
forall (m :: * -> *) r. Monad m => ContT r m r -> m r
evalContT (ContT (Maybe Signature) IO (Maybe Signature) -> Maybe Signature)
-> ContT (Maybe Signature) IO (Maybe Signature) -> Maybe Signature
forall a b. (a -> b) -> a -> b
$ do
        (Ptr Msg32
msgHashPtr, CSize
_) <- (((Ptr Msg32, CSize) -> IO (Maybe Signature))
 -> IO (Maybe Signature))
-> ContT (Maybe Signature) IO (Ptr Msg32, CSize)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (ByteString
-> ((Ptr Msg32, CSize) -> IO (Maybe Signature))
-> IO (Maybe Signature)
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
bs)
        Ptr Keypair96
keyPairPtr <- ((Ptr Keypair96 -> IO (Maybe Signature)) -> IO (Maybe Signature))
-> ContT (Maybe Signature) IO (Ptr Keypair96)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (ForeignPtr Keypair96
-> (Ptr Keypair96 -> IO (Maybe Signature)) -> IO (Maybe Signature)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Keypair96
keyPairFPtr)
        IO (Maybe Signature)
-> ContT (Maybe Signature) IO (Maybe Signature)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (IO (Maybe Signature)
 -> ContT (Maybe Signature) IO (Maybe Signature))
-> IO (Maybe Signature)
-> ContT (Maybe Signature) IO (Maybe Signature)
forall a b. (a -> b) -> a -> b
$ do
            Ptr Sig64
sigBuf <- Int -> IO (Ptr Sig64)
forall a. Int -> IO (Ptr a)
mallocBytes Int
64
            -- TODO: provide randomness here instead of supplying a null pointer
            Ret
ret <- Ctx
-> Ptr Sig64
-> Ptr Msg32
-> Ptr Keypair96
-> Ptr (Bytes 32)
-> IO Ret
Prim.schnorrsigSign Ctx
ctx Ptr Sig64
sigBuf Ptr Msg32
msgHashPtr Ptr Keypair96
keyPairPtr Ptr (Bytes 32)
forall a. Ptr a
nullPtr
            if Ret -> Bool
isSuccess Ret
ret
                then Signature -> Maybe Signature
forall a. a -> Maybe a
Just (Signature -> Maybe Signature)
-> (ForeignPtr Sig64 -> Signature)
-> ForeignPtr Sig64
-> Maybe Signature
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ForeignPtr Sig64 -> Signature
Signature (ForeignPtr Sig64 -> Maybe Signature)
-> IO (ForeignPtr Sig64) -> IO (Maybe Signature)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FinalizerPtr Sig64 -> Ptr Sig64 -> IO (ForeignPtr Sig64)
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr FinalizerPtr Sig64
forall a. FinalizerPtr a
finalizerFree Ptr Sig64
sigBuf
                else Ptr Sig64 -> IO ()
forall a. Ptr a -> IO ()
free Ptr Sig64
sigBuf IO () -> Maybe Signature -> IO (Maybe Signature)
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Maybe Signature
forall a. Maybe a
Nothing


-- | Extra parameters object for alternative nonce generation
data SchnorrExtra a = Storable a =>
    SchnorrExtra
    { forall a.
SchnorrExtra a
-> ByteString
-> SecKey
-> PubKeyXO
-> ByteString
-> a
-> Maybe (SizedByteArray 32 ByteString)
schnorrExtraNonceFunHardened :: ByteString -> SecKey -> PubKeyXO -> ByteString -> a -> Maybe (SizedByteArray 32 ByteString)
    , forall a. SchnorrExtra a -> a
schnorrExtraData :: a
    }


-- | Compute a schnorr signature with an alternative scheme for generating nonces, it is not recommended you use this
-- unless you know what you are doing. Instead, favor the usage of 'schnorrSign'
schnorrSignCustom :: forall a. KeyPair -> ByteString -> SchnorrExtra a -> Maybe Signature
schnorrSignCustom :: forall a.
KeyPair -> ByteString -> SchnorrExtra a -> Maybe Signature
schnorrSignCustom KeyPair{ForeignPtr Keypair96
keyPairFPtr :: ForeignPtr Keypair96
keyPairFPtr :: KeyPair -> ForeignPtr Keypair96
..} ByteString
msg SchnorrExtra{a
ByteString
-> SecKey
-> PubKeyXO
-> ByteString
-> a
-> Maybe (SizedByteArray 32 ByteString)
schnorrExtraData :: a
schnorrExtraNonceFunHardened :: ByteString
-> SecKey
-> PubKeyXO
-> ByteString
-> a
-> Maybe (SizedByteArray 32 ByteString)
schnorrExtraData :: forall a. SchnorrExtra a -> a
schnorrExtraNonceFunHardened :: forall a.
SchnorrExtra a
-> ByteString
-> SecKey
-> PubKeyXO
-> ByteString
-> a
-> Maybe (SizedByteArray 32 ByteString)
..} = IO (Maybe Signature) -> Maybe Signature
forall a. IO a -> a
unsafePerformIO (IO (Maybe Signature) -> Maybe Signature)
-> (ContT (Maybe Signature) IO (Maybe Signature)
    -> IO (Maybe Signature))
-> ContT (Maybe Signature) IO (Maybe Signature)
-> Maybe Signature
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ContT (Maybe Signature) IO (Maybe Signature)
-> IO (Maybe Signature)
forall (m :: * -> *) r. Monad m => ContT r m r -> m r
evalContT (ContT (Maybe Signature) IO (Maybe Signature) -> Maybe Signature)
-> ContT (Maybe Signature) IO (Maybe Signature) -> Maybe Signature
forall a b. (a -> b) -> a -> b
$ do
    (Ptr (Bytes Any)
msgPtr, CSize
msgLen) <- (((Ptr (Bytes Any), CSize) -> IO (Maybe Signature))
 -> IO (Maybe Signature))
-> ContT (Maybe Signature) IO (Ptr (Bytes Any), CSize)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (ByteString
-> ((Ptr (Bytes Any), CSize) -> IO (Maybe Signature))
-> IO (Maybe Signature)
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
msg)
    Ptr Keypair96
keyPairPtr <- ((Ptr Keypair96 -> IO (Maybe Signature)) -> IO (Maybe Signature))
-> ContT (Maybe Signature) IO (Ptr Keypair96)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (ForeignPtr Keypair96
-> (Ptr Keypair96 -> IO (Maybe Signature)) -> IO (Maybe Signature)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Keypair96
keyPairFPtr)
    IO (Maybe Signature)
-> ContT (Maybe Signature) IO (Maybe Signature)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (IO (Maybe Signature)
 -> ContT (Maybe Signature) IO (Maybe Signature))
-> IO (Maybe Signature)
-> ContT (Maybe Signature) IO (Maybe Signature)
forall a b. (a -> b) -> a -> b
$ do
        Ptr Sig64
sigBuf <- Int -> IO (Ptr Sig64)
forall a. Int -> IO (Ptr a)
mallocBytes Int
64
        -- convert fn into funptr
        FunPtr (NonceFunHardened a)
funptr <- NonceFunHardened a -> IO (FunPtr (NonceFunHardened a))
forall a. NonceFunHardened a -> IO (FunPtr (NonceFunHardened a))
mkNonceFunHardened NonceFunHardened a
Storable a => NonceFunHardened a
primFn
        -- allocate memory for extra data ptr
        Ptr a
dataptr <- IO (Ptr a)
forall a. Storable a => IO (Ptr a)
malloc
        -- copy data to new pointer
        Ptr a -> a -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr a
dataptr a
schnorrExtraData
        -- allocate extraparams structure
        Ptr SchnorrExtra
extraPtr <- Int -> IO (Ptr SchnorrExtra)
forall a. Int -> IO (Ptr a)
mallocBytes (Int
4 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ FunPtr (NonceFunHardened a) -> Int
forall a. Storable a => a -> Int
sizeOf FunPtr (NonceFunHardened a)
funptr Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Ptr a -> Int
forall a. Storable a => a -> Int
sizeOf Ptr a
dataptr)
        -- fill magic
        Ptr SchnorrExtra -> Int -> Word8 -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr SchnorrExtra
extraPtr Int
0 (Word8
0xDA :: Word8)
        Ptr SchnorrExtra -> Int -> Word8 -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr SchnorrExtra
extraPtr Int
1 (Word8
0x6F :: Word8)
        Ptr SchnorrExtra -> Int -> Word8 -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr SchnorrExtra
extraPtr Int
2 (Word8
0xB3 :: Word8)
        Ptr SchnorrExtra -> Int -> Word8 -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr SchnorrExtra
extraPtr Int
3 (Word8
0x8C :: Word8)
        -- fill funptr
        Ptr SchnorrExtra -> Int -> FunPtr (NonceFunHardened a) -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr SchnorrExtra
extraPtr Int
4 FunPtr (NonceFunHardened a)
funptr
        -- fill dataptr
        Ptr SchnorrExtra -> Int -> Ptr a -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr SchnorrExtra
extraPtr (Int
4 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ FunPtr (NonceFunHardened a) -> Int
forall a. Storable a => a -> Int
sizeOf FunPtr (NonceFunHardened a)
funptr) Ptr a
dataptr
        Ret
ret <- Ctx
-> Ptr Sig64
-> Ptr (Bytes Any)
-> CSize
-> Ptr Keypair96
-> Ptr SchnorrExtra
-> IO Ret
forall (n :: Nat).
Ctx
-> Ptr Sig64
-> Ptr (Bytes n)
-> CSize
-> Ptr Keypair96
-> Ptr SchnorrExtra
-> IO Ret
Prim.schnorrsigSignCustom Ctx
ctx Ptr Sig64
sigBuf Ptr (Bytes Any)
msgPtr CSize
msgLen Ptr Keypair96
keyPairPtr Ptr SchnorrExtra
extraPtr
        FunPtr (NonceFunHardened a) -> IO ()
forall a. FunPtr a -> IO ()
freeHaskellFunPtr FunPtr (NonceFunHardened a)
funptr
        Ptr a -> IO ()
forall a. Ptr a -> IO ()
free Ptr a
dataptr
        Ptr SchnorrExtra -> IO ()
forall a. Ptr a -> IO ()
free Ptr SchnorrExtra
extraPtr
        if Ret -> Bool
isSuccess Ret
ret
            then Signature -> Maybe Signature
forall a. a -> Maybe a
Just (Signature -> Maybe Signature)
-> (ForeignPtr Sig64 -> Signature)
-> ForeignPtr Sig64
-> Maybe Signature
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ForeignPtr Sig64 -> Signature
Signature (ForeignPtr Sig64 -> Maybe Signature)
-> IO (ForeignPtr Sig64) -> IO (Maybe Signature)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FinalizerPtr Sig64 -> Ptr Sig64 -> IO (ForeignPtr Sig64)
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr FinalizerPtr Sig64
forall a. FinalizerPtr a
finalizerFree Ptr Sig64
sigBuf
            else Ptr Sig64 -> IO ()
forall a. Ptr a -> IO ()
free Ptr Sig64
sigBuf IO () -> Maybe Signature -> IO (Maybe Signature)
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Maybe Signature
forall a. Maybe a
Nothing
    where
        primFn :: Storable a => Prim.NonceFunHardened a
        primFn :: Storable a => NonceFunHardened a
primFn Ptr CUChar
outBuf Ptr CUChar
msgPtr CSize
msgLen Ptr CUChar
sk Ptr CUChar
xopk Ptr CUChar
algo CSize
algolen Ptr a
dataPtr = do
            ByteString
msg <- (Ptr CUChar, CSize) -> IO ByteString
forall a. (Ptr a, CSize) -> IO ByteString
unsafePackByteString (Ptr CUChar
msgPtr, CSize
msgLen)
            SecKey
sk <- ForeignPtr Seckey32 -> SecKey
SecKey (ForeignPtr Seckey32 -> SecKey)
-> IO (ForeignPtr Seckey32) -> IO SecKey
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr Seckey32 -> IO (ForeignPtr Seckey32)
forall a. Ptr a -> IO (ForeignPtr a)
newForeignPtr_ (Ptr CUChar -> Ptr Seckey32
forall a b. Ptr a -> Ptr b
castPtr Ptr CUChar
sk)
            PubKeyXO
xopk <- ForeignPtr XonlyPubkey64 -> PubKeyXO
PubKeyXO (ForeignPtr XonlyPubkey64 -> PubKeyXO)
-> IO (ForeignPtr XonlyPubkey64) -> IO PubKeyXO
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr XonlyPubkey64 -> IO (ForeignPtr XonlyPubkey64)
forall a. Ptr a -> IO (ForeignPtr a)
newForeignPtr_ (Ptr CUChar -> Ptr XonlyPubkey64
forall a b. Ptr a -> Ptr b
castPtr Ptr CUChar
xopk)
            ByteString
algo <- (Ptr CUChar, CSize) -> IO ByteString
forall a. (Ptr a, CSize) -> IO ByteString
unsafePackByteString (Ptr CUChar
algo, CSize
algolen)
            a
extra <- Ptr a -> IO a
forall a. Storable a => Ptr a -> IO a
peek Ptr a
dataPtr
            case ByteString
-> SecKey
-> PubKeyXO
-> ByteString
-> a
-> Maybe (SizedByteArray 32 ByteString)
schnorrExtraNonceFunHardened ByteString
msg SecKey
sk PubKeyXO
xopk ByteString
algo a
extra of
                Maybe (SizedByteArray 32 ByteString)
Nothing -> Ret -> IO Ret
forall (f :: * -> *) a. Applicative f => a -> f a
pure Ret
0
                Just SizedByteArray 32 ByteString
bs -> ContT Ret IO Ret -> IO Ret
forall (m :: * -> *) r. Monad m => ContT r m r -> m r
evalContT (ContT Ret IO Ret -> IO Ret) -> ContT Ret IO Ret -> IO Ret
forall a b. (a -> b) -> a -> b
$ do
                    (Ptr CUChar
hashPtr, CSize
_) <- (((Ptr CUChar, CSize) -> IO Ret) -> IO Ret)
-> ContT Ret IO (Ptr CUChar, CSize)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (ByteString -> ((Ptr CUChar, CSize) -> IO Ret) -> IO Ret
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString (SizedByteArray 32 ByteString -> ByteString
forall (n :: Nat) ba. SizedByteArray n ba -> ba
unSizedByteArray SizedByteArray 32 ByteString
bs))
                    IO (Ptr ()) -> ContT Ret IO (Ptr ())
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Ptr CUChar -> Ptr CUChar -> CSize -> IO (Ptr ())
forall a. Ptr a -> Ptr a -> CSize -> IO (Ptr ())
memcpy Ptr CUChar
outBuf Ptr CUChar
hashPtr CSize
32)
                    Ret -> ContT Ret IO Ret
forall (f :: * -> *) a. Applicative f => a -> f a
pure Ret
1


-- | Verify the authenticity of a schnorr signature. @True@ means the 'Signature' is correct.
schnorrVerify :: PubKeyXO -> ByteString -> Signature -> Bool
schnorrVerify :: PubKeyXO -> ByteString -> Signature -> Bool
schnorrVerify PubKeyXO{ForeignPtr XonlyPubkey64
pubKeyXOFPtr :: ForeignPtr XonlyPubkey64
pubKeyXOFPtr :: PubKeyXO -> ForeignPtr XonlyPubkey64
..} ByteString
bs Signature{ForeignPtr Sig64
signatureFPtr :: ForeignPtr Sig64
signatureFPtr :: Signature -> ForeignPtr Sig64
..} = IO Bool -> Bool
forall a. IO a -> a
unsafePerformIO (IO Bool -> Bool)
-> (ContT Bool IO Bool -> IO Bool) -> ContT Bool IO Bool -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ContT Bool IO Bool -> IO Bool
forall (m :: * -> *) r. Monad m => ContT r m r -> m r
evalContT (ContT Bool IO Bool -> Bool) -> ContT Bool IO Bool -> Bool
forall a b. (a -> b) -> a -> b
$ do
    Ptr XonlyPubkey64
pubKeyPtr <- ((Ptr XonlyPubkey64 -> IO Bool) -> IO Bool)
-> ContT Bool IO (Ptr XonlyPubkey64)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (ForeignPtr XonlyPubkey64
-> (Ptr XonlyPubkey64 -> IO Bool) -> IO Bool
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr XonlyPubkey64
pubKeyXOFPtr)
    Ptr Sig64
signaturePtr <- ((Ptr Sig64 -> IO Bool) -> IO Bool) -> ContT Bool IO (Ptr Sig64)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (ForeignPtr Sig64 -> (Ptr Sig64 -> IO Bool) -> IO Bool
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Sig64
signatureFPtr)
    (Ptr (Bytes Any)
msgPtr, CSize
msgLen) <- (((Ptr (Bytes Any), CSize) -> IO Bool) -> IO Bool)
-> ContT Bool IO (Ptr (Bytes Any), CSize)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (ByteString -> ((Ptr (Bytes Any), CSize) -> IO Bool) -> IO Bool
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
bs)
    IO Bool -> ContT Bool IO Bool
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (IO Bool -> ContT Bool IO Bool) -> IO Bool -> ContT Bool IO Bool
forall a b. (a -> b) -> a -> b
$ Ret -> Bool
isSuccess (Ret -> Bool) -> IO Ret -> IO Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ctx
-> Ptr Sig64
-> Ptr (Bytes Any)
-> CSize
-> Ptr XonlyPubkey64
-> IO Ret
forall (n :: Nat).
Ctx
-> Ptr Sig64
-> Ptr (Bytes n)
-> CSize
-> Ptr XonlyPubkey64
-> IO Ret
Prim.schnorrsigSignVerify Ctx
ctx Ptr Sig64
signaturePtr Ptr (Bytes Any)
msgPtr CSize
msgLen Ptr XonlyPubkey64
pubKeyPtr


-- | Generate a tagged sha256 digest as specified in BIP340
taggedSha256 :: ByteString -> ByteString -> Digest SHA256
taggedSha256 :: ByteString -> ByteString -> Digest SHA256
taggedSha256 ByteString
tag ByteString
msg = IO (Digest SHA256) -> Digest SHA256
forall a. IO a -> a
unsafePerformIO (IO (Digest SHA256) -> Digest SHA256)
-> (ContT (Digest SHA256) IO (Digest SHA256) -> IO (Digest SHA256))
-> ContT (Digest SHA256) IO (Digest SHA256)
-> Digest SHA256
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ContT (Digest SHA256) IO (Digest SHA256) -> IO (Digest SHA256)
forall (m :: * -> *) r. Monad m => ContT r m r -> m r
evalContT (ContT (Digest SHA256) IO (Digest SHA256) -> Digest SHA256)
-> ContT (Digest SHA256) IO (Digest SHA256) -> Digest SHA256
forall a b. (a -> b) -> a -> b
$ do
    (Ptr (Bytes Any)
tagBuf, CSize
tagLen) <- (((Ptr (Bytes Any), CSize) -> IO (Digest SHA256))
 -> IO (Digest SHA256))
-> ContT (Digest SHA256) IO (Ptr (Bytes Any), CSize)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (ByteString
-> ((Ptr (Bytes Any), CSize) -> IO (Digest SHA256))
-> IO (Digest SHA256)
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
tag)
    (Ptr (Bytes Any)
msgBuf, CSize
msgLen) <- (((Ptr (Bytes Any), CSize) -> IO (Digest SHA256))
 -> IO (Digest SHA256))
-> ContT (Digest SHA256) IO (Ptr (Bytes Any), CSize)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (ByteString
-> ((Ptr (Bytes Any), CSize) -> IO (Digest SHA256))
-> IO (Digest SHA256)
forall a b. ByteString -> ((Ptr a, CSize) -> IO b) -> IO b
unsafeUseByteString ByteString
msg)
    IO (Digest SHA256) -> ContT (Digest SHA256) IO (Digest SHA256)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (IO (Digest SHA256) -> ContT (Digest SHA256) IO (Digest SHA256))
-> IO (Digest SHA256) -> ContT (Digest SHA256) IO (Digest SHA256)
forall a b. (a -> b) -> a -> b
$ do
        Ptr (Bytes 32)
hashBuf <- Int -> IO (Ptr (Bytes 32))
forall a. Int -> IO (Ptr a)
mallocBytes Int
32
        Ret
ret <- Ctx
-> Ptr (Bytes 32)
-> Ptr (Bytes Any)
-> CSize
-> Ptr (Bytes Any)
-> CSize
-> IO Ret
forall (n :: Nat).
Ctx
-> Ptr (Bytes 32)
-> Ptr (Bytes n)
-> CSize
-> Ptr (Bytes n)
-> CSize
-> IO Ret
Prim.taggedSha256 Ctx
ctx Ptr (Bytes 32)
hashBuf Ptr (Bytes Any)
tagBuf CSize
tagLen Ptr (Bytes Any)
msgBuf CSize
msgLen
        Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Ret -> Bool
isSuccess Ret
ret) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
            Ptr (Bytes 32) -> IO ()
forall a. Ptr a -> IO ()
free Ptr (Bytes 32)
hashBuf
            [Char] -> IO ()
forall a. HasCallStack => [Char] -> a
error [Char]
"Bug: Invalid use of C Lib"
        ByteString
bs <- (Ptr (Bytes 32), CSize) -> IO ByteString
forall a. (Ptr a, CSize) -> IO ByteString
unsafePackByteString (Ptr (Bytes 32)
hashBuf, CSize
32)
        let Just Digest SHA256
digest = ByteString -> Maybe (Digest SHA256)
forall a ba.
(HashAlgorithm a, ByteArrayAccess ba) =>
ba -> Maybe (Digest a)
digestFromByteString ByteString
bs
        Digest SHA256 -> IO (Digest SHA256)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Digest SHA256
digest


-- | Combine a list of 'PubKeyXY's into a single 'PubKeyXY'. This will result in @Nothing@ if the group operation results
-- in the Point at Infinity
pubKeyCombine :: [PubKeyXY] -> Maybe PubKeyXY
pubKeyCombine :: [PubKeyXY] -> Maybe PubKeyXY
pubKeyCombine [PubKeyXY]
keys = IO (Maybe PubKeyXY) -> Maybe PubKeyXY
forall a. IO a -> a
unsafePerformIO (IO (Maybe PubKeyXY) -> Maybe PubKeyXY)
-> IO (Maybe PubKeyXY) -> Maybe PubKeyXY
forall a b. (a -> b) -> a -> b
$ do
    let n :: Int
n = [PubKeyXY] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [PubKeyXY]
keys
    Ptr (Ptr Pubkey64)
keysBuf <- Int -> IO (Ptr (Ptr Pubkey64))
forall a. Int -> IO (Ptr a)
mallocBytes (Int
64 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
n)
    [(Int, PubKeyXY)] -> ((Int, PubKeyXY) -> IO ()) -> IO ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ ([Int] -> [PubKeyXY] -> [(Int, PubKeyXY)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0 ..] [PubKeyXY]
keys) (((Int, PubKeyXY) -> IO ()) -> IO ())
-> ((Int, PubKeyXY) -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \(Int
i, PubKeyXY{ForeignPtr Pubkey64
pubKeyXYFPtr :: ForeignPtr Pubkey64
pubKeyXYFPtr :: PubKeyXY -> ForeignPtr Pubkey64
..}) ->
        ForeignPtr Pubkey64 -> (Ptr Pubkey64 -> IO ()) -> IO ()
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Pubkey64
pubKeyXYFPtr ((Ptr Pubkey64 -> IO ()) -> IO ())
-> (Ptr Pubkey64 -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ Ptr (Ptr Pubkey64) -> Int -> Ptr Pubkey64 -> IO ()
forall a. Storable a => Ptr a -> Int -> a -> IO ()
pokeElemOff Ptr (Ptr Pubkey64)
keysBuf Int
i
    Ptr Pubkey64
outBuf <- Int -> IO (Ptr Pubkey64)
forall a. Int -> IO (Ptr a)
mallocBytes Int
64
    Ret
ret <- Ctx -> Ptr Pubkey64 -> Ptr (Ptr Pubkey64) -> Ret -> IO Ret
Prim.ecPubkeyCombine Ctx
ctx Ptr Pubkey64
outBuf Ptr (Ptr Pubkey64)
keysBuf (Int -> Ret
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n)
    if Ret -> Bool
isSuccess Ret
ret
        then PubKeyXY -> Maybe PubKeyXY
forall a. a -> Maybe a
Just (PubKeyXY -> Maybe PubKeyXY)
-> (ForeignPtr Pubkey64 -> PubKeyXY)
-> ForeignPtr Pubkey64
-> Maybe PubKeyXY
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ForeignPtr Pubkey64 -> PubKeyXY
PubKeyXY (ForeignPtr Pubkey64 -> Maybe PubKeyXY)
-> IO (ForeignPtr Pubkey64) -> IO (Maybe PubKeyXY)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FinalizerPtr Pubkey64 -> Ptr Pubkey64 -> IO (ForeignPtr Pubkey64)
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr FinalizerPtr Pubkey64
forall a. FinalizerPtr a
finalizerFree Ptr Pubkey64
outBuf
        else Ptr Pubkey64 -> IO ()
forall a. Ptr a -> IO ()
free Ptr Pubkey64
outBuf IO () -> Maybe PubKeyXY -> IO (Maybe PubKeyXY)
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Maybe PubKeyXY
forall a. Maybe a
Nothing


-- | Negate a 'PubKeyXY'
pubKeyNegate :: PubKeyXY -> PubKeyXY
pubKeyNegate :: PubKeyXY -> PubKeyXY
pubKeyNegate PubKeyXY{ForeignPtr Pubkey64
pubKeyXYFPtr :: ForeignPtr Pubkey64
pubKeyXYFPtr :: PubKeyXY -> ForeignPtr Pubkey64
..} = IO PubKeyXY -> PubKeyXY
forall a. IO a -> a
unsafePerformIO (IO PubKeyXY -> PubKeyXY) -> IO PubKeyXY -> PubKeyXY
forall a b. (a -> b) -> a -> b
$ do
    Ptr Pubkey64
outBuf <- Int -> IO (Ptr Pubkey64)
forall a. Int -> IO (Ptr a)
mallocBytes Int
64
    ForeignPtr Pubkey64 -> (Ptr Pubkey64 -> IO (Ptr ())) -> IO (Ptr ())
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Pubkey64
pubKeyXYFPtr ((Ptr Pubkey64 -> IO (Ptr ())) -> IO (Ptr ()))
-> (Ptr Pubkey64 -> IO (Ptr ())) -> IO (Ptr ())
forall a b. (a -> b) -> a -> b
$ (Ptr Pubkey64 -> CSize -> IO (Ptr ()))
-> CSize -> Ptr Pubkey64 -> IO (Ptr ())
forall a b c. (a -> b -> c) -> b -> a -> c
flip (Ptr Pubkey64 -> Ptr Pubkey64 -> CSize -> IO (Ptr ())
forall a. Ptr a -> Ptr a -> CSize -> IO (Ptr ())
memcpy Ptr Pubkey64
outBuf) CSize
64
    Ret
_ret <- Ctx -> Ptr Pubkey64 -> IO Ret
Prim.ecPubkeyNegate Ctx
ctx Ptr Pubkey64
outBuf
    ForeignPtr Pubkey64 -> PubKeyXY
PubKeyXY (ForeignPtr Pubkey64 -> PubKeyXY)
-> IO (ForeignPtr Pubkey64) -> IO PubKeyXY
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FinalizerPtr Pubkey64 -> Ptr Pubkey64 -> IO (ForeignPtr Pubkey64)
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr FinalizerPtr Pubkey64
forall a. FinalizerPtr a
finalizerFree Ptr Pubkey64
outBuf


-- | Add 'Tweak' to 'PubKeyXY'. This will result in @Nothing@ if the group operation results in the Point at Infinity
pubKeyTweakAdd :: PubKeyXY -> Tweak -> Maybe PubKeyXY
pubKeyTweakAdd :: PubKeyXY -> Tweak -> Maybe PubKeyXY
pubKeyTweakAdd PubKeyXY{ForeignPtr Pubkey64
pubKeyXYFPtr :: ForeignPtr Pubkey64
pubKeyXYFPtr :: PubKeyXY -> ForeignPtr Pubkey64
..} Tweak{ForeignPtr Tweak32
tweakFPtr :: ForeignPtr Tweak32
tweakFPtr :: Tweak -> ForeignPtr Tweak32
..} = IO (Maybe PubKeyXY) -> Maybe PubKeyXY
forall a. IO a -> a
unsafePerformIO (IO (Maybe PubKeyXY) -> Maybe PubKeyXY)
-> (ContT (Maybe PubKeyXY) IO (Maybe PubKeyXY)
    -> IO (Maybe PubKeyXY))
-> ContT (Maybe PubKeyXY) IO (Maybe PubKeyXY)
-> Maybe PubKeyXY
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ContT (Maybe PubKeyXY) IO (Maybe PubKeyXY) -> IO (Maybe PubKeyXY)
forall (m :: * -> *) r. Monad m => ContT r m r -> m r
evalContT (ContT (Maybe PubKeyXY) IO (Maybe PubKeyXY) -> Maybe PubKeyXY)
-> ContT (Maybe PubKeyXY) IO (Maybe PubKeyXY) -> Maybe PubKeyXY
forall a b. (a -> b) -> a -> b
$ do
    Ptr Pubkey64
pubKeyPtr <- ((Ptr Pubkey64 -> IO (Maybe PubKeyXY)) -> IO (Maybe PubKeyXY))
-> ContT (Maybe PubKeyXY) IO (Ptr Pubkey64)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (ForeignPtr Pubkey64
-> (Ptr Pubkey64 -> IO (Maybe PubKeyXY)) -> IO (Maybe PubKeyXY)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Pubkey64
pubKeyXYFPtr)
    Ptr Tweak32
tweakPtr <- ((Ptr Tweak32 -> IO (Maybe PubKeyXY)) -> IO (Maybe PubKeyXY))
-> ContT (Maybe PubKeyXY) IO (Ptr Tweak32)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (ForeignPtr Tweak32
-> (Ptr Tweak32 -> IO (Maybe PubKeyXY)) -> IO (Maybe PubKeyXY)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Tweak32
tweakFPtr)
    IO (Maybe PubKeyXY) -> ContT (Maybe PubKeyXY) IO (Maybe PubKeyXY)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (IO (Maybe PubKeyXY) -> ContT (Maybe PubKeyXY) IO (Maybe PubKeyXY))
-> IO (Maybe PubKeyXY)
-> ContT (Maybe PubKeyXY) IO (Maybe PubKeyXY)
forall a b. (a -> b) -> a -> b
$ do
        Ptr Pubkey64
pubKeyOutBuf <- Int -> IO (Ptr Pubkey64)
forall a. Int -> IO (Ptr a)
mallocBytes Int
64
        Ptr Pubkey64 -> Ptr Pubkey64 -> CSize -> IO (Ptr ())
forall a. Ptr a -> Ptr a -> CSize -> IO (Ptr ())
memcpy Ptr Pubkey64
pubKeyOutBuf Ptr Pubkey64
pubKeyPtr CSize
64
        Ret
ret <- Ctx -> Ptr Pubkey64 -> Ptr Tweak32 -> IO Ret
Prim.ecPubkeyTweakAdd Ctx
ctx Ptr Pubkey64
pubKeyOutBuf Ptr Tweak32
tweakPtr
        if Ret -> Bool
isSuccess Ret
ret
            then PubKeyXY -> Maybe PubKeyXY
forall a. a -> Maybe a
Just (PubKeyXY -> Maybe PubKeyXY)
-> (ForeignPtr Pubkey64 -> PubKeyXY)
-> ForeignPtr Pubkey64
-> Maybe PubKeyXY
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ForeignPtr Pubkey64 -> PubKeyXY
PubKeyXY (ForeignPtr Pubkey64 -> Maybe PubKeyXY)
-> IO (ForeignPtr Pubkey64) -> IO (Maybe PubKeyXY)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FinalizerPtr Pubkey64 -> Ptr Pubkey64 -> IO (ForeignPtr Pubkey64)
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr FinalizerPtr Pubkey64
forall a. FinalizerPtr a
finalizerFree Ptr Pubkey64
pubKeyOutBuf
            else Ptr Pubkey64 -> IO ()
forall a. Ptr a -> IO ()
free Ptr Pubkey64
pubKeyOutBuf IO () -> Maybe PubKeyXY -> IO (Maybe PubKeyXY)
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Maybe PubKeyXY
forall a. Maybe a
Nothing


-- | Multiply 'PubKeyXY' by 'Tweak'. This will result in @Nothing@ if the group operation results in the Point at Infinity
pubKeyTweakMul :: PubKeyXY -> Tweak -> Maybe PubKeyXY
pubKeyTweakMul :: PubKeyXY -> Tweak -> Maybe PubKeyXY
pubKeyTweakMul PubKeyXY{ForeignPtr Pubkey64
pubKeyXYFPtr :: ForeignPtr Pubkey64
pubKeyXYFPtr :: PubKeyXY -> ForeignPtr Pubkey64
..} Tweak{ForeignPtr Tweak32
tweakFPtr :: ForeignPtr Tweak32
tweakFPtr :: Tweak -> ForeignPtr Tweak32
..} = IO (Maybe PubKeyXY) -> Maybe PubKeyXY
forall a. IO a -> a
unsafePerformIO (IO (Maybe PubKeyXY) -> Maybe PubKeyXY)
-> (ContT (Maybe PubKeyXY) IO (Maybe PubKeyXY)
    -> IO (Maybe PubKeyXY))
-> ContT (Maybe PubKeyXY) IO (Maybe PubKeyXY)
-> Maybe PubKeyXY
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ContT (Maybe PubKeyXY) IO (Maybe PubKeyXY) -> IO (Maybe PubKeyXY)
forall (m :: * -> *) r. Monad m => ContT r m r -> m r
evalContT (ContT (Maybe PubKeyXY) IO (Maybe PubKeyXY) -> Maybe PubKeyXY)
-> ContT (Maybe PubKeyXY) IO (Maybe PubKeyXY) -> Maybe PubKeyXY
forall a b. (a -> b) -> a -> b
$ do
    Ptr Pubkey64
pubKeyPtr <- ((Ptr Pubkey64 -> IO (Maybe PubKeyXY)) -> IO (Maybe PubKeyXY))
-> ContT (Maybe PubKeyXY) IO (Ptr Pubkey64)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (ForeignPtr Pubkey64
-> (Ptr Pubkey64 -> IO (Maybe PubKeyXY)) -> IO (Maybe PubKeyXY)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Pubkey64
pubKeyXYFPtr)
    Ptr Tweak32
tweakPtr <- ((Ptr Tweak32 -> IO (Maybe PubKeyXY)) -> IO (Maybe PubKeyXY))
-> ContT (Maybe PubKeyXY) IO (Ptr Tweak32)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (ForeignPtr Tweak32
-> (Ptr Tweak32 -> IO (Maybe PubKeyXY)) -> IO (Maybe PubKeyXY)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Tweak32
tweakFPtr)
    IO (Maybe PubKeyXY) -> ContT (Maybe PubKeyXY) IO (Maybe PubKeyXY)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (IO (Maybe PubKeyXY) -> ContT (Maybe PubKeyXY) IO (Maybe PubKeyXY))
-> IO (Maybe PubKeyXY)
-> ContT (Maybe PubKeyXY) IO (Maybe PubKeyXY)
forall a b. (a -> b) -> a -> b
$ do
        Ptr Pubkey64
pubKeyOutBuf <- Int -> IO (Ptr Pubkey64)
forall a. Int -> IO (Ptr a)
mallocBytes Int
64
        Ptr Pubkey64 -> Ptr Pubkey64 -> CSize -> IO (Ptr ())
forall a. Ptr a -> Ptr a -> CSize -> IO (Ptr ())
memcpy Ptr Pubkey64
pubKeyOutBuf Ptr Pubkey64
pubKeyPtr CSize
64
        Ret
ret <- Ctx -> Ptr Pubkey64 -> Ptr Tweak32 -> IO Ret
Prim.ecPubkeyTweakMul Ctx
ctx Ptr Pubkey64
pubKeyOutBuf Ptr Tweak32
tweakPtr
        if Ret -> Bool
isSuccess Ret
ret
            then PubKeyXY -> Maybe PubKeyXY
forall a. a -> Maybe a
Just (PubKeyXY -> Maybe PubKeyXY)
-> (ForeignPtr Pubkey64 -> PubKeyXY)
-> ForeignPtr Pubkey64
-> Maybe PubKeyXY
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ForeignPtr Pubkey64 -> PubKeyXY
PubKeyXY (ForeignPtr Pubkey64 -> Maybe PubKeyXY)
-> IO (ForeignPtr Pubkey64) -> IO (Maybe PubKeyXY)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FinalizerPtr Pubkey64 -> Ptr Pubkey64 -> IO (ForeignPtr Pubkey64)
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr FinalizerPtr Pubkey64
forall a. FinalizerPtr a
finalizerFree Ptr Pubkey64
pubKeyOutBuf
            else Ptr Pubkey64 -> IO ()
forall a. Ptr a -> IO ()
free Ptr Pubkey64
pubKeyOutBuf IO () -> Maybe PubKeyXY -> IO (Maybe PubKeyXY)
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Maybe PubKeyXY
forall a. Maybe a
Nothing


-- | Negate a 'SecKey'
secKeyNegate :: SecKey -> SecKey
secKeyNegate :: SecKey -> SecKey
secKeyNegate SecKey{ForeignPtr Seckey32
secKeyFPtr :: ForeignPtr Seckey32
secKeyFPtr :: SecKey -> ForeignPtr Seckey32
..} = IO SecKey -> SecKey
forall a. IO a -> a
unsafePerformIO (IO SecKey -> SecKey) -> IO SecKey -> SecKey
forall a b. (a -> b) -> a -> b
$ do
    Ptr Seckey32
outBuf <- Int -> IO (Ptr Seckey32)
forall a. Int -> IO (Ptr a)
mallocBytes Int
32
    ForeignPtr Seckey32 -> (Ptr Seckey32 -> IO (Ptr ())) -> IO (Ptr ())
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Seckey32
secKeyFPtr ((Ptr Seckey32 -> IO (Ptr ())) -> IO (Ptr ()))
-> (Ptr Seckey32 -> IO (Ptr ())) -> IO (Ptr ())
forall a b. (a -> b) -> a -> b
$ (Ptr Seckey32 -> CSize -> IO (Ptr ()))
-> CSize -> Ptr Seckey32 -> IO (Ptr ())
forall a b c. (a -> b -> c) -> b -> a -> c
flip (Ptr Seckey32 -> Ptr Seckey32 -> CSize -> IO (Ptr ())
forall a. Ptr a -> Ptr a -> CSize -> IO (Ptr ())
memcpy Ptr Seckey32
outBuf) CSize
32
    Ret
_ret <- Ctx -> Ptr Seckey32 -> IO Ret
Prim.ecSeckeyNegate Ctx
ctx Ptr Seckey32
outBuf
    ForeignPtr Seckey32 -> SecKey
SecKey (ForeignPtr Seckey32 -> SecKey)
-> IO (ForeignPtr Seckey32) -> IO SecKey
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FinalizerPtr Seckey32 -> Ptr Seckey32 -> IO (ForeignPtr Seckey32)
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr FinalizerPtr Seckey32
forall a. FinalizerPtr a
finalizerFree Ptr Seckey32
outBuf


-- | Convert 'PubKeyXY' to 'PubKeyXO'. See 'keyPairPubKeyXO' for more information on how to interpret the parity bit.
xyToXO :: PubKeyXY -> (PubKeyXO, Bool)
xyToXO :: PubKeyXY -> (PubKeyXO, Bool)
xyToXO PubKeyXY{ForeignPtr Pubkey64
pubKeyXYFPtr :: ForeignPtr Pubkey64
pubKeyXYFPtr :: PubKeyXY -> ForeignPtr Pubkey64
..} = IO (PubKeyXO, Bool) -> (PubKeyXO, Bool)
forall a. IO a -> a
unsafePerformIO (IO (PubKeyXO, Bool) -> (PubKeyXO, Bool))
-> IO (PubKeyXO, Bool) -> (PubKeyXO, Bool)
forall a b. (a -> b) -> a -> b
$ do
    Ptr XonlyPubkey64
outBuf <- Int -> IO (Ptr XonlyPubkey64)
forall a. Int -> IO (Ptr a)
mallocBytes Int
64
    Ptr Ret
parityPtr <- IO (Ptr Ret)
forall a. Storable a => IO (Ptr a)
malloc
    Ret
ret <- ForeignPtr Pubkey64 -> (Ptr Pubkey64 -> IO Ret) -> IO Ret
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Pubkey64
pubKeyXYFPtr ((Ptr Pubkey64 -> IO Ret) -> IO Ret)
-> (Ptr Pubkey64 -> IO Ret) -> IO Ret
forall a b. (a -> b) -> a -> b
$ Ctx -> Ptr XonlyPubkey64 -> Ptr Ret -> Ptr Pubkey64 -> IO Ret
Prim.xonlyPubkeyFromPubkey Ctx
ctx Ptr XonlyPubkey64
outBuf Ptr Ret
parityPtr
    Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Ret -> Bool
isSuccess Ret
ret) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
        Ptr XonlyPubkey64 -> IO ()
forall a. Ptr a -> IO ()
free Ptr XonlyPubkey64
outBuf
        [Char] -> IO ()
forall a. HasCallStack => [Char] -> a
error [Char]
"Bug: Couldn't convert xy to xo"
    Ret
parity <- Ptr Ret -> IO Ret
forall a. Storable a => Ptr a -> IO a
peek Ptr Ret
parityPtr
    Bool
negated <- case Ret
parity of
        Ret
0 -> Bool -> IO Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
False
        Ret
1 -> Bool -> IO Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
True
        Ret
_ -> Ptr XonlyPubkey64 -> IO ()
forall a. Ptr a -> IO ()
free Ptr XonlyPubkey64
outBuf IO () -> IO Bool -> IO Bool
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> [Char] -> IO Bool
forall a. HasCallStack => [Char] -> a
error [Char]
"Bug: Invalid pk_parity from Prim"
    (,Bool
negated) (PubKeyXO -> (PubKeyXO, Bool))
-> (ForeignPtr XonlyPubkey64 -> PubKeyXO)
-> ForeignPtr XonlyPubkey64
-> (PubKeyXO, Bool)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ForeignPtr XonlyPubkey64 -> PubKeyXO
PubKeyXO (ForeignPtr XonlyPubkey64 -> (PubKeyXO, Bool))
-> IO (ForeignPtr XonlyPubkey64) -> IO (PubKeyXO, Bool)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FinalizerPtr XonlyPubkey64
-> Ptr XonlyPubkey64 -> IO (ForeignPtr XonlyPubkey64)
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr FinalizerPtr XonlyPubkey64
forall a. FinalizerPtr a
finalizerFree Ptr XonlyPubkey64
outBuf


-- | Add 'Tweak' to 'PubKeyXO'. This will result in @Nothing@ if the group operation results in the Point at Infinity
pubKeyXOTweakAdd :: PubKeyXO -> Tweak -> Maybe PubKeyXY
pubKeyXOTweakAdd :: PubKeyXO -> Tweak -> Maybe PubKeyXY
pubKeyXOTweakAdd PubKeyXO{ForeignPtr XonlyPubkey64
pubKeyXOFPtr :: ForeignPtr XonlyPubkey64
pubKeyXOFPtr :: PubKeyXO -> ForeignPtr XonlyPubkey64
..} Tweak{ForeignPtr Tweak32
tweakFPtr :: ForeignPtr Tweak32
tweakFPtr :: Tweak -> ForeignPtr Tweak32
..} = IO (Maybe PubKeyXY) -> Maybe PubKeyXY
forall a. IO a -> a
unsafePerformIO (IO (Maybe PubKeyXY) -> Maybe PubKeyXY)
-> (ContT (Maybe PubKeyXY) IO (Maybe PubKeyXY)
    -> IO (Maybe PubKeyXY))
-> ContT (Maybe PubKeyXY) IO (Maybe PubKeyXY)
-> Maybe PubKeyXY
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ContT (Maybe PubKeyXY) IO (Maybe PubKeyXY) -> IO (Maybe PubKeyXY)
forall (m :: * -> *) r. Monad m => ContT r m r -> m r
evalContT (ContT (Maybe PubKeyXY) IO (Maybe PubKeyXY) -> Maybe PubKeyXY)
-> ContT (Maybe PubKeyXY) IO (Maybe PubKeyXY) -> Maybe PubKeyXY
forall a b. (a -> b) -> a -> b
$ do
    Ptr XonlyPubkey64
pubKeyXOPtr <- ((Ptr XonlyPubkey64 -> IO (Maybe PubKeyXY)) -> IO (Maybe PubKeyXY))
-> ContT (Maybe PubKeyXY) IO (Ptr XonlyPubkey64)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (ForeignPtr XonlyPubkey64
-> (Ptr XonlyPubkey64 -> IO (Maybe PubKeyXY))
-> IO (Maybe PubKeyXY)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr XonlyPubkey64
pubKeyXOFPtr)
    Ptr Tweak32
tweakPtr <- ((Ptr Tweak32 -> IO (Maybe PubKeyXY)) -> IO (Maybe PubKeyXY))
-> ContT (Maybe PubKeyXY) IO (Ptr Tweak32)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (ForeignPtr Tweak32
-> (Ptr Tweak32 -> IO (Maybe PubKeyXY)) -> IO (Maybe PubKeyXY)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Tweak32
tweakFPtr)
    IO (Maybe PubKeyXY) -> ContT (Maybe PubKeyXY) IO (Maybe PubKeyXY)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (IO (Maybe PubKeyXY) -> ContT (Maybe PubKeyXY) IO (Maybe PubKeyXY))
-> IO (Maybe PubKeyXY)
-> ContT (Maybe PubKeyXY) IO (Maybe PubKeyXY)
forall a b. (a -> b) -> a -> b
$ do
        Ptr Pubkey64
outBuf <- Int -> IO (Ptr Pubkey64)
forall a. Int -> IO (Ptr a)
mallocBytes Int
64
        Ret
ret <- Ctx -> Ptr Pubkey64 -> Ptr XonlyPubkey64 -> Ptr Tweak32 -> IO Ret
Prim.xonlyPubkeyTweakAdd Ctx
ctx Ptr Pubkey64
outBuf Ptr XonlyPubkey64
pubKeyXOPtr Ptr Tweak32
tweakPtr
        if Ret -> Bool
isSuccess Ret
ret
            then PubKeyXY -> Maybe PubKeyXY
forall a. a -> Maybe a
Just (PubKeyXY -> Maybe PubKeyXY)
-> (ForeignPtr Pubkey64 -> PubKeyXY)
-> ForeignPtr Pubkey64
-> Maybe PubKeyXY
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ForeignPtr Pubkey64 -> PubKeyXY
PubKeyXY (ForeignPtr Pubkey64 -> Maybe PubKeyXY)
-> IO (ForeignPtr Pubkey64) -> IO (Maybe PubKeyXY)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FinalizerPtr Pubkey64 -> Ptr Pubkey64 -> IO (ForeignPtr Pubkey64)
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr FinalizerPtr Pubkey64
forall a. FinalizerPtr a
finalizerFree Ptr Pubkey64
outBuf
            else Ptr Pubkey64 -> IO ()
forall a. Ptr a -> IO ()
free Ptr Pubkey64
outBuf IO () -> Maybe PubKeyXY -> IO (Maybe PubKeyXY)
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Maybe PubKeyXY
forall a. Maybe a
Nothing


-- | Check that a 'PubKeyXO' is the result of the specified tweak operation. @True@ means it was.
pubKeyXOTweakAddCheck :: PubKeyXO -> Bool -> PubKeyXO -> Tweak -> Bool
pubKeyXOTweakAddCheck :: PubKeyXO -> Bool -> PubKeyXO -> Tweak -> Bool
pubKeyXOTweakAddCheck PubKeyXO{pubKeyXOFPtr :: PubKeyXO -> ForeignPtr XonlyPubkey64
pubKeyXOFPtr = ForeignPtr XonlyPubkey64
tweakedFPtr} Bool
parity PubKeyXO{pubKeyXOFPtr :: PubKeyXO -> ForeignPtr XonlyPubkey64
pubKeyXOFPtr = ForeignPtr XonlyPubkey64
origFPtr} Tweak{ForeignPtr Tweak32
tweakFPtr :: ForeignPtr Tweak32
tweakFPtr :: Tweak -> ForeignPtr Tweak32
..} =
    IO Bool -> Bool
forall a. IO a -> a
unsafePerformIO (IO Bool -> Bool)
-> (ContT Bool IO Bool -> IO Bool) -> ContT Bool IO Bool -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ContT Bool IO Bool -> IO Bool
forall (m :: * -> *) r. Monad m => ContT r m r -> m r
evalContT (ContT Bool IO Bool -> Bool) -> ContT Bool IO Bool -> Bool
forall a b. (a -> b) -> a -> b
$ do
        Ptr XonlyPubkey64
tweakedPtr <- ((Ptr XonlyPubkey64 -> IO Bool) -> IO Bool)
-> ContT Bool IO (Ptr XonlyPubkey64)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (ForeignPtr XonlyPubkey64
-> (Ptr XonlyPubkey64 -> IO Bool) -> IO Bool
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr XonlyPubkey64
tweakedFPtr)
        Ptr XonlyPubkey64
origPtr <- ((Ptr XonlyPubkey64 -> IO Bool) -> IO Bool)
-> ContT Bool IO (Ptr XonlyPubkey64)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (ForeignPtr XonlyPubkey64
-> (Ptr XonlyPubkey64 -> IO Bool) -> IO Bool
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr XonlyPubkey64
origFPtr)
        Ptr Tweak32
tweakPtr <- ((Ptr Tweak32 -> IO Bool) -> IO Bool)
-> ContT Bool IO (Ptr Tweak32)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (ForeignPtr Tweak32 -> (Ptr Tweak32 -> IO Bool) -> IO Bool
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Tweak32
tweakFPtr)
        let parityInt :: Ret
parityInt = if Bool
parity then Ret
1 else Ret
0
        IO Bool -> ContT Bool IO Bool
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (IO Bool -> ContT Bool IO Bool) -> IO Bool -> ContT Bool IO Bool
forall a b. (a -> b) -> a -> b
$ Ret -> Bool
isSuccess (Ret -> Bool) -> IO Ret -> IO Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ctx
-> Ptr XonlyPubkey64
-> Ret
-> Ptr XonlyPubkey64
-> Ptr Tweak32
-> IO Ret
Prim.xonlyPubkeyTweakAddCheck Ctx
ctx Ptr XonlyPubkey64
tweakedPtr Ret
parityInt Ptr XonlyPubkey64
origPtr Ptr Tweak32
tweakPtr


foreign import ccall "wrapper"
    mkNonceFunHardened :: Prim.NonceFunHardened a -> IO (FunPtr (Prim.NonceFunHardened a))