From bc88e3777f49ac0b07c530b75d94b35d1fa18717 Mon Sep 17 00:00:00 2001 From: Tomasz Rybarczyk Date: Mon, 27 May 2024 12:17:58 +0200 Subject: [PATCH] Introduce ripemd_160 with artifical cost model (temp keccak_256 copy) --- plutus-benchmark/plutus-benchmark.cabal | 2 +- .../budgeting-bench/Benchmarks/Crypto.hs | 2 +- .../create-cost-model/BuiltinMemoryModels.hs | 1 + .../CreateBuiltinCostModel.hs | 3 +++ .../cost-model/data/builtinCostModelA.json | 26 +++++++++++++++++++ .../cost-model/data/builtinCostModelB.json | 13 ++++++++++ .../cost-model/data/builtinCostModelC.json | 15 ++++++++++- plutus-core/cost-model/data/models.R | 5 +++- plutus-core/cost-model/test/TestCostModels.hs | 3 +++ plutus-core/plutus-core.cabal | 3 ++- .../plutus-core/src/PlutusCore/Crypto/Hash.hs | 6 +++++ .../src/PlutusCore/Default/Builtins.hs | 14 ++++++++++ .../Evaluation/Machine/BuiltinCostModel.hs | 2 ++ .../Evaluation/Machine/ExBudgetingDefaults.hs | 2 ++ .../defaultCostModelParams.json | 3 +++ .../Golden/DefaultFun/Ripemd_160.plc.golden | 1 + .../RewriteRules/CommuteFnWithConst.hs | 1 + .../Generators/Hedgehog/Denotation.hs | 1 + .../PlutusCore/Generators/NEAT/Term.hs | 2 +- .../test/Evaluation/Builtins/Definition.hs | 12 +++++++++ .../src/PlutusLedgerApi/Common/Versions.hs | 3 ++- .../src/PlutusLedgerApi/V3/ParamName.hs | 3 +++ .../test/Spec/CostModelParams.hs | 2 +- plutus-ledger-api/test/Spec/Versions.hs | 6 ++++- .../Test/V3/EvaluationContext.hs | 1 + .../src/Algorithmic/CEK.lagda.md | 1 + plutus-metatheory/src/Builtin.lagda.md | 7 +++++ plutus-metatheory/src/Untyped/CEK.lagda.md | 4 +++ .../src/PlutusTx/Compiler/Builtins.hs | 2 ++ plutus-tx/src/PlutusTx/Builtins.hs | 6 +++++ plutus-tx/src/PlutusTx/Builtins/Internal.hs | 4 +++ plutus-tx/src/PlutusTx/Prelude.hs | 5 ++-- 32 files changed, 150 insertions(+), 11 deletions(-) create mode 100644 plutus-core/plutus-core/test/TypeSynthesis/Golden/DefaultFun/Ripemd_160.plc.golden diff --git a/plutus-benchmark/plutus-benchmark.cabal b/plutus-benchmark/plutus-benchmark.cabal index 1505932a0f0..25c1b3b048f 100644 --- a/plutus-benchmark/plutus-benchmark.cabal +++ b/plutus-benchmark/plutus-benchmark.cabal @@ -471,7 +471,7 @@ library marlowe-internal build-depends: , base , bytestring - , cardano-crypto-class >=2.0.0.1 && <2.2 + , cardano-crypto-class >=2.1.5 && <2.2 , directory , filepath , mtl diff --git a/plutus-core/cost-model/budgeting-bench/Benchmarks/Crypto.hs b/plutus-core/cost-model/budgeting-bench/Benchmarks/Crypto.hs index fab8b7ce884..7afe1b4f672 100644 --- a/plutus-core/cost-model/budgeting-bench/Benchmarks/Crypto.hs +++ b/plutus-core/cost-model/budgeting-bench/Benchmarks/Crypto.hs @@ -317,5 +317,5 @@ makeBenchmarks gen = [ benchVerifyEd25519Signature , benchVerifyEcdsaSecp256k1Signature , benchVerifySchnorrSecp256k1Signature ] - <> (benchByteStringOneArgOp <$> [Sha2_256, Sha3_256, Blake2b_224, Blake2b_256, Keccak_256]) + <> (benchByteStringOneArgOp <$> [Sha2_256, Sha3_256, Blake2b_224, Blake2b_256, Keccak_256, Ripemd_160]) <> blsBenchmarks gen diff --git a/plutus-core/cost-model/create-cost-model/BuiltinMemoryModels.hs b/plutus-core/cost-model/create-cost-model/BuiltinMemoryModels.hs index f796c7aa4c4..457328b53c9 100644 --- a/plutus-core/cost-model/create-cost-model/BuiltinMemoryModels.hs +++ b/plutus-core/cost-model/create-cost-model/BuiltinMemoryModels.hs @@ -150,4 +150,5 @@ builtinMemoryModels = BuiltinCostModelBase -- a special memory costing function to handle that. , paramIntegerToByteString = Id $ ModelThreeArgumentsLiteralInYOrLinearInZ $ OneVariableLinearFunction 0 1 , paramByteStringToInteger = Id $ ModelTwoArgumentsLinearInY $ OneVariableLinearFunction 0 1 + , paramRipemd_160 = Id $ hashMemModel Hash.ripemd_160 } diff --git a/plutus-core/cost-model/create-cost-model/CreateBuiltinCostModel.hs b/plutus-core/cost-model/create-cost-model/CreateBuiltinCostModel.hs index 4b09e138fc2..df93f906607 100644 --- a/plutus-core/cost-model/create-cost-model/CreateBuiltinCostModel.hs +++ b/plutus-core/cost-model/create-cost-model/CreateBuiltinCostModel.hs @@ -112,6 +112,7 @@ builtinCostModelNames = BuiltinCostModelBase , paramKeccak_256 = "keccak_256Model" , paramIntegerToByteString = "integerToByteStringModel" , paramByteStringToInteger = "byteStringToIntegerModel" + , paramRipemd_160 = "ripemd_160Model" } @@ -238,6 +239,8 @@ createBuiltinCostModel bmfile rfile = do -- Bitwise operations paramByteStringToInteger <- getParams readCF2 paramByteStringToInteger paramIntegerToByteString <- getParams readCF3 paramIntegerToByteString + -- And another hash function + paramRipemd_160 <- getParams readCF1 paramRipemd_160 pure $ BuiltinCostModelBase {..} diff --git a/plutus-core/cost-model/data/builtinCostModelA.json b/plutus-core/cost-model/data/builtinCostModelA.json index b775ce272af..b6d05efdfa4 100644 --- a/plutus-core/cost-model/data/builtinCostModelA.json +++ b/plutus-core/cost-model/data/builtinCostModelA.json @@ -527,6 +527,19 @@ "type": "constant_cost" } }, + "ripemd_160": { + "cpu": { + "arguments": { + "intercept": 1927926, + "slope": 82523 + }, + "type": "linear_in_x" + }, + "memory": { + "arguments": 4, + "type": "constant_cost" + } + }, "lengthOfByteString": { "cpu": { "arguments": 1000, @@ -721,6 +734,19 @@ "type": "subtracted_sizes" } }, + "ripemd_160": { + "cpu": { + "arguments": { + "intercept": 2261318, + "slope": 64571 + }, + "type": "linear_in_x" + }, + "memory": { + "arguments": 4, + "type": "constant_cost" + } + }, "remainderInteger": { "cpu": { "arguments": { diff --git a/plutus-core/cost-model/data/builtinCostModelB.json b/plutus-core/cost-model/data/builtinCostModelB.json index 40bdbf94f5f..2245cd2f05a 100644 --- a/plutus-core/cost-model/data/builtinCostModelB.json +++ b/plutus-core/cost-model/data/builtinCostModelB.json @@ -721,6 +721,19 @@ "type": "subtracted_sizes" } }, + "ripemd_160": { + "cpu": { + "arguments": { + "intercept": 2261318, + "slope": 64571 + }, + "type": "linear_in_x" + }, + "memory": { + "arguments": 4, + "type": "constant_cost" + } + }, "remainderInteger": { "cpu": { "arguments": { diff --git a/plutus-core/cost-model/data/builtinCostModelC.json b/plutus-core/cost-model/data/builtinCostModelC.json index 8c7fc158bad..df68591e287 100644 --- a/plutus-core/cost-model/data/builtinCostModelC.json +++ b/plutus-core/cost-model/data/builtinCostModelC.json @@ -735,6 +735,19 @@ "type": "subtracted_sizes" } }, + "ripemd_160": { + "cpu": { + "arguments": { + "intercept": 2261318, + "slope": 64571 + }, + "type": "linear_in_x" + }, + "memory": { + "arguments": 4, + "type": "constant_cost" + } + }, "remainderInteger": { "cpu": { "arguments": { @@ -952,4 +965,4 @@ "type": "constant_cost" } } -} \ No newline at end of file +} diff --git a/plutus-core/cost-model/data/models.R b/plutus-core/cost-model/data/models.R index 86162b36873..c245de65d5d 100644 --- a/plutus-core/cost-model/data/models.R +++ b/plutus-core/cost-model/data/models.R @@ -131,7 +131,8 @@ arity <- function(name) { "Keccak_256" = 1, "Blake2b_224" = 1, "IntegerToByteString" = 3, - "ByteStringToInteger" = 2 + "ByteStringToInteger" = 2, + "Ripemd_160" = 1 ) } @@ -558,6 +559,7 @@ modelFun <- function(path) { blake2b_224Model <- linearInX ("Blake2b_224") blake2b_256Model <- linearInX ("Blake2b_256") keccak_256Model <- linearInX ("Keccak_256") + ripemd_160Model <- linearInX ("Ripemd_160") ###### Signature verification ##### @@ -765,6 +767,7 @@ modelFun <- function(path) { blake2b_224Model = blake2b_224Model, blake2b_256Model = blake2b_256Model, keccak_256Model = keccak_256Model, + ripemd_160Model = ripemd_160Model, verifyEd25519SignatureModel = verifyEd25519SignatureModel, verifyEcdsaSecp256k1SignatureModel = verifyEcdsaSecp256k1SignatureModel, verifySchnorrSecp256k1SignatureModel = verifySchnorrSecp256k1SignatureModel, diff --git a/plutus-core/cost-model/test/TestCostModels.hs b/plutus-core/cost-model/test/TestCostModels.hs index 5e446022687..4ac0efc6793 100644 --- a/plutus-core/cost-model/test/TestCostModels.hs +++ b/plutus-core/cost-model/test/TestCostModels.hs @@ -417,5 +417,8 @@ main = -- Bitwise operations , $(genTest 3 "integerToByteString") , $(genTest 2 "byteStringToInteger") Everywhere + + -- Ripemd_160 + , $(genTest 1 "ripemd_160") ] diff --git a/plutus-core/plutus-core.cabal b/plutus-core/plutus-core.cabal index b7f98202df9..ca998b789e5 100644 --- a/plutus-core/plutus-core.cabal +++ b/plutus-core/plutus-core.cabal @@ -290,7 +290,7 @@ library , bytestring , bytestring-strict-builder , cardano-crypto - , cardano-crypto-class ^>=2.1 + , cardano-crypto-class ^>=2.1.5 , cassava , cborg , composition-prelude >=1.1.0.1 @@ -440,6 +440,7 @@ test-suite untyped-plutus-core-test build-depends: , base >=4.9 && <5 + , base16-bytestring , bytestring , cardano-crypto-class , dlist diff --git a/plutus-core/plutus-core/src/PlutusCore/Crypto/Hash.hs b/plutus-core/plutus-core/src/PlutusCore/Crypto/Hash.hs index c956927be49..9d311f60e58 100644 --- a/plutus-core/plutus-core/src/PlutusCore/Crypto/Hash.hs +++ b/plutus-core/plutus-core/src/PlutusCore/Crypto/Hash.hs @@ -6,11 +6,13 @@ module PlutusCore.Crypto.Hash , blake2b_224 , blake2b_256 , keccak_256 + , ripemd_160 ) where import Cardano.Crypto.Hash.Blake2b import Cardano.Crypto.Hash.Class import Cardano.Crypto.Hash.Keccak256 +import Cardano.Crypto.Hash.RIPEMD160 import Cardano.Crypto.Hash.SHA256 import Cardano.Crypto.Hash.SHA3_256 import Data.ByteString qualified as BS @@ -35,3 +37,7 @@ blake2b_256 = digest (Proxy @Blake2b_256) -- | Hash a `ByteString` using the Keccak-256 hash function. keccak_256 :: BS.ByteString -> BS.ByteString keccak_256 = digest (Proxy @Keccak256) + +-- | Hash a `ByteString` using the RIPEMD-160 hash function. +ripemd_160 :: BS.ByteString -> BS.ByteString +ripemd_160 = digest (Proxy @RIPEMD160) diff --git a/plutus-core/plutus-core/src/PlutusCore/Default/Builtins.hs b/plutus-core/plutus-core/src/PlutusCore/Default/Builtins.hs index e4a51c5e2d0..43e31a96009 100644 --- a/plutus-core/plutus-core/src/PlutusCore/Default/Builtins.hs +++ b/plutus-core/plutus-core/src/PlutusCore/Default/Builtins.hs @@ -165,6 +165,8 @@ data DefaultFun | RotateByteString | CountSetBits | FindFirstSetBit + -- Ripemd_160 + | Ripemd_160 deriving stock (Show, Eq, Ord, Enum, Bounded, Generic, Ix) deriving anyclass (NFData, Hashable, PrettyBy PrettyConfigPlc) @@ -1971,6 +1973,15 @@ instance uni ~ DefaultUni => ToBuiltinMeaning uni DefaultFun where findFirstSetBitDenotation (runCostingFunOneArgument . unimplementedCostingFun) + toBuiltinMeaning _semvar Ripemd_160 = + let ripemd_160Denotation :: BS.ByteString -> BS.ByteString + ripemd_160Denotation = Hash.ripemd_160 + {-# INLINE ripemd_160Denotation #-} + in makeBuiltinMeaning + ripemd_160Denotation + (runCostingFunOneArgument . paramRipemd_160) + + -- See Note [Inlining meanings of builtins]. {-# INLINE toBuiltinMeaning #-} @@ -2111,6 +2122,8 @@ instance Flat DefaultFun where CountSetBits -> 84 FindFirstSetBit -> 85 + Ripemd_160 -> 86 + decode = go =<< decodeBuiltin where go 0 = pure AddInteger go 1 = pure SubtractInteger @@ -2198,6 +2211,7 @@ instance Flat DefaultFun where go 83 = pure RotateByteString go 84 = pure CountSetBits go 85 = pure FindFirstSetBit + go 86 = pure Ripemd_160 go t = fail $ "Failed to decode builtin tag, got: " ++ show t size _ n = n + builtinTagWidth diff --git a/plutus-core/plutus-core/src/PlutusCore/Evaluation/Machine/BuiltinCostModel.hs b/plutus-core/plutus-core/src/PlutusCore/Evaluation/Machine/BuiltinCostModel.hs index 39c4169d34e..b8050fdb4a8 100644 --- a/plutus-core/plutus-core/src/PlutusCore/Evaluation/Machine/BuiltinCostModel.hs +++ b/plutus-core/plutus-core/src/PlutusCore/Evaluation/Machine/BuiltinCostModel.hs @@ -169,6 +169,8 @@ data BuiltinCostModelBase f = -- Bitwise operations , paramIntegerToByteString :: f ModelThreeArguments , paramByteStringToInteger :: f ModelTwoArguments + -- Ripemd_160 + , paramRipemd_160 :: f ModelOneArgument } deriving stock (Generic) deriving anyclass (FunctorB, TraversableB, ConstraintsB) diff --git a/plutus-core/plutus-core/src/PlutusCore/Evaluation/Machine/ExBudgetingDefaults.hs b/plutus-core/plutus-core/src/PlutusCore/Evaluation/Machine/ExBudgetingDefaults.hs index 2f4d119c813..02358bdf5b5 100644 --- a/plutus-core/plutus-core/src/PlutusCore/Evaluation/Machine/ExBudgetingDefaults.hs +++ b/plutus-core/plutus-core/src/PlutusCore/Evaluation/Machine/ExBudgetingDefaults.hs @@ -330,6 +330,8 @@ unitCostBuiltinCostModel = BuiltinCostModelBase -- Bitwise operations , paramIntegerToByteString = unitCostThreeArguments , paramByteStringToInteger = unitCostTwoArguments + -- Ripemd_160 + , paramRipemd_160 = unitCostOneArgument } unitCekParameters :: Typeable ann => MachineParameters CekMachineCosts DefaultFun (CekValue DefaultUni DefaultFun ann) diff --git a/plutus-core/plutus-core/test/CostModelInterface/defaultCostModelParams.json b/plutus-core/plutus-core/test/CostModelInterface/defaultCostModelParams.json index ac8d35742ce..c20336b0342 100644 --- a/plutus-core/plutus-core/test/CostModelInterface/defaultCostModelParams.json +++ b/plutus-core/plutus-core/test/CostModelInterface/defaultCostModelParams.json @@ -144,6 +144,9 @@ "keccak_256-cpu-arguments-intercept": 2261318, "keccak_256-cpu-arguments-slope": 64571, "keccak_256-memory-arguments": 4, + "ripemd_160-cpu-arguments-intercept": 1927926, + "ripemd_160-cpu-arguments-slope": 82523, + "ripemd_160-memory-arguments": 4, "lengthOfByteString-cpu-arguments": 1000, "lengthOfByteString-memory-arguments": 10, "lessThanByteString-cpu-arguments-intercept": 197145, diff --git a/plutus-core/plutus-core/test/TypeSynthesis/Golden/DefaultFun/Ripemd_160.plc.golden b/plutus-core/plutus-core/test/TypeSynthesis/Golden/DefaultFun/Ripemd_160.plc.golden new file mode 100644 index 00000000000..770236177ca --- /dev/null +++ b/plutus-core/plutus-core/test/TypeSynthesis/Golden/DefaultFun/Ripemd_160.plc.golden @@ -0,0 +1 @@ +bytestring -> bytestring \ No newline at end of file diff --git a/plutus-core/plutus-ir/src/PlutusIR/Transform/RewriteRules/CommuteFnWithConst.hs b/plutus-core/plutus-ir/src/PlutusIR/Transform/RewriteRules/CommuteFnWithConst.hs index 0424128e68f..dbb70ed0541 100644 --- a/plutus-core/plutus-ir/src/PlutusIR/Transform/RewriteRules/CommuteFnWithConst.hs +++ b/plutus-core/plutus-ir/src/PlutusIR/Transform/RewriteRules/CommuteFnWithConst.hs @@ -79,6 +79,7 @@ isCommutative = \case Blake2b_224 -> False Blake2b_256 -> False Keccak_256 -> False + Ripemd_160 -> False VerifyEd25519Signature -> False VerifyEcdsaSecp256k1Signature -> False VerifySchnorrSecp256k1Signature -> False diff --git a/plutus-core/testlib/PlutusCore/Generators/Hedgehog/Denotation.hs b/plutus-core/testlib/PlutusCore/Generators/Hedgehog/Denotation.hs index dfebec2c7f9..3dbf0e7fd20 100644 --- a/plutus-core/testlib/PlutusCore/Generators/Hedgehog/Denotation.hs +++ b/plutus-core/testlib/PlutusCore/Generators/Hedgehog/Denotation.hs @@ -140,5 +140,6 @@ typedBuiltins . insertBuiltin Blake2b_224 . insertBuiltin Blake2b_256 . insertBuiltin Keccak_256 + . insertBuiltin Ripemd_160 . insertBuiltin EqualsByteString $ DenotationContext mempty diff --git a/plutus-core/testlib/PlutusCore/Generators/NEAT/Term.hs b/plutus-core/testlib/PlutusCore/Generators/NEAT/Term.hs index 67323f53617..8b748b7d810 100644 --- a/plutus-core/testlib/PlutusCore/Generators/NEAT/Term.hs +++ b/plutus-core/testlib/PlutusCore/Generators/NEAT/Term.hs @@ -399,7 +399,7 @@ defaultFunTypes = Map.fromList [(TyFunG (TyBuiltinG TyIntegerG) (TyFunG (TyBuilt ,(TyFunG (TyBuiltinG TyByteStringG) (TyFunG (TyBuiltinG TyIntegerG) (TyBuiltinG TyIntegerG)) ,[IndexByteString]) ,(TyFunG (TyBuiltinG TyByteStringG) (TyBuiltinG TyByteStringG) - ,[Sha2_256,Sha3_256,Blake2b_224,Blake2b_256,Keccak_256]) + ,[Sha2_256,Sha3_256,Blake2b_224,Blake2b_256,Keccak_256,Ripemd_160]) ,(TyFunG (TyBuiltinG TyByteStringG) (TyFunG (TyBuiltinG TyByteStringG) (TyFunG (TyBuiltinG TyByteStringG) (TyBuiltinG TyBoolG))) ,[VerifyEd25519Signature]) ,(TyFunG (TyBuiltinG TyByteStringG) (TyFunG (TyBuiltinG TyByteStringG) (TyBuiltinG TyBoolG)) diff --git a/plutus-core/untyped-plutus-core/test/Evaluation/Builtins/Definition.hs b/plutus-core/untyped-plutus-core/test/Evaluation/Builtins/Definition.hs index fab83cf11a4..f80b8398ac2 100644 --- a/plutus-core/untyped-plutus-core/test/Evaluation/Builtins/Definition.hs +++ b/plutus-core/untyped-plutus-core/test/Evaluation/Builtins/Definition.hs @@ -45,10 +45,13 @@ import PlutusCore.StdLib.Data.Unit import Control.Exception import Data.ByteString (ByteString, pack) +import Data.ByteString.Base16 qualified as Base16 import Data.DList qualified as DList import Data.Proxy import Data.String (IsString (fromString)) import Data.Text (Text) +import Data.Text qualified as Text +import Data.Text.Encoding qualified as Text import Evaluation.Builtins.BLS12_381 (test_BLS12_381) import Evaluation.Builtins.Common import Evaluation.Builtins.Conversion qualified as Conversion @@ -751,6 +754,14 @@ test_Crypto = testNestedM "Crypto" $ do -- hex output: 47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad evals @ByteString "G\ETB2\133\168\215\&4\RS^\151/\198w(c\132\248\STX\248\239B\165\236_\ETX\187\250%L\176\US\173" Keccak_256 [] [cons @ByteString "hello world"] + -- independently verified by the calculator at https://emn178.github.io/online-tools/ripemd_160.html + let + hashHex = "98c615784ccb5fe5936fbc0cbe9dfdb408d92f0f" + ripemd_160Hash = case Base16.decode $ Text.encodeUtf8 hashHex of + Right res -> res + Left _ -> error $ "Unexpected error during hex decoding: " <> Text.unpack hashHex + evals @ByteString ripemd_160Hash + Ripemd_160 [] [cons @ByteString "hello world"] -- Tests for blake2b_224: output obtained using the b2sum program from https://github.com/BLAKE2/BLAKE2 evals (pack [ 0x83, 0x6c, 0xc6, 0x89, 0x31, 0xc2, 0xe4, 0xe3, 0xe8, 0x38, 0x60, 0x2e, 0xca, 0x19 , 0x02, 0x59, 0x1d, 0x21, 0x68, 0x37, 0xba, 0xfd, 0xdf, 0xe6, 0xf0, 0xc8, 0xcb, 0x07 ]) @@ -835,6 +846,7 @@ test_HashSizes = , test_HashSize Blake2b_256 256 , test_HashSize Keccak_256 256 , test_HashSize Blake2b_224 224 + , test_HashSize Ripemd_160 160 ] -- Test all remaining builtins of the default universe diff --git a/plutus-ledger-api/src/PlutusLedgerApi/Common/Versions.hs b/plutus-ledger-api/src/PlutusLedgerApi/Common/Versions.hs index bdec21ac37d..14028368ac4 100644 --- a/plutus-ledger-api/src/PlutusLedgerApi/Common/Versions.hs +++ b/plutus-ledger-api/src/PlutusLedgerApi/Common/Versions.hs @@ -122,7 +122,8 @@ builtinsIntroducedIn = Map.fromList [ ((PlutusV3, futurePV), Set.fromList [ AndByteString, OrByteString, XorByteString, ComplementByteString, ReadBit, WriteBits, ReplicateByte, - ShiftByteString, RotateByteString, CountSetBits, FindFirstSetBit + ShiftByteString, RotateByteString, CountSetBits, FindFirstSetBit, + Ripemd_160 ]) ] diff --git a/plutus-ledger-api/src/PlutusLedgerApi/V3/ParamName.hs b/plutus-ledger-api/src/PlutusLedgerApi/V3/ParamName.hs index 68186fd1c59..73ba3adc844 100644 --- a/plutus-ledger-api/src/PlutusLedgerApi/V3/ParamName.hs +++ b/plutus-ledger-api/src/PlutusLedgerApi/V3/ParamName.hs @@ -266,5 +266,8 @@ data ParamName = | ByteStringToInteger'cpu'arguments'c2 | ByteStringToInteger'memory'arguments'intercept | ByteStringToInteger'memory'arguments'slope + | Ripemd_160'cpu'arguments'intercept + | Ripemd_160'cpu'arguments'slope + | Ripemd_160'memory'arguments deriving stock (Eq, Ord, Enum, Ix, Bounded, Generic) deriving IsParamName via (GenericParamName ParamName) diff --git a/plutus-ledger-api/test/Spec/CostModelParams.hs b/plutus-ledger-api/test/Spec/CostModelParams.hs index 7298c0d8a1c..f63425a0844 100644 --- a/plutus-ledger-api/test/Spec/CostModelParams.hs +++ b/plutus-ledger-api/test/Spec/CostModelParams.hs @@ -28,7 +28,7 @@ tests = [ testCase "length" $ do 166 @=? length v1_ParamNames 185 @=? length v2_ParamNames - 251 @=? length v3_ParamNames + 254 @=? length v3_ParamNames , testCase "tripping paramname" $ do for_ v1_ParamNames $ \ p -> assertBool "tripping v1 cm params failed" $ Just p == readParamName (showParamName p) diff --git a/plutus-ledger-api/test/Spec/Versions.hs b/plutus-ledger-api/test/Spec/Versions.hs index 61b180ea852..a437590aa1f 100644 --- a/plutus-ledger-api/test/Spec/Versions.hs +++ b/plutus-ledger-api/test/Spec/Versions.hs @@ -76,7 +76,7 @@ testBuiltinVersions = testGroup "builtins" assertBool "not in l2,Vasil" $ isRight $ V2.deserialiseScript vasilPV serialiseDataExScript assertBool "not in l3,future" $ isRight $ V3.deserialiseScript futurePV serialiseDataExScript , testCase "bls,keccak256,blake2b224 only available in l3,Future and after" $ - for_ [blsExScript, keccak256ExScript, blake2b224ExScript] $ \script -> do + for_ [blsExScript, keccak256ExScript, blake2b224ExScript, ripemd160ExScript] $ \script -> do assertBool "in l1,Alonzo" $ isLeft $ V1.deserialiseScript alonzoPV script assertBool "in l1,Vasil" $ isLeft $ V1.deserialiseScript vasilPV script assertBool "in l2,Alonzo" $ isLeft $ V2.deserialiseScript alonzoPV script @@ -148,3 +148,7 @@ keccak256ExScript = serialiseUPLC $ UPLC.Program () PLC.plcVersion100 $ blake2b224ExScript :: SerialisedScript blake2b224ExScript = serialiseUPLC $ UPLC.Program () PLC.plcVersion100 $ builtin () Blake2b_224 @@ [mkConstant @BS.ByteString () "hashme"] + +ripemd160ExScript :: SerialisedScript +ripemd160ExScript = serialiseUPLC $ UPLC.Program () PLC.plcVersion100 $ + builtin () Ripemd_160 @@ [mkConstant @BS.ByteString () "hashme"] diff --git a/plutus-ledger-api/testlib/PlutusLedgerApi/Test/V3/EvaluationContext.hs b/plutus-ledger-api/testlib/PlutusLedgerApi/Test/V3/EvaluationContext.hs index ff71a2c514e..ca71dc0db1d 100644 --- a/plutus-ledger-api/testlib/PlutusLedgerApi/Test/V3/EvaluationContext.hs +++ b/plutus-ledger-api/testlib/PlutusLedgerApi/Test/V3/EvaluationContext.hs @@ -67,4 +67,5 @@ clearBuiltinCostModel r = r , paramBls12_381_finalVerify = mempty , paramKeccak_256 = mempty , paramBlake2b_224 = mempty + , paramRipemd_160 = mempty } diff --git a/plutus-metatheory/src/Algorithmic/CEK.lagda.md b/plutus-metatheory/src/Algorithmic/CEK.lagda.md index 321dae4a290..18930234d91 100644 --- a/plutus-metatheory/src/Algorithmic/CEK.lagda.md +++ b/plutus-metatheory/src/Algorithmic/CEK.lagda.md @@ -222,6 +222,7 @@ BUILTIN sha3-256 (base $ V-con b) = inj₂ (V-con (SHA3-256 b)) BUILTIN blake2b-224 (base $ V-con b) = inj₂ (V-con (BLAKE2B-224 b)) BUILTIN blake2b-256 (base $ V-con b) = inj₂ (V-con (BLAKE2B-256 b)) BUILTIN keccak-256 (base $ V-con b) = inj₂ (V-con (KECCAK-256 b)) +BUILTIN ripemd-160 (base $ V-con b) = inj₂ (V-con (RIPEMD-160 b)) BUILTIN verifyEd25519Signature (base $ V-con k $ V-con d $ V-con c) with (verifyEd25519Sig k d c) ... | just b = inj₂ (V-con b) ... | nothing = inj₁ (con (ne (^ (atomic aBool)))) diff --git a/plutus-metatheory/src/Builtin.lagda.md b/plutus-metatheory/src/Builtin.lagda.md index ac170bb5e2c..cf011fe6d59 100644 --- a/plutus-metatheory/src/Builtin.lagda.md +++ b/plutus-metatheory/src/Builtin.lagda.md @@ -132,6 +132,8 @@ data Builtin : Set where -- Bitwise operations byteStringToInteger : Builtin integerToByteString : Builtin + -- Ripemd-160 + ripemd-160 : Builtin ``` ## Signatures @@ -248,6 +250,7 @@ sig n⋆ n♯ (t₃ ∷ t₂ ∷ t₁) tᵣ signature blake2b-224 = ∙ [ bytestring ↑ ]⟶ bytestring ↑ signature blake2b-256 = ∙ [ bytestring ↑ ]⟶ bytestring ↑ signature keccak-256 = ∙ [ bytestring ↑ ]⟶ bytestring ↑ + signature ripemd-160 = ∙ [ bytestring ↑ ]⟶ bytestring ↑ signature verifyEd25519Signature = ∙ [ bytestring ↑ , bytestring ↑ , bytestring ↑ ]⟶ bool ↑ signature verifyEcdsaSecp256k1Signature = ∙ [ bytestring ↑ , bytestring ↑ , bytestring ↑ ]⟶ bool ↑ signature verifySchnorrSecp256k1Signature = ∙ [ bytestring ↑ , bytestring ↑ , bytestring ↑ ]⟶ bool ↑ @@ -390,6 +393,7 @@ Each Agda built-in name must be mapped to a Haskell name. | Blake2b_224 | ByteStringToInteger | IntegerToByteString + | Ripemd_160 ) #-} ``` @@ -445,6 +449,7 @@ postulate BLAKE2B-224 : ByteString → ByteString BStoI : Bool -> ByteString -> Int ItoBS : Bool -> Int -> Int -> Maybe ByteString + RIPEMD-160 : ByteString → ByteString ``` ### What builtin operations should be compiled to if we compile to Haskell @@ -539,6 +544,8 @@ postulate {-# COMPILE GHC BStoI = Convert.byteStringToIntegerWrapper #-} {-# COMPILE GHC ItoBS = \e w n -> builtinResultToMaybe $ Convert.integerToByteStringWrapper e w n #-} +{-# COMPILE GHC RIPEMD-160 = Hash.ripemd_160 #-} + -- no binding needed for appendStr -- no binding needed for traceStr ``` diff --git a/plutus-metatheory/src/Untyped/CEK.lagda.md b/plutus-metatheory/src/Untyped/CEK.lagda.md index f3915779ca4..92ab21b240f 100644 --- a/plutus-metatheory/src/Untyped/CEK.lagda.md +++ b/plutus-metatheory/src/Untyped/CEK.lagda.md @@ -506,6 +506,10 @@ BUILTIN integerToByteString = λ } ; _ -> inj₁ userError } +BUILTIN ripemd-160 = λ + { (app base (V-con bytestring b)) -> inj₂ (V-con bytestring (RIPEMD-160 b)) + ; _ -> inj₁ userError + } -- Take an apparently more general index and show that it is a fully applied builtin. mkFullyAppliedBuiltin : ∀ { b } diff --git a/plutus-tx-plugin/src/PlutusTx/Compiler/Builtins.hs b/plutus-tx-plugin/src/PlutusTx/Compiler/Builtins.hs index 297f3297d41..45078c4ca8c 100644 --- a/plutus-tx-plugin/src/PlutusTx/Compiler/Builtins.hs +++ b/plutus-tx-plugin/src/PlutusTx/Compiler/Builtins.hs @@ -172,6 +172,7 @@ builtinNames = [ , 'Builtins.blake2b_224 , 'Builtins.blake2b_256 , 'Builtins.keccak_256 + , 'Builtins.ripemd_160 , 'Builtins.equalsByteString , 'Builtins.lessThanByteString , 'Builtins.lessThanEqualsByteString @@ -362,6 +363,7 @@ defineBuiltinTerms = do PLC.Blake2b_224 -> defineBuiltinInl 'Builtins.blake2b_224 PLC.Blake2b_256 -> defineBuiltinInl 'Builtins.blake2b_256 PLC.Keccak_256 -> defineBuiltinInl 'Builtins.keccak_256 + PLC.Ripemd_160 -> defineBuiltinInl 'Builtins.ripemd_160 PLC.EqualsByteString -> defineBuiltinInl 'Builtins.equalsByteString PLC.LessThanByteString -> defineBuiltinInl 'Builtins.lessThanByteString PLC.LessThanEqualsByteString -> defineBuiltinInl 'Builtins.lessThanEqualsByteString diff --git a/plutus-tx/src/PlutusTx/Builtins.hs b/plutus-tx/src/PlutusTx/Builtins.hs index fdbe67fe750..04b6a619627 100644 --- a/plutus-tx/src/PlutusTx/Builtins.hs +++ b/plutus-tx/src/PlutusTx/Builtins.hs @@ -20,6 +20,7 @@ module PlutusTx.Builtins ( , blake2b_224 , blake2b_256 , keccak_256 + , ripemd_160 , verifyEd25519Signature , verifyEcdsaSecp256k1Signature , verifySchnorrSecp256k1Signature @@ -193,6 +194,11 @@ blake2b_256 = BI.blake2b_256 keccak_256 :: BuiltinByteString -> BuiltinByteString keccak_256 = BI.keccak_256 +{-# INLINABLE ripemd_160 #-} +-- | The RIPEMD-160 hash of a 'ByteString' +ripemd_160 :: BuiltinByteString -> BuiltinByteString +ripemd_160 = BI.ripemd_160 + {-# INLINABLE verifyEd25519Signature #-} -- | Ed25519 signature verification. Verify that the signature is a signature of -- the message by the public key. This will fail if key or the signature are not diff --git a/plutus-tx/src/PlutusTx/Builtins/Internal.hs b/plutus-tx/src/PlutusTx/Builtins/Internal.hs index 37844dd4f57..a11a9b45dbc 100644 --- a/plutus-tx/src/PlutusTx/Builtins/Internal.hs +++ b/plutus-tx/src/PlutusTx/Builtins/Internal.hs @@ -254,6 +254,10 @@ blake2b_256 (BuiltinByteString b) = BuiltinByteString $ Hash.blake2b_256 b keccak_256 :: BuiltinByteString -> BuiltinByteString keccak_256 (BuiltinByteString b) = BuiltinByteString $ Hash.keccak_256 b +{-# NOINLINE ripemd_160 #-} +ripemd_160 :: BuiltinByteString -> BuiltinByteString +ripemd_160 (BuiltinByteString b) = BuiltinByteString $ Hash.ripemd_160 b + {-# NOINLINE verifyEd25519Signature #-} verifyEd25519Signature :: BuiltinByteString -> BuiltinByteString -> BuiltinByteString -> BuiltinBool verifyEd25519Signature (BuiltinByteString vk) (BuiltinByteString msg) (BuiltinByteString sig) = diff --git a/plutus-tx/src/PlutusTx/Prelude.hs b/plutus-tx/src/PlutusTx/Prelude.hs index 2c430615079..55b114fb033 100644 --- a/plutus-tx/src/PlutusTx/Prelude.hs +++ b/plutus-tx/src/PlutusTx/Prelude.hs @@ -72,6 +72,7 @@ module PlutusTx.Prelude ( blake2b_224, blake2b_256, keccak_256, + ripemd_160, verifyEd25519Signature, verifyEcdsaSecp256k1Signature, verifySchnorrSecp256k1Signature, @@ -137,8 +138,8 @@ import PlutusTx.Builtins (BuiltinBLS12_381_G1_Element, BuiltinBLS12_381_G2_Eleme emptyByteString, emptyString, encodeUtf8, equalsByteString, equalsString, error, fromBuiltin, fromOpaque, greaterThanByteString, indexByteString, integerToByteString, keccak_256, lengthOfByteString, lessThanByteString, - sha2_256, sha3_256, sliceByteString, toBuiltin, toOpaque, trace, - verifyEcdsaSecp256k1Signature, verifyEd25519Signature, + ripemd_160, sha2_256, sha3_256, sliceByteString, toBuiltin, toOpaque, + trace, verifyEcdsaSecp256k1Signature, verifyEd25519Signature, verifySchnorrSecp256k1Signature) import PlutusTx.Builtins qualified as Builtins