{-# LANGUAGE DataKinds #-} {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} {-# OPTIONS_GHC -fplugin PlutusTx.Plugin #-} {-# OPTIONS_GHC -fplugin-opt PlutusTx.Plugin:defer-errors #-} -- | Verify-gate validator (Plutus V3). -- -- A minimal spending validator whose ONLY job is to run the real -- commitment-aware Groth16 verifier ('groth16VerifyCommitted') against: -- -- * a verifying key @vk@ (672 B) and public input @pub@ (32 B) baked in at -- deploy time as the applied parameter, and -- * a proof @p@ (336 B) supplied at spend time as the redeemer. -- -- The UTxO at this script's address is spendable iff the proof verifies under -- the baked-in (vk, pub). The node runs the pairing check as phase-2 -- validation: a valid proof => the spend succeeds; a tampered proof => a -- BLS12-381 builtin errors => the script fails => no spend (collateral -- forfeit). -- -- Parameter encoding (applied at deploy time): -- paramsData = toBuiltinData ((vk, pub) :: (BuiltinByteString, BuiltinByteString)) -- = Constr 0 [B vk, B pub] -- Redeemer encoding (supplied at spend time): -- redeemer = B p -- the raw 336-byte proof bytes, as a Data bytestring module Gate (mkGate, compiledGate) where import PlutusTx import PlutusTx.Prelude import qualified PlutusTx.Builtins as B import PlutusTx.Builtins.Internal (BuiltinUnit) import PlutusLedgerApi.V3 (ScriptContext (..), Redeemer (..)) import Recovery.Types (VerifyingKey (..), Proof (..), Scalar (..)) import Recovery.Verify (groth16VerifyCommitted) -- | V3 validator. First argument is the Data-encoded (vk, pub) parameter -- (applied at deploy time); second is the ScriptContext supplied by the -- ledger. The proof is read from the spending redeemer (a Data bytestring). {-# INLINABLE mkGate #-} mkGate :: BuiltinData -> BuiltinData -> BuiltinUnit mkGate paramsData ctxData = let (vk, pub) = unsafeFromBuiltinData paramsData :: (BuiltinByteString, BuiltinByteString) ctx = unsafeFromBuiltinData ctxData :: ScriptContext proofData = getRedeemer (scriptContextRedeemer ctx) proof = B.unsafeDataAsB proofData in check (groth16VerifyCommitted (VerifyingKey vk) (Proof proof) (Scalar pub)) -- | PlutusTx-compiled UPLC validator. Apply 'compiledGate' to the Data-encoded -- (vk, pub) parameter to obtain the deployable @BuiltinData -> BuiltinUnit@. compiledGate :: CompiledCode (BuiltinData -> BuiltinData -> BuiltinUnit) compiledGate = $$(compile [|| mkGate ||])