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 #6147

Closed
wants to merge 2 commits 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
3 changes: 2 additions & 1 deletion cabal.project
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ index-state:
-- Bump both the following dates if you need newer packages from Hackage
, hackage.haskell.org 2024-01-08T22:38:30Z
-- Bump this if you need newer packages from CHaP
, cardano-haskell-packages 2024-01-16T11:00:00Z
, cardano-haskell-packages 2024-06-03T14:31:53Z

packages: doc/read-the-docs-site
plutus-benchmark
Expand Down Expand Up @@ -82,3 +82,4 @@ allow-newer:
, inline-r:bytestring
, inline-r:containers
, inline-r:primitive

6 changes: 3 additions & 3 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 5 additions & 4 deletions nix/project.nix
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# editorconfig-checker-disable-file
# editorconfig-checker-disable-file

{ repoRoot, inputs, pkgs, system, lib }:

Expand All @@ -8,7 +8,7 @@ let
{
name = "plutus";

# We need the mkDefault here since compiler-nix-name will be overridden
# We need the mkDefault here since compiler-nix-name will be overridden
# in the flake variants.
compiler-nix-name = lib.mkDefault "ghc96";

Expand Down Expand Up @@ -37,6 +37,7 @@ let

sha256map = {
"https://github.com/jaccokrijnen/plutus-cert"."e814b9171398cbdfecdc6823067156a7e9fc76a3" = "0srqvx0b819b5crrbsa9hz2fnr50ahqizvvm0wdmyq2bbpk2rka7";
"https://github.com/paluh/cardano-base"."ea31e27ae4c9715232fa20e2e91f23e5bd967d65" = "sha256-R/uqcScLbkFhYL8x0FL7eQ2UIJY30o6ec312I/E7KdU=";
};

# TODO: move this into the cabalib.project using the new conditional support?
Expand All @@ -58,7 +59,7 @@ let

modules = [

# Cross Compiling
# Cross Compiling
(lib.mkIf isCrossCompiling {
packages = {
# Things that need plutus-tx-plugin
Expand All @@ -77,7 +78,7 @@ let
reinstallableLibGhc = false;
})

# Common
# Common
{
packages = {
# Packages we just don't want docs for
Expand Down
2 changes: 1 addition & 1 deletion plutus-benchmark/plutus-benchmark.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ library marlowe-internal
build-depends:
, base
, bytestring
, cardano-crypto-class >=2.0.0.1 && <2.3
, cardano-crypto-class >=2.1.5 && <2.3
, directory
, filepath
, mtl
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
-- Test vector (0-bit input) for Ripemd_160.
-- Output obtained using the online tool https://emn178.github.io/online-tools/ripemd_160.html
(program 1.0.0
[
[
(builtin equalsByteString)
[
(builtin ripemd_160)
(con bytestring #)
]
]
(con bytestring #9c1185a5c5e9fc54612808977ee8f548b2258d31)
]
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
({cpu: 2388508
| mem: 805})
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
(program 1.0.0 (con bool True))
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
-- Test vector (0-bit input) for Ripemd_160.
-- Output obtained using the online tool https://emn178.github.io/online-tools/ripemd_160.html
(program 1.0.0
[
[
(builtin equalsByteString)
[
(builtin ripemd_160)
(con bytestring #2e7ea84da4bc4d7cfb463e3f2c8647057afff3fbececa1d200)
]
]
(con bytestring #f18921115370b049e99dfdd49fc92b371dd7c7e9)
]
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
({cpu: 2636077
| mem: 805})
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
(program 1.0.0 (con bool True))
Copy link
Contributor

Choose a reason for hiding this comment

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

JFYI: I advocate for not using golden file machinery for programs that are expected to evaluate to a simple value like boolean True and instead verify expected result directly in the test code.

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'm happy to refactor this out if that is the way to go. Could you please point me to a place where I should put such a test case?

Copy link
Contributor

Choose a reason for hiding this comment

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

JFYI: I advocate for not using golden file machinery for programs that are expected to evaluate to a simple value like boolean True and instead verify expected result directly in the test code.

I don't think that necessarily applies here. This is in the conformance tests and by design all of those are golden tests whose input and output are textual UPLC so that they can be run by other evaluators, in particular by the Agda evaluator in plutus-metatheory.

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
13 changes: 13 additions & 0 deletions plutus-core/cost-model/data/builtinCostModel.json
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
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 @@ -554,6 +555,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 @@ -764,6 +766,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 @@ -414,5 +414,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 @@ -286,7 +286,7 @@ library
, bytestring
, bytestring-strict-builder
, cardano-crypto
, cardano-crypto-class ^>=2.1.2
, cardano-crypto-class ^>=2.1.5
, cassava
, cborg
, composition-prelude >=1.1.0.1
Expand Down Expand Up @@ -433,6 +433,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)
15 changes: 15 additions & 0 deletions plutus-core/plutus-core/src/PlutusCore/Default/Builtins.hs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ data DefaultFun
-- Conversions
| IntegerToByteString
| ByteStringToInteger
-- Ripemd_160
| Ripemd_160
deriving stock (Show, Eq, Ord, Enum, Bounded, Generic, Ix)
deriving anyclass (NFData, Hashable, PrettyBy PrettyConfigPlc)

Expand Down Expand Up @@ -1820,6 +1822,16 @@ instance uni ~ DefaultUni => ToBuiltinMeaning uni DefaultFun where
in makeBuiltinMeaning
byteStringToIntegerDenotation
(runCostingFunTwoArguments . paramByteStringToInteger)

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 @@ -1947,6 +1959,8 @@ instance Flat DefaultFun where
IntegerToByteString -> 73
ByteStringToInteger -> 74

Ripemd_160 -> 75

decode = go =<< decodeBuiltin
where go 0 = pure AddInteger
go 1 = pure SubtractInteger
Expand Down Expand Up @@ -2023,6 +2037,7 @@ instance Flat DefaultFun where
go 72 = pure Blake2b_224
go 73 = pure IntegerToByteString
go 74 = pure ByteStringToInteger
go 75 = 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 @@ -162,6 +162,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 @@ -234,5 +234,7 @@ unitCostBuiltinCostModel = BuiltinCostModelBase
-- Bitwise operations
, paramIntegerToByteString = unitCostThreeArguments
, paramByteStringToInteger = unitCostTwoArguments
-- Ripemd_160
, paramRipemd_160 = unitCostOneArgument
}

Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,9 @@
"keccak_256-cpu-arguments-intercept": 1927926,
"keccak_256-cpu-arguments-slope": 82523,
"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
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 @@ -49,10 +49,13 @@ import Evaluation.Builtins.SignatureVerification (ecdsaSecp256k1Prop, ed25519_Va

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 Hedgehog hiding (Opaque, Size, Var)
import Hedgehog.Gen qualified as Gen
import Hedgehog.Range qualified as Range
Expand Down Expand Up @@ -670,6 +673,14 @@ test_Crypto = testCase "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 @@ -749,11 +760,12 @@ test_HashSize hashFun expectedNumBits =
test_HashSizes :: TestTree
test_HashSizes =
testGroup "Hash sizes"
[ test_HashSize Sha2_256 256
, test_HashSize Sha3_256 256
, test_HashSize Blake2b_256 256
, test_HashSize Keccak_256 256
, test_HashSize Blake2b_224 224
[ test_HashSize Sha2_256 256
, test_HashSize Sha3_256 256
, 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 @@ -117,7 +117,8 @@ builtinsIntroducedIn = Map.fromList [
Bls12_381_G2_equal, Bls12_381_G2_hashToGroup,
Bls12_381_G2_compress, Bls12_381_G2_uncompress,
Bls12_381_millerLoop, Bls12_381_mulMlResult, Bls12_381_finalVerify,
Keccak_256, Blake2b_224, IntegerToByteString, ByteStringToInteger
Keccak_256, Blake2b_224, IntegerToByteString, ByteStringToInteger,
Ripemd_160
])
]

Expand Down
Loading