{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeApplications #-}
module PlutusCore.Crypto.Secp256k1 (
verifyEcdsaSecp256k1Signature,
verifySchnorrSecp256k1Signature
) where
import PlutusCore.Builtin.Result
import PlutusCore.Crypto.Utils
import Cardano.Crypto.DSIGN.Class qualified as DSIGN
import Cardano.Crypto.DSIGN.EcdsaSecp256k1 (EcdsaSecp256k1DSIGN, toMessageHash)
import Cardano.Crypto.DSIGN.SchnorrSecp256k1 (SchnorrSecp256k1DSIGN)
import Data.ByteString qualified as BS
import Data.Text (Text)
verifyEcdsaSecp256k1Signature
:: BS.ByteString
-> BS.ByteString
-> BS.ByteString
-> BuiltinResult Bool
verifyEcdsaSecp256k1Signature :: ByteString -> ByteString -> ByteString -> BuiltinResult Bool
verifyEcdsaSecp256k1Signature ByteString
pk ByteString
msg ByteString
sig =
case forall v. DSIGNAlgorithm v => ByteString -> Maybe (VerKeyDSIGN v)
DSIGN.rawDeserialiseVerKeyDSIGN @EcdsaSecp256k1DSIGN ByteString
pk of
Maybe (VerKeyDSIGN EcdsaSecp256k1DSIGN)
Nothing -> Text -> Text -> BuiltinResult Bool
forall a. Text -> Text -> BuiltinResult a
failWithMessage Text
loc Text
"Invalid verification key."
Just VerKeyDSIGN EcdsaSecp256k1DSIGN
pk' -> case forall v. DSIGNAlgorithm v => ByteString -> Maybe (SigDSIGN v)
DSIGN.rawDeserialiseSigDSIGN @EcdsaSecp256k1DSIGN ByteString
sig of
Maybe (SigDSIGN EcdsaSecp256k1DSIGN)
Nothing -> Text -> Text -> BuiltinResult Bool
forall a. Text -> Text -> BuiltinResult a
failWithMessage Text
loc Text
"Invalid signature."
Just SigDSIGN EcdsaSecp256k1DSIGN
sig' -> case ByteString -> Maybe MessageHash
toMessageHash ByteString
msg of
Maybe MessageHash
Nothing -> Text -> Text -> BuiltinResult Bool
forall a. Text -> Text -> BuiltinResult a
failWithMessage Text
loc Text
"Invalid message hash."
Just MessageHash
msg' -> Bool -> BuiltinResult Bool
forall a. a -> BuiltinResult a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bool -> BuiltinResult Bool) -> Bool -> BuiltinResult Bool
forall a b. (a -> b) -> a -> b
$ case ContextDSIGN EcdsaSecp256k1DSIGN
-> VerKeyDSIGN EcdsaSecp256k1DSIGN
-> MessageHash
-> SigDSIGN EcdsaSecp256k1DSIGN
-> Either String ()
forall v a.
(DSIGNAlgorithm v, Signable v a, HasCallStack) =>
ContextDSIGN v
-> VerKeyDSIGN v -> a -> SigDSIGN v -> Either String ()
forall a.
(Signable EcdsaSecp256k1DSIGN a, HasCallStack) =>
ContextDSIGN EcdsaSecp256k1DSIGN
-> VerKeyDSIGN EcdsaSecp256k1DSIGN
-> a
-> SigDSIGN EcdsaSecp256k1DSIGN
-> Either String ()
DSIGN.verifyDSIGN () VerKeyDSIGN EcdsaSecp256k1DSIGN
pk' MessageHash
msg' SigDSIGN EcdsaSecp256k1DSIGN
sig' of
Left String
_ -> Bool
False
Right () -> Bool
True
where
loc :: Text
loc :: Text
loc = Text
"ECDSA SECP256k1 signature verification"
verifySchnorrSecp256k1Signature
:: BS.ByteString
-> BS.ByteString
-> BS.ByteString
-> BuiltinResult Bool
verifySchnorrSecp256k1Signature :: ByteString -> ByteString -> ByteString -> BuiltinResult Bool
verifySchnorrSecp256k1Signature ByteString
pk ByteString
msg ByteString
sig =
case forall v. DSIGNAlgorithm v => ByteString -> Maybe (VerKeyDSIGN v)
DSIGN.rawDeserialiseVerKeyDSIGN @SchnorrSecp256k1DSIGN ByteString
pk of
Maybe (VerKeyDSIGN SchnorrSecp256k1DSIGN)
Nothing -> Text -> Text -> BuiltinResult Bool
forall a. Text -> Text -> BuiltinResult a
failWithMessage Text
loc Text
"Invalid verification key."
Just VerKeyDSIGN SchnorrSecp256k1DSIGN
pk' -> case forall v. DSIGNAlgorithm v => ByteString -> Maybe (SigDSIGN v)
DSIGN.rawDeserialiseSigDSIGN @SchnorrSecp256k1DSIGN ByteString
sig of
Maybe (SigDSIGN SchnorrSecp256k1DSIGN)
Nothing -> Text -> Text -> BuiltinResult Bool
forall a. Text -> Text -> BuiltinResult a
failWithMessage Text
loc Text
"Invalid signature."
Just SigDSIGN SchnorrSecp256k1DSIGN
sig' -> Bool -> BuiltinResult Bool
forall a. a -> BuiltinResult a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bool -> BuiltinResult Bool) -> Bool -> BuiltinResult Bool
forall a b. (a -> b) -> a -> b
$ case ContextDSIGN SchnorrSecp256k1DSIGN
-> VerKeyDSIGN SchnorrSecp256k1DSIGN
-> ByteString
-> SigDSIGN SchnorrSecp256k1DSIGN
-> Either String ()
forall v a.
(DSIGNAlgorithm v, Signable v a, HasCallStack) =>
ContextDSIGN v
-> VerKeyDSIGN v -> a -> SigDSIGN v -> Either String ()
forall a.
(Signable SchnorrSecp256k1DSIGN a, HasCallStack) =>
ContextDSIGN SchnorrSecp256k1DSIGN
-> VerKeyDSIGN SchnorrSecp256k1DSIGN
-> a
-> SigDSIGN SchnorrSecp256k1DSIGN
-> Either String ()
DSIGN.verifyDSIGN () VerKeyDSIGN SchnorrSecp256k1DSIGN
pk' ByteString
msg SigDSIGN SchnorrSecp256k1DSIGN
sig' of
Left String
_ -> Bool
False
Right () -> Bool
True
where
loc :: Text
loc :: Text
loc = Text
"Schnorr SECP256k1 signature verification"