{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeApplications #-}
module PlutusCore.Crypto.Ed25519 (
verifyEd25519Signature_V1,
verifyEd25519Signature_V2
) where
import PlutusCore.Builtin.KnownType (BuiltinResult)
import PlutusCore.Crypto.Utils
import Cardano.Crypto.DSIGN.Class qualified as DSIGN
import Cardano.Crypto.DSIGN.Ed25519 (Ed25519DSIGN)
import Crypto.ECC.Ed25519Donna (publicKey, signature, verify)
import Crypto.Error (CryptoFailable (..))
import Data.ByteString qualified as BS
import Data.Text (Text, pack)
verifyEd25519Signature_V1
:: BS.ByteString
-> BS.ByteString
-> BS.ByteString
-> BuiltinResult Bool
verifyEd25519Signature_V1 :: ByteString -> ByteString -> ByteString -> BuiltinResult Bool
verifyEd25519Signature_V1 ByteString
pubKey ByteString
msg ByteString
sig =
case PublicKey -> ByteString -> Signature -> Bool
forall ba.
ByteArrayAccess ba =>
PublicKey -> ba -> Signature -> Bool
verify
(PublicKey -> ByteString -> Signature -> Bool)
-> CryptoFailable PublicKey
-> CryptoFailable (ByteString -> Signature -> Bool)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ByteString -> CryptoFailable PublicKey
forall ba. ByteArrayAccess ba => ba -> CryptoFailable PublicKey
publicKey ByteString
pubKey
CryptoFailable (ByteString -> Signature -> Bool)
-> CryptoFailable ByteString -> CryptoFailable (Signature -> Bool)
forall a b.
CryptoFailable (a -> b) -> CryptoFailable a -> CryptoFailable b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ByteString -> CryptoFailable ByteString
forall a. a -> CryptoFailable a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ByteString
msg
CryptoFailable (Signature -> Bool)
-> CryptoFailable Signature -> CryptoFailable Bool
forall a b.
CryptoFailable (a -> b) -> CryptoFailable a -> CryptoFailable b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ByteString -> CryptoFailable Signature
forall ba. ByteArrayAccess ba => ba -> CryptoFailable Signature
signature ByteString
sig
of CryptoPassed Bool
r -> Bool -> BuiltinResult Bool
forall a. a -> BuiltinResult a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
r
CryptoFailed CryptoError
err -> Text -> Text -> BuiltinResult Bool
forall a. Text -> Text -> BuiltinResult a
failWithMessage Text
loc (Text -> BuiltinResult Bool) -> Text -> BuiltinResult Bool
forall a b. (a -> b) -> a -> b
$ String -> Text
pack (CryptoError -> String
forall a. Show a => a -> String
show CryptoError
err)
where
loc :: Text
loc :: Text
loc = Text
"Ed25519 signature verification"
verifyEd25519Signature_V2
:: BS.ByteString
-> BS.ByteString
-> BS.ByteString
-> BuiltinResult Bool
verifyEd25519Signature_V2 :: ByteString -> ByteString -> ByteString -> BuiltinResult Bool
verifyEd25519Signature_V2 ByteString
pk ByteString
msg ByteString
sig =
case forall v. DSIGNAlgorithm v => ByteString -> Maybe (VerKeyDSIGN v)
DSIGN.rawDeserialiseVerKeyDSIGN @Ed25519DSIGN ByteString
pk of
Maybe (VerKeyDSIGN Ed25519DSIGN)
Nothing -> Text -> Text -> BuiltinResult Bool
forall a. Text -> Text -> BuiltinResult a
failWithMessage Text
loc Text
"Invalid verification key."
Just VerKeyDSIGN Ed25519DSIGN
pk' -> case forall v. DSIGNAlgorithm v => ByteString -> Maybe (SigDSIGN v)
DSIGN.rawDeserialiseSigDSIGN @Ed25519DSIGN ByteString
sig of
Maybe (SigDSIGN Ed25519DSIGN)
Nothing -> Text -> Text -> BuiltinResult Bool
forall a. Text -> Text -> BuiltinResult a
failWithMessage Text
loc Text
"Invalid signature."
Just SigDSIGN Ed25519DSIGN
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 Ed25519DSIGN
-> VerKeyDSIGN Ed25519DSIGN
-> ByteString
-> SigDSIGN Ed25519DSIGN
-> Either String ()
forall v a.
(DSIGNAlgorithm v, Signable v a, HasCallStack) =>
ContextDSIGN v
-> VerKeyDSIGN v -> a -> SigDSIGN v -> Either String ()
forall a.
(Signable Ed25519DSIGN a, HasCallStack) =>
ContextDSIGN Ed25519DSIGN
-> VerKeyDSIGN Ed25519DSIGN
-> a
-> SigDSIGN Ed25519DSIGN
-> Either String ()
DSIGN.verifyDSIGN () VerKeyDSIGN Ed25519DSIGN
pk' ByteString
msg SigDSIGN Ed25519DSIGN
sig' of
Left String
_ -> Bool
False
Right () -> Bool
True
where
loc :: Text
loc :: Text
loc = Text
"Ed25519 signature verification"