Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new builtin hashing function ripemd_160 #6252

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion plutus-benchmark/plutus-benchmark.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ builtinCostModelNames = BuiltinCostModelBase
, paramKeccak_256 = "keccak_256Model"
, paramIntegerToByteString = "integerToByteStringModel"
, paramByteStringToInteger = "byteStringToIntegerModel"
, paramRipemd_160 = "ripemd_160Model"
}


Expand Down Expand Up @@ -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 {..}

Expand Down
26 changes: 26 additions & 0 deletions plutus-core/cost-model/data/builtinCostModelA.json
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,19 @@
"type": "constant_cost"
}
},
"ripemd_160": {
"cpu": {
"arguments": {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You must have run the benchmarks to get these numbers. Which machine did you run them on?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kwxm - unfortunately I did not benchmark this as I stated above:

This draft contains an artificial costing model for the new builtin - I copied keccak_256 related values for now.

That is for sure missing part :-( Sorry for the confusion.

"intercept": 1927926,
"slope": 82523
},
"type": "linear_in_x"
},
"memory": {
"arguments": 4,
"type": "constant_cost"
}
},
"lengthOfByteString": {
"cpu": {
"arguments": 1000,
Expand Down Expand Up @@ -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": {
Expand Down
13 changes: 13 additions & 0 deletions plutus-core/cost-model/data/builtinCostModelB.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down
15 changes: 14 additions & 1 deletion plutus-core/cost-model/data/builtinCostModelC.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down Expand Up @@ -952,4 +965,4 @@
"type": "constant_cost"
}
}
}
}
5 changes: 4 additions & 1 deletion plutus-core/cost-model/data/models.R
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,8 @@ arity <- function(name) {
"Keccak_256" = 1,
"Blake2b_224" = 1,
"IntegerToByteString" = 3,
"ByteStringToInteger" = 2
"ByteStringToInteger" = 2,
"Ripemd_160" = 1
)
}

Expand Down Expand Up @@ -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 #####

Expand Down Expand Up @@ -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,
Expand Down
3 changes: 3 additions & 0 deletions plutus-core/cost-model/test/TestCostModels.hs
Original file line number Diff line number Diff line change
Expand Up @@ -417,5 +417,8 @@ main =
-- Bitwise operations
, $(genTest 3 "integerToByteString")
, $(genTest 2 "byteStringToInteger") Everywhere

-- Ripemd_160
, $(genTest 1 "ripemd_160")
]

3 changes: 2 additions & 1 deletion plutus-core/plutus-core.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -440,6 +440,7 @@ test-suite untyped-plutus-core-test

build-depends:
, base >=4.9 && <5
, base16-bytestring
, bytestring
, cardano-crypto-class
, dlist
Expand Down
6 changes: 6 additions & 0 deletions plutus-core/plutus-core/src/PlutusCore/Crypto/Hash.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
14 changes: 14 additions & 0 deletions plutus-core/plutus-core/src/PlutusCore/Default/Builtins.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -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 #-}

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bytestring -> bytestring
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ isCommutative = \case
Blake2b_224 -> False
Blake2b_256 -> False
Keccak_256 -> False
Ripemd_160 -> False
VerifyEd25519Signature -> False
VerifyEcdsaSecp256k1Signature -> False
VerifySchnorrSecp256k1Signature -> False
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,5 +140,6 @@ typedBuiltins
. insertBuiltin Blake2b_224
. insertBuiltin Blake2b_256
. insertBuiltin Keccak_256
. insertBuiltin Ripemd_160
. insertBuiltin EqualsByteString
$ DenotationContext mempty
2 changes: 1 addition & 1 deletion plutus-core/testlib/PlutusCore/Generators/NEAT/Term.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 ])
Expand Down Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion plutus-ledger-api/src/PlutusLedgerApi/Common/Versions.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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
])
]

Expand Down
3 changes: 3 additions & 0 deletions plutus-ledger-api/src/PlutusLedgerApi/V3/ParamName.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
2 changes: 1 addition & 1 deletion plutus-ledger-api/test/Spec/CostModelParams.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
6 changes: 5 additions & 1 deletion plutus-ledger-api/test/Spec/Versions.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not totally sure if ripemd160 should be in here, but these tests need to be reworked anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can drop it if you wish :-)

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
Expand Down Expand Up @@ -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"]
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,5 @@ clearBuiltinCostModel r = r
, paramBls12_381_finalVerify = mempty
, paramKeccak_256 = mempty
, paramBlake2b_224 = mempty
, paramRipemd_160 = mempty
}
1 change: 1 addition & 0 deletions plutus-metatheory/src/Algorithmic/CEK.lagda.md
Original file line number Diff line number Diff line change
Expand Up @@ -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))))
Expand Down
Loading