content: {-# LANGUAGE DataKinds #-}
  {-# LANGUAGE NoImplicitPrelude #-}
  {-# LANGUAGE TemplateHaskell #-}
  {-# LANGUAGE TypeApplications #-}
  {-# LANGUAGE TypeFamilies #-}
  
  -- PlutusV2 must be compiled using plc 1.0
  {-# OPTIONS_GHC -fplugin-opt PlutusTx.Plugin:target-version=1.0.0 #-}
  
  module Cardano.Benchmarking.PlutusScripts.EcdsaSecp256k1Loop (script) where
  
  import           Cardano.Api (PlutusScript (..), PlutusScriptV2, PlutusScriptVersion (..),
                     Script (..), toScriptInAnyLang)
  
  import           Cardano.Benchmarking.ScriptAPI
  import qualified PlutusLedgerApi.V2 as PlutusV2
  
  import           Prelude as Haskell (String, (.), (<$>))
  
  import qualified Data.ByteString.Short as SBS
  
  import           Language.Haskell.TH
  import           Language.Haskell.TH.Syntax
  import qualified PlutusTx
  import qualified PlutusTx.Builtins as BI
  import           PlutusTx.Prelude as P hiding (Semigroup (..), (.), (<$>))
  
  
  scriptName :: Haskell.String
  scriptName
    = prepareScriptName $(LitE . StringL . loc_module <$> qLocation)
  
  script :: PlutusBenchScript
  script = mkPlutusBenchScript scriptName (toScriptInAnyLang (PlutusScript PlutusScriptV2 scriptSerialized))
  
  
  {-# INLINEABLE mkValidator #-}
  mkValidator :: BuiltinData -> BuiltinData -> BuiltinData -> ()
  mkValidator _datum red _txContext =
    case PlutusV2.fromBuiltinData red of
      Nothing -> P.traceError "Trace error: Invalid redeemer"
      Just (n, vkey, msg, sig) ->
        if n < (1000000 :: Integer) -- large number ensures same bitsize for all counter values
        then traceError "redeemer is < 1000000"
        else loop n vkey msg sig
    where
      loop i v m s
        | i == 1000000 = ()
        | BI.verifyEcdsaSecp256k1Signature v m s = loop (pred i) v m s
        | otherwise = P.traceError "Trace error: ECDSA validation failed"
  
  v2EcdsaLoopScriptShortBs :: SBS.ShortByteString
  v2EcdsaLoopScriptShortBs = PlutusV2.serialiseCompiledCode $$(PlutusTx.compile [|| mkValidator ||])
  
  scriptSerialized :: PlutusScript PlutusScriptV2
  scriptSerialized = PlutusScriptSerialised v2EcdsaLoopScriptShortBs
  