From a002f08d386c2ba8ff71adc4c2968abb3a46da04 Mon Sep 17 00:00:00 2001 From: zeme Date: Wed, 1 Jul 2026 13:59:12 +0200 Subject: [PATCH 1/4] wip --- cfree-plinth-flag-demo.sh | 209 ++++++++++++++++++ plinth-template | 1 + plutus-core/plutus-core.cabal | 67 +++++- .../src/PlutusCore/Crypto/BLS12_381/G1.hs | 108 ++++++++- .../src/PlutusCore/Crypto/BLS12_381/G2.hs | 107 ++++++++- .../PlutusCore/Crypto/BLS12_381/Pairing.hs | 49 +++- .../src/PlutusCore/Crypto/Ed25519.hs | 11 +- .../plutus-core/src/PlutusCore/Crypto/Hash.hs | 58 +++-- .../src/PlutusCore/Crypto/Secp256k1.hs | 16 +- .../src/PlutusCore/Crypto/Utils.hs | 37 ++++ plutus-core/test-crypto-hash-parity/Spec.hs | 68 ++++++ .../golden/blake2b_224-abc.golden | 1 + .../golden/blake2b_224-allbytes.golden | 1 + .../golden/blake2b_224-byte00.golden | 1 + .../golden/blake2b_224-byteff.golden | 1 + .../golden/blake2b_224-empty.golden | 1 + .../golden/blake2b_224-fox.golden | 1 + .../golden/blake2b_224-len1000.golden | 1 + .../golden/blake2b_224-len127.golden | 1 + .../golden/blake2b_224-len128.golden | 1 + .../golden/blake2b_224-len129.golden | 1 + .../golden/blake2b_224-len135.golden | 1 + .../golden/blake2b_224-len136.golden | 1 + .../golden/blake2b_224-len137.golden | 1 + .../golden/blake2b_224-len55.golden | 1 + .../golden/blake2b_224-len56.golden | 1 + .../golden/blake2b_224-len63.golden | 1 + .../golden/blake2b_224-len64.golden | 1 + .../golden/blake2b_224-len65.golden | 1 + .../golden/blake2b_224-pseudorandom333.golden | 1 + .../golden/blake2b_256-abc.golden | 1 + .../golden/blake2b_256-allbytes.golden | 1 + .../golden/blake2b_256-byte00.golden | 1 + .../golden/blake2b_256-byteff.golden | 1 + .../golden/blake2b_256-empty.golden | 1 + .../golden/blake2b_256-fox.golden | 1 + .../golden/blake2b_256-len1000.golden | 1 + .../golden/blake2b_256-len127.golden | 1 + .../golden/blake2b_256-len128.golden | 1 + .../golden/blake2b_256-len129.golden | 1 + .../golden/blake2b_256-len135.golden | 1 + .../golden/blake2b_256-len136.golden | 1 + .../golden/blake2b_256-len137.golden | 1 + .../golden/blake2b_256-len55.golden | 1 + .../golden/blake2b_256-len56.golden | 1 + .../golden/blake2b_256-len63.golden | 1 + .../golden/blake2b_256-len64.golden | 1 + .../golden/blake2b_256-len65.golden | 1 + .../golden/blake2b_256-pseudorandom333.golden | 1 + .../golden/keccak_256-abc.golden | 1 + .../golden/keccak_256-allbytes.golden | 1 + .../golden/keccak_256-byte00.golden | 1 + .../golden/keccak_256-byteff.golden | 1 + .../golden/keccak_256-empty.golden | 1 + .../golden/keccak_256-fox.golden | 1 + .../golden/keccak_256-len1000.golden | 1 + .../golden/keccak_256-len127.golden | 1 + .../golden/keccak_256-len128.golden | 1 + .../golden/keccak_256-len129.golden | 1 + .../golden/keccak_256-len135.golden | 1 + .../golden/keccak_256-len136.golden | 1 + .../golden/keccak_256-len137.golden | 1 + .../golden/keccak_256-len55.golden | 1 + .../golden/keccak_256-len56.golden | 1 + .../golden/keccak_256-len63.golden | 1 + .../golden/keccak_256-len64.golden | 1 + .../golden/keccak_256-len65.golden | 1 + .../golden/keccak_256-pseudorandom333.golden | 1 + .../golden/ripemd_160-abc.golden | 1 + .../golden/ripemd_160-allbytes.golden | 1 + .../golden/ripemd_160-byte00.golden | 1 + .../golden/ripemd_160-byteff.golden | 1 + .../golden/ripemd_160-empty.golden | 1 + .../golden/ripemd_160-fox.golden | 1 + .../golden/ripemd_160-len1000.golden | 1 + .../golden/ripemd_160-len127.golden | 1 + .../golden/ripemd_160-len128.golden | 1 + .../golden/ripemd_160-len129.golden | 1 + .../golden/ripemd_160-len135.golden | 1 + .../golden/ripemd_160-len136.golden | 1 + .../golden/ripemd_160-len137.golden | 1 + .../golden/ripemd_160-len55.golden | 1 + .../golden/ripemd_160-len56.golden | 1 + .../golden/ripemd_160-len63.golden | 1 + .../golden/ripemd_160-len64.golden | 1 + .../golden/ripemd_160-len65.golden | 1 + .../golden/ripemd_160-pseudorandom333.golden | 1 + .../golden/sha2_256-abc.golden | 1 + .../golden/sha2_256-allbytes.golden | 1 + .../golden/sha2_256-byte00.golden | 1 + .../golden/sha2_256-byteff.golden | 1 + .../golden/sha2_256-empty.golden | 1 + .../golden/sha2_256-fox.golden | 1 + .../golden/sha2_256-len1000.golden | 1 + .../golden/sha2_256-len127.golden | 1 + .../golden/sha2_256-len128.golden | 1 + .../golden/sha2_256-len129.golden | 1 + .../golden/sha2_256-len135.golden | 1 + .../golden/sha2_256-len136.golden | 1 + .../golden/sha2_256-len137.golden | 1 + .../golden/sha2_256-len55.golden | 1 + .../golden/sha2_256-len56.golden | 1 + .../golden/sha2_256-len63.golden | 1 + .../golden/sha2_256-len64.golden | 1 + .../golden/sha2_256-len65.golden | 1 + .../golden/sha2_256-pseudorandom333.golden | 1 + .../golden/sha3_256-abc.golden | 1 + .../golden/sha3_256-allbytes.golden | 1 + .../golden/sha3_256-byte00.golden | 1 + .../golden/sha3_256-byteff.golden | 1 + .../golden/sha3_256-empty.golden | 1 + .../golden/sha3_256-fox.golden | 1 + .../golden/sha3_256-len1000.golden | 1 + .../golden/sha3_256-len127.golden | 1 + .../golden/sha3_256-len128.golden | 1 + .../golden/sha3_256-len129.golden | 1 + .../golden/sha3_256-len135.golden | 1 + .../golden/sha3_256-len136.golden | 1 + .../golden/sha3_256-len137.golden | 1 + .../golden/sha3_256-len55.golden | 1 + .../golden/sha3_256-len56.golden | 1 + .../golden/sha3_256-len63.golden | 1 + .../golden/sha3_256-len64.golden | 1 + .../golden/sha3_256-len65.golden | 1 + .../golden/sha3_256-pseudorandom333.golden | 1 + plutus-metatheory/plutus-metatheory.cabal | 14 ++ 126 files changed, 810 insertions(+), 49 deletions(-) create mode 100755 cfree-plinth-flag-demo.sh create mode 160000 plinth-template create mode 100644 plutus-core/test-crypto-hash-parity/Spec.hs create mode 100644 plutus-core/test-crypto-hash-parity/golden/blake2b_224-abc.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/blake2b_224-allbytes.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/blake2b_224-byte00.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/blake2b_224-byteff.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/blake2b_224-empty.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/blake2b_224-fox.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/blake2b_224-len1000.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/blake2b_224-len127.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/blake2b_224-len128.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/blake2b_224-len129.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/blake2b_224-len135.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/blake2b_224-len136.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/blake2b_224-len137.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/blake2b_224-len55.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/blake2b_224-len56.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/blake2b_224-len63.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/blake2b_224-len64.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/blake2b_224-len65.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/blake2b_224-pseudorandom333.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/blake2b_256-abc.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/blake2b_256-allbytes.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/blake2b_256-byte00.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/blake2b_256-byteff.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/blake2b_256-empty.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/blake2b_256-fox.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/blake2b_256-len1000.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/blake2b_256-len127.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/blake2b_256-len128.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/blake2b_256-len129.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/blake2b_256-len135.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/blake2b_256-len136.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/blake2b_256-len137.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/blake2b_256-len55.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/blake2b_256-len56.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/blake2b_256-len63.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/blake2b_256-len64.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/blake2b_256-len65.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/blake2b_256-pseudorandom333.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/keccak_256-abc.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/keccak_256-allbytes.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/keccak_256-byte00.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/keccak_256-byteff.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/keccak_256-empty.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/keccak_256-fox.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/keccak_256-len1000.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/keccak_256-len127.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/keccak_256-len128.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/keccak_256-len129.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/keccak_256-len135.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/keccak_256-len136.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/keccak_256-len137.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/keccak_256-len55.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/keccak_256-len56.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/keccak_256-len63.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/keccak_256-len64.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/keccak_256-len65.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/keccak_256-pseudorandom333.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/ripemd_160-abc.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/ripemd_160-allbytes.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/ripemd_160-byte00.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/ripemd_160-byteff.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/ripemd_160-empty.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/ripemd_160-fox.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/ripemd_160-len1000.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/ripemd_160-len127.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/ripemd_160-len128.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/ripemd_160-len129.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/ripemd_160-len135.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/ripemd_160-len136.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/ripemd_160-len137.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/ripemd_160-len55.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/ripemd_160-len56.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/ripemd_160-len63.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/ripemd_160-len64.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/ripemd_160-len65.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/ripemd_160-pseudorandom333.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/sha2_256-abc.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/sha2_256-allbytes.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/sha2_256-byte00.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/sha2_256-byteff.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/sha2_256-empty.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/sha2_256-fox.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/sha2_256-len1000.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/sha2_256-len127.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/sha2_256-len128.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/sha2_256-len129.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/sha2_256-len135.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/sha2_256-len136.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/sha2_256-len137.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/sha2_256-len55.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/sha2_256-len56.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/sha2_256-len63.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/sha2_256-len64.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/sha2_256-len65.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/sha2_256-pseudorandom333.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/sha3_256-abc.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/sha3_256-allbytes.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/sha3_256-byte00.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/sha3_256-byteff.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/sha3_256-empty.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/sha3_256-fox.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/sha3_256-len1000.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/sha3_256-len127.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/sha3_256-len128.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/sha3_256-len129.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/sha3_256-len135.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/sha3_256-len136.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/sha3_256-len137.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/sha3_256-len55.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/sha3_256-len56.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/sha3_256-len63.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/sha3_256-len64.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/sha3_256-len65.golden create mode 100644 plutus-core/test-crypto-hash-parity/golden/sha3_256-pseudorandom333.golden diff --git a/cfree-plinth-flag-demo.sh b/cfree-plinth-flag-demo.sh new file mode 100755 index 00000000000..0cbb5eb1b2f --- /dev/null +++ b/cfree-plinth-flag-demo.sh @@ -0,0 +1,209 @@ +#!/usr/bin/env bash +# +# cfree-plinth-flag-demo.sh +# +# Demonstrate that a Plinth script (IntersectMBO/plinth-template) can be WRITTEN +# and COMPILED with NO system cryptography C libraries (libsodium / libblst / +# libsecp256k1), in a self-contained non-nix sandbox, using ONLY the new +# `with-crypto` Cabal flag on plutus-core. +# +# Unlike the sub-library carve, the consumer makes NO source or .cabal changes: +# plinth-template depends on the ordinary plutus-core / plutus-tx / +# plutus-ledger-api / plutus-tx-plugin and merely sets +# +# package plutus-core +# flags: -with-crypto +# +# in its cabal.project. The flag drops cardano-crypto-class (and therefore the C +# libraries) from plutus-core's dependency closure; the cryptographic builtins +# become compile-only stubs. +# +# It: +# 1. Creates an isolated sandbox (its own ghcup + cabal store). +# 2. Downloads GHC 9.6.7 + cabal from ghcup (the web). +# 3. sdist's the monorepo plutus packages into a local file+noindex repo. +# 4. Clones plinth-template UNMODIFIED and adds only the -with-crypto flag. +# 5. Solves + builds, asserting cardano-crypto-class is never solved or built. +# 6. Runs the compiled validator to emit a CIP-57 blueprint. +# +# Usage: ./cfree-plinth-flag-demo.sh +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PLUTUS_REPO="${PLUTUS_REPO:-$(git -C "$SCRIPT_DIR" rev-parse --show-toplevel)}" +SANDBOX="${SANDBOX:-/tmp/plinth-flag-sandbox}" + +GHC_VERSION="${GHC_VERSION:-9.6.7}" +CABAL_VERSION="${CABAL_VERSION:-3.14.2.0}" +PLINTH_TEMPLATE_URL="https://github.com/IntersectMBO/plinth-template.git" + +# index-states matching the monorepo's cabal.project. +HACKAGE_INDEX="2026-06-22T23:30:49Z" +CHAP_INDEX="2026-06-18T17:45:00Z" + +# The monorepo packages plinth-template depends on (transitively). Only +# plutus-core carries the with-crypto flag; the rest inherit C-free-ness. +PLUTUS_PKGS=(plutus-core plutus-tx plutus-tx-plugin plutus-ledger-api) + +say() { printf '\n\033[1;36m== %s ==\033[0m\n' "$*"; } +die() { printf '\n\033[1;31mFAIL: %s\033[0m\n' "$*" >&2; exit 1; } + +# --------------------------------------------------------------------------- +# 1. Isolated sandbox +# --------------------------------------------------------------------------- +say "1. Creating isolated sandbox at $SANDBOX" +mkdir -p "$SANDBOX" +export GHCUP_INSTALL_BASE_PREFIX="$SANDBOX" +export CABAL_DIR="$SANDBOX/.cabal" +export BOOTSTRAP_HASKELL_NONINTERACTIVE=1 +export BOOTSTRAP_HASKELL_NO_UPGRADE=1 +export BOOTSTRAP_HASKELL_ADJUST_BASHRC=0 +export BOOTSTRAP_HASKELL_INSTALL_NO_STACK=1 +export BOOTSTRAP_HASKELL_GHC_VERSION="$GHC_VERSION" +export BOOTSTRAP_HASKELL_CABAL_VERSION="$CABAL_VERSION" +GHCUP_BIN="$SANDBOX/.ghcup/bin" +[ -d "$PLUTUS_REPO/plutus-core" ] || die "PLUTUS_REPO ($PLUTUS_REPO) is not the plutus monorepo" + +# --------------------------------------------------------------------------- +# 2. ghcup + GHC + cabal from the web +# --------------------------------------------------------------------------- +say "2. Installing ghcup + GHC $GHC_VERSION + cabal $CABAL_VERSION" +if [ ! -x "$GHCUP_BIN/ghcup" ]; then + curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh +fi +export PATH="$GHCUP_BIN:$PATH" +ghcup install ghc "$GHC_VERSION" --set || true +ghcup install cabal "$CABAL_VERSION" --set || true +hash -r 2>/dev/null || true +ghc --version >/dev/null 2>&1 || ghcup install ghc "$GHC_VERSION" --force --set +cabal --version >/dev/null 2>&1 || ghcup install cabal "$CABAL_VERSION" --force --set +hash -r 2>/dev/null || true +say "Toolchain:"; ghc --version; cabal --version +cabal update + +# --------------------------------------------------------------------------- +# 3. Show the host has NO crypto C libraries +# --------------------------------------------------------------------------- +say "3. System cryptography C libraries on this host" +for lib in libblst libsodium libsecp256k1; do + if command -v pkg-config >/dev/null 2>&1 && pkg-config --exists "$lib" 2>/dev/null; then + printf ' %-14s PRESENT\n' "$lib" + else + printf ' %-14s absent\n' "$lib" + fi +done +echo " (the C-free build below must not need any of them; we assert" +echo " cardano-crypto-class is never solved or built.)" + +# --------------------------------------------------------------------------- +# 4. sdist the monorepo plutus packages into a local repo +# --------------------------------------------------------------------------- +say "4. Building source tarballs of the monorepo plutus packages -> file+noindex repo" +REPO="$SANDBOX/local-plutus-repo" +rm -rf "$REPO"; mkdir -p "$REPO" +SDIST_PROJECT="$SANDBOX/cabal.project.sdist" +{ echo "packages:"; for p in "${PLUTUS_PKGS[@]}"; do echo " $PLUTUS_REPO/$p"; done; } > "$SDIST_PROJECT" +cabal sdist --project-file="$SDIST_PROJECT" "${PLUTUS_PKGS[@]}" --output-dir "$REPO" +ls -1 "$REPO"/*.tar.gz + +# --------------------------------------------------------------------------- +# 5. Clone plinth-template UNMODIFIED; add only the -with-crypto flag +# --------------------------------------------------------------------------- +say "5. Cloning plinth-template (no source/.cabal changes) and setting -with-crypto" +cd "$SANDBOX" +rm -rf plinth-template +git clone --depth 1 "$PLINTH_TEMPLATE_URL" plinth-template +cd plinth-template + +cat > cabal.project <=0.19.0.0 + +-- Mirror the monorepo cabal.project's allow-newer (needed at this index-state, +-- e.g. deriving-aeson hasn't bumped its aeson upper bound). +allow-newer: + , deriving-aeson:aeson + , microstache:aeson + , turtle:containers + , turtle:optparse-applicative +EOF + +# --------------------------------------------------------------------------- +# 6. Solve (must be crypto-free) +# --------------------------------------------------------------------------- +say "6. Checking the build plan is crypto-free" +cabal update +PLAN="$(cabal build all --dry-run 2>&1)" +echo "$PLAN" | grep -E "plutus-(core|tx|ledger-api)" || true +if echo "$PLAN" | grep -qi "cardano-crypto-class"; then + echo "$PLAN" | grep -i "cardano-crypto-class" + die "build plan pulls cardano-crypto-class -> NOT C-free" +fi +echo " -> build plan contains NO cardano-crypto-class. C-free solve confirmed." + +# --------------------------------------------------------------------------- +# 7. Build and assert cardano-crypto-class is never built +# --------------------------------------------------------------------------- +say "7. Building plinth-template (no crypto C libraries)" +BUILD_LOG="$SANDBOX/build.log" +cabal build all 2>&1 | tee "$BUILD_LOG" +grep -qiE "cardano-crypto-class.* \((lib|exe)" "$BUILD_LOG" \ + && die "cardano-crypto-class was built -> NOT C-free" || true +grep -qE "Compiling AuctionValidator" "$BUILD_LOG" \ + || die "the Plinth validator was not compiled by the plugin" +echo " -> plugin compiled the Plinth scripts; cardano-crypto-class was never built." + +# --------------------------------------------------------------------------- +# 8. Run the C-free-compiled validator: emit a CIP-57 blueprint +# --------------------------------------------------------------------------- +say "8. Running the C-free-compiled validator to emit a blueprint" +OUT="$SANDBOX/auction-blueprint.json" +cabal run -v0 gen-auction-validator-blueprint -- "$OUT" +[ -s "$OUT" ] || die "no blueprint produced" +echo " -> wrote $(wc -c < "$OUT") bytes to $OUT" +head -c 300 "$OUT"; echo + +say "SUCCESS" +cat <=1.1.0.1 @@ -368,6 +379,44 @@ library , unordered-containers , vector ^>=0.13.2 + -- The cryptographic builtins (hashes, signature verification, BLS12-381) are + -- the only part of the library that needs the C cryptography libraries, all + -- via cardano-crypto-class. When -with-crypto is set, the modules under + -- PlutusCore.Crypto compile a C-free stub instead (see Note [The with-crypto + -- flag] in PlutusCore.Crypto.Utils), so the library has no C dependency. + if flag(with-crypto) + -- >=2.3.1.0 for the bls12-381 multi-scalar-multiplication binding (blsMSM). + build-depends: cardano-crypto-class >=2.3.1.0 + cpp-options: -DWITH_CRYPTO + + else + -- C-free build: the hashes (needed at compile time) are computed with + -- crypton, which vendors its C sources and needs no system C library. + -- Pinned to the 1.0.x line, which depends on the standalone `memory` + -- package (so `Data.ByteArray.convert` has the needed instances; crypton + -- 1.1.x vendored its own byte-array and dropped that dependency). + build-depends: + , crypton ^>=1.0 + , memory + +-- Verifies the C-free (crypton) hashes are byte-identical to the +-- cardano-crypto-class hashes of the default build. Builds in BOTH flag modes +-- (it only uses the flag-gated PlutusCore.Crypto.Hash, no crypto lib directly): +-- the with-crypto build generates the goldens, the -with-crypto build checks +-- them. See Note [The with-crypto flag] in PlutusCore.Crypto.Utils. +test-suite crypto-hash-parity-test + import: lang + type: exitcode-stdio-1.0 + main-is: Spec.hs + hs-source-dirs: test-crypto-hash-parity + build-depends: + , base + , base16-bytestring + , bytestring + , plutus-core + , tasty + , tasty-golden + test-suite plutus-core-test import: lang @@ -435,6 +484,11 @@ test-suite untyped-plutus-core-test if (os(windows) || arch(wasm32)) buildable: False + -- Depends on untyped-plutus-core-testlib, which uses cardano-crypto-class and + -- is unavailable in a C-free (-with-crypto) build. See Note [The with-crypto flag]. + if !flag(with-crypto) + buildable: False + type: exitcode-stdio-1.0 main-is: Spec.hs hs-source-dirs: untyped-plutus-core/test @@ -455,6 +509,11 @@ library untyped-plutus-core-testlib if (os(windows) || arch(wasm32)) buildable: False + -- Uses cardano-crypto-class directly (signature/BLS test helpers), so it is + -- unavailable in a C-free (-with-crypto) build. See Note [The with-crypto flag]. + if !flag(with-crypto) + buildable: False + exposed-modules: Analysis.Lib Analysis.Spec @@ -814,6 +873,12 @@ library plutus-ir-cert executable cost-model-budgeting-bench import: lang main-is: Main.hs + + -- Benchmarks the cryptographic builtins, so it uses cardano-crypto-class + -- directly and is unavailable in a C-free (-with-crypto) build. + if !flag(with-crypto) + buildable: False + other-modules: Benchmarks.Arrays Benchmarks.Bitwise diff --git a/plutus-core/plutus-core/src/PlutusCore/Crypto/BLS12_381/G1.hs b/plutus-core/plutus-core/src/PlutusCore/Crypto/BLS12_381/G1.hs index c97bd17c3c1..3efae596c09 100644 --- a/plutus-core/plutus-core/src/PlutusCore/Crypto/BLS12_381/G1.hs +++ b/plutus-core/plutus-core/src/PlutusCore/Crypto/BLS12_381/G1.hs @@ -1,4 +1,5 @@ -- editorconfig-checker-disable +{-# LANGUAGE CPP #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TypeApplications #-} @@ -20,12 +21,7 @@ module PlutusCore.Crypto.BLS12_381.G1 , multiScalarMul ) where -import Cardano.Crypto.EllipticCurve.BLS12_381 qualified as BlstBindings -import Cardano.Crypto.EllipticCurve.BLS12_381.Internal qualified as BlstBindings.Internal - import PlutusCore.Builtin.Result (BuiltinResult (..)) -import PlutusCore.Crypto.BLS12_381.Bounds (msmScalarOutOfBounds) -import PlutusCore.Crypto.BLS12_381.Error (BLS12_381_Error (..)) import PlutusCore.Crypto.Utils (byteStringAsHex) import PlutusCore.Pretty.PrettyConst (ConstConfig) import Text.PrettyBy (PrettyBy) @@ -35,16 +31,26 @@ import Control.DeepSeq , rnf , rwhnf ) -import Data.ByteString - ( ByteString - , length - ) -import Data.Coerce (coerce) +import Data.ByteString (ByteString) import Data.Hashable -import Data.Proxy (Proxy (..)) import PlutusCore.Flat import Prettyprinter +#ifdef WITH_CRYPTO +import Cardano.Crypto.EllipticCurve.BLS12_381 qualified as BlstBindings +import Cardano.Crypto.EllipticCurve.BLS12_381.Internal qualified as BlstBindings.Internal +import Data.ByteString (length) +import Data.Coerce (coerce) +import Data.Proxy (Proxy (..)) +import PlutusCore.Crypto.BLS12_381.Bounds (msmScalarOutOfBounds) +import PlutusCore.Crypto.BLS12_381.Error (BLS12_381_Error (..)) +#else +import Data.ByteString (pack) +import Data.Char (digitToInt) +import PlutusCore.Crypto.BLS12_381.Error (BLS12_381_Error) +import PlutusCore.Crypto.Utils (cryptoDisabled) +#endif + {- Note [Wrapping the BLS12-381 types in Plutus Core]. In the Haskell bindings to the `blst` library in cardano-crypto-class, points in G1 and G2 are represented as ForeignPtrs pointing to C objects, with a phantom type @@ -60,8 +66,18 @@ functions at the appropriate phantom types. See also Note [Wrapping the BLS12-381 types in PlutusTx]. -} +#ifdef WITH_CRYPTO newtype Element = Element {unElement :: BlstBindings.Point1} deriving newtype (Eq) +#else +{- See Note [The with-crypto flag] in PlutusCore.Crypto.Utils. Without the C +cryptography libraries a G1 element is represented by its compressed-point bytes; +this is enough to carry the type through the universe and to compile scripts, but +the group operations below are unavailable. -} +newtype Element = Element {unElement :: ByteString} + deriving newtype (Eq) +#endif + instance Show Element where show = byteStringAsHex . compress instance Pretty Element where @@ -91,6 +107,8 @@ instance NFData Element where instance Hashable Element where hashWithSalt salt = hashWithSalt salt . compress +#ifdef WITH_CRYPTO + -- | Add two G1 group elements add :: Element -> Element -> Element add = coerce (BlstBindings.blsAddOrDouble @BlstBindings.Curve1) @@ -199,3 +217,71 @@ multiScalarMul :: [Integer] -> [Element] -> BuiltinResult Element multiScalarMul ss p | any msmScalarOutOfBounds ss = fail "Scalar exceeds 512-byte bound for G1.multiScalarMul" | otherwise = pure . coerce $ BlstBindings.blsMSM @BlstBindings.Curve1 (zip ss (coerce p)) + +#else + +-- C-free stubs. See Note [The with-crypto flag] in PlutusCore.Crypto.Utils. +-- The group operations require the blst C library and are therefore unavailable; +-- 'compress'/'uncompress' remain total so the type can still be carried through +-- the universe, parsed, and compiled. + +add :: Element -> Element -> Element +add = cryptoDisabled "bls12_381_G1_add" + +neg :: Element -> Element +neg = cryptoDisabled "bls12_381_G1_neg" + +scalarMul :: Integer -> Element -> Element +scalarMul = cryptoDisabled "bls12_381_G1_scalarMul" + +scalarMulE :: Integer -> Element -> BuiltinResult Element +scalarMulE = cryptoDisabled "bls12_381_G1_scalarMul" + +-- | Just exposes the stored bytes: the only G1 operation that stays total in a +-- C-free build, so that 'Show'/'Hashable' keep working. +compress :: Element -> ByteString +compress = unElement + +-- | Cannot validate the point without the C library, so it just stores the +-- bytes. This lets the textual parser accept G1 literals when compiling scripts; +-- the bytes are never interpreted as a curve point in a C-free build. +uncompress :: ByteString -> Either BLS12_381_Error Element +uncompress = Right . Element + +hashToGroup :: ByteString -> ByteString -> Either BLS12_381_Error Element +hashToGroup = cryptoDisabled "bls12_381_G1_hashToGroup" + +-- The compressed zero/generator are fixed constants that PlutusTx lifts at +-- COMPILE time, so they must be real values (not stubs) even in a C-free build. +-- These literals are golden-checked (in a with-crypto build) to equal +-- @compress blsZero@ / @compress blsGenerator@. +offchain_zero :: Element +offchain_zero = Element compressed_zero + +compressed_zero :: ByteString +compressed_zero = + unhex "c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + +compressed_generator :: ByteString +compressed_generator = + unhex "97f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb" + +-- | Decode a hex string to a 'ByteString'. C-free helper for the constants above. +unhex :: String -> ByteString +unhex = pack . go + where + go (a : b : rest) = fromIntegral (digitToInt a * 16 + digitToInt b) : go rest + go _ = [] + +-- | Memory usage of a G1 point (144 bytes) +memSizeBytes :: Int +memSizeBytes = 144 + +-- | Compressed size of a G1 point (48 bytes) +compressedSizeBytes :: Int +compressedSizeBytes = 48 + +multiScalarMul :: [Integer] -> [Element] -> BuiltinResult Element +multiScalarMul = cryptoDisabled "bls12_381_G1_multiScalarMul" + +#endif diff --git a/plutus-core/plutus-core/src/PlutusCore/Crypto/BLS12_381/G2.hs b/plutus-core/plutus-core/src/PlutusCore/Crypto/BLS12_381/G2.hs index 66e41dd09b1..a69105233be 100644 --- a/plutus-core/plutus-core/src/PlutusCore/Crypto/BLS12_381/G2.hs +++ b/plutus-core/plutus-core/src/PlutusCore/Crypto/BLS12_381/G2.hs @@ -1,4 +1,5 @@ -- editorconfig-checker-disable +{-# LANGUAGE CPP #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TypeApplications #-} @@ -20,12 +21,7 @@ module PlutusCore.Crypto.BLS12_381.G2 , multiScalarMul ) where -import Cardano.Crypto.EllipticCurve.BLS12_381 qualified as BlstBindings -import Cardano.Crypto.EllipticCurve.BLS12_381.Internal qualified as BlstBindings.Internal - import PlutusCore.Builtin.Result (BuiltinResult (..)) -import PlutusCore.Crypto.BLS12_381.Bounds (msmScalarOutOfBounds) -import PlutusCore.Crypto.BLS12_381.Error (BLS12_381_Error (..)) import PlutusCore.Crypto.Utils (byteStringAsHex) import PlutusCore.Pretty.PrettyConst (ConstConfig) import Text.PrettyBy (PrettyBy) @@ -35,19 +31,38 @@ import Control.DeepSeq , rnf , rwhnf ) -import Data.ByteString - ( ByteString - , length - ) -import Data.Coerce (coerce) +import Data.ByteString (ByteString) import Data.Hashable -import Data.Proxy (Proxy (..)) import PlutusCore.Flat import Prettyprinter +#ifdef WITH_CRYPTO +import Cardano.Crypto.EllipticCurve.BLS12_381 qualified as BlstBindings +import Cardano.Crypto.EllipticCurve.BLS12_381.Internal qualified as BlstBindings.Internal +import Data.ByteString (length) +import Data.Coerce (coerce) +import Data.Proxy (Proxy (..)) +import PlutusCore.Crypto.BLS12_381.Bounds (msmScalarOutOfBounds) +import PlutusCore.Crypto.BLS12_381.Error (BLS12_381_Error (..)) +#else +import Data.ByteString (pack) +import Data.Char (digitToInt) +import PlutusCore.Crypto.BLS12_381.Error (BLS12_381_Error) +import PlutusCore.Crypto.Utils (cryptoDisabled) +#endif + -- | See Note [Wrapping the BLS12-381 types in Plutus Core]. +#ifdef WITH_CRYPTO newtype Element = Element {unElement :: BlstBindings.Point2} deriving newtype (Eq) +#else +{- See Note [The with-crypto flag] in PlutusCore.Crypto.Utils. Without the C +cryptography libraries a G2 element is represented by its compressed-point bytes; +this is enough to carry the type through the universe and to compile scripts, but +the group operations below are unavailable. -} +newtype Element = Element {unElement :: ByteString} + deriving newtype (Eq) +#endif instance Show Element where show = byteStringAsHex . compress @@ -78,6 +93,8 @@ instance NFData Element where instance Hashable Element where hashWithSalt salt = hashWithSalt salt . compress +#ifdef WITH_CRYPTO + -- | Add two G2 group elements add :: Element -> Element -> Element add = coerce (BlstBindings.blsAddOrDouble @BlstBindings.Curve2) @@ -157,3 +174,71 @@ multiScalarMul :: [Integer] -> [Element] -> BuiltinResult Element multiScalarMul ss p | any msmScalarOutOfBounds ss = fail "Scalar exceeds 512-byte bound for G2.multiScalarMul" | otherwise = pure . coerce $ BlstBindings.blsMSM @BlstBindings.Curve2 (zip ss (coerce p)) + +#else + +-- C-free stubs. See Note [The with-crypto flag] in PlutusCore.Crypto.Utils. +-- The group operations require the blst C library and are therefore unavailable; +-- 'compress'/'uncompress' remain total so the type can still be carried through +-- the universe, parsed, and compiled. + +add :: Element -> Element -> Element +add = cryptoDisabled "bls12_381_G2_add" + +neg :: Element -> Element +neg = cryptoDisabled "bls12_381_G2_neg" + +scalarMul :: Integer -> Element -> Element +scalarMul = cryptoDisabled "bls12_381_G2_scalarMul" + +scalarMulE :: Integer -> Element -> BuiltinResult Element +scalarMulE = cryptoDisabled "bls12_381_G2_scalarMul" + +-- | Just exposes the stored bytes: the only G2 operation that stays total in a +-- C-free build, so that 'Show'/'Hashable' keep working. +compress :: Element -> ByteString +compress = unElement + +-- | Cannot validate the point without the C library, so it just stores the +-- bytes. This lets the textual parser accept G2 literals when compiling scripts; +-- the bytes are never interpreted as a curve point in a C-free build. +uncompress :: ByteString -> Either BLS12_381_Error Element +uncompress = Right . Element + +hashToGroup :: ByteString -> ByteString -> Either BLS12_381_Error Element +hashToGroup = cryptoDisabled "bls12_381_G2_hashToGroup" + +-- The compressed zero/generator are fixed constants that PlutusTx lifts at +-- COMPILE time, so they must be real values (not stubs) even in a C-free build. +-- These literals are golden-checked (in a with-crypto build) to equal +-- @compress blsZero@ / @compress blsGenerator@. +offchain_zero :: Element +offchain_zero = Element compressed_zero + +compressed_zero :: ByteString +compressed_zero = + unhex "c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + +compressed_generator :: ByteString +compressed_generator = + unhex "93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8" + +-- | Decode a hex string to a 'ByteString'. C-free helper for the constants above. +unhex :: String -> ByteString +unhex = pack . go + where + go (a : b : rest) = fromIntegral (digitToInt a * 16 + digitToInt b) : go rest + go _ = [] + +-- | Memory usage of a G2 point (288 bytes) +memSizeBytes :: Int +memSizeBytes = 288 + +-- | Compressed size of a G2 point (96 bytes) +compressedSizeBytes :: Int +compressedSizeBytes = 96 + +multiScalarMul :: [Integer] -> [Element] -> BuiltinResult Element +multiScalarMul = cryptoDisabled "bls12_381_G2_multiScalarMul" + +#endif diff --git a/plutus-core/plutus-core/src/PlutusCore/Crypto/BLS12_381/Pairing.hs b/plutus-core/plutus-core/src/PlutusCore/Crypto/BLS12_381/Pairing.hs index c5caf1eb233..bc4ce3ea6db 100644 --- a/plutus-core/plutus-core/src/PlutusCore/Crypto/BLS12_381/Pairing.hs +++ b/plutus-core/plutus-core/src/PlutusCore/Crypto/BLS12_381/Pairing.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE CPP #-} {-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE TypeApplications #-} @@ -11,26 +12,39 @@ module PlutusCore.Crypto.BLS12_381.Pairing , identityMlResult ) where -import Cardano.Crypto.EllipticCurve.BLS12_381 qualified as BlstBindings -import Cardano.Crypto.EllipticCurve.BLS12_381.Internal qualified as BlstBindings.Internal - import PlutusCore.Crypto.BLS12_381.G1 qualified as G1 import PlutusCore.Crypto.BLS12_381.G2 qualified as G2 import PlutusCore.Pretty.PrettyConst (ConstConfig) import Text.PrettyBy (PrettyBy, prettyBy) import Control.DeepSeq (NFData, rnf) -import Data.Coerce (coerce) import Data.Hashable import PlutusCore.Flat import Prettyprinter +#ifdef WITH_CRYPTO +import Cardano.Crypto.EllipticCurve.BLS12_381 qualified as BlstBindings +import Cardano.Crypto.EllipticCurve.BLS12_381.Internal qualified as BlstBindings.Internal +import Data.Coerce (coerce) +#else +import Data.ByteString (ByteString) +import PlutusCore.Crypto.Utils (cryptoDisabled) +#endif + {-| This type represents the result of computing a pairing using the Miller loop. Values of this type are ephemeral, only created during script execution. We do not provide any means of serialising, deserialising, printing, or parsing MlResult values. -} +#ifdef WITH_CRYPTO newtype MlResult = MlResult {unMlResult :: BlstBindings.PT} deriving newtype (Eq) +#else +-- See Note [The with-crypto flag] in PlutusCore.Crypto.Utils. MlResult values +-- are only ever created during evaluation, which is unavailable in a C-free +-- build, so the representation is a placeholder. +newtype MlResult = MlResult {unMlResult :: ByteString} + deriving newtype (Eq) +#endif instance Show MlResult where show _ = "" @@ -56,6 +70,11 @@ instance NFData MlResult where instance Hashable MlResult where hashWithSalt salt _MlResult = salt +-- | Memory usage of an MlResult point (576 bytes) +mlResultMemSizeBytes :: Int + +#ifdef WITH_CRYPTO + millerLoop :: G1.Element -> G2.Element -> MlResult millerLoop = coerce BlstBindings.millerLoop @@ -67,11 +86,29 @@ finalVerify = coerce BlstBindings.ptFinalVerify -- Not exposed as builtins --- | Memory usage of an MlResult point (576 bytes) -mlResultMemSizeBytes :: Int mlResultMemSizeBytes = BlstBindings.Internal.sizePT {-| For some of the tests we need a small element of the MlResult type. We can get the identity element by pairing the zero elements of G1 and G2. -} identityMlResult :: MlResult identityMlResult = millerLoop G1.offchain_zero G2.offchain_zero + +#else + +-- C-free stubs. See Note [The with-crypto flag] in PlutusCore.Crypto.Utils. + +millerLoop :: G1.Element -> G2.Element -> MlResult +millerLoop = cryptoDisabled "bls12_381_millerLoop" + +mulMlResult :: MlResult -> MlResult -> MlResult +mulMlResult = cryptoDisabled "bls12_381_mulMlResult" + +finalVerify :: MlResult -> MlResult -> Bool +finalVerify = cryptoDisabled "bls12_381_finalVerify" + +mlResultMemSizeBytes = 576 + +identityMlResult :: MlResult +identityMlResult = cryptoDisabled "bls12_381 identityMlResult" + +#endif diff --git a/plutus-core/plutus-core/src/PlutusCore/Crypto/Ed25519.hs b/plutus-core/plutus-core/src/PlutusCore/Crypto/Ed25519.hs index 12a6aca1926..a3afafd1c4b 100644 --- a/plutus-core/plutus-core/src/PlutusCore/Crypto/Ed25519.hs +++ b/plutus-core/plutus-core/src/PlutusCore/Crypto/Ed25519.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE CPP #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TypeApplications #-} @@ -7,10 +8,13 @@ where import PlutusCore.Builtin.KnownType (BuiltinResult) import PlutusCore.Crypto.Utils +import Data.ByteString qualified as BS + +#ifdef WITH_CRYPTO import Cardano.Crypto.DSIGN.Class qualified as DSIGN import Cardano.Crypto.DSIGN.Ed25519 (Ed25519DSIGN) -import Data.ByteString qualified as BS import Data.Text (Text) +#endif {-| Ed25519 signature verification This will fail if the key or the signature are not of the expected length. @@ -24,6 +28,7 @@ verifyEd25519Signature -> BS.ByteString -- ^ Signature (64 bytes) -> BuiltinResult Bool +#ifdef WITH_CRYPTO verifyEd25519Signature pk msg sig = case DSIGN.rawDeserialiseVerKeyDSIGN @Ed25519DSIGN pk of Nothing -> failWithMessage loc "Invalid verification key." @@ -37,3 +42,7 @@ verifyEd25519Signature pk msg sig = where loc :: Text loc = "Ed25519 signature verification" +#else +-- See Note [The with-crypto flag] in PlutusCore.Crypto.Utils. +verifyEd25519Signature _pk _msg _sig = cryptoDisabled "verifyEd25519Signature" +#endif diff --git a/plutus-core/plutus-core/src/PlutusCore/Crypto/Hash.hs b/plutus-core/plutus-core/src/PlutusCore/Crypto/Hash.hs index a8104f8f150..42f68ba89fe 100644 --- a/plutus-core/plutus-core/src/PlutusCore/Crypto/Hash.hs +++ b/plutus-core/plutus-core/src/PlutusCore/Crypto/Hash.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE CPP #-} {-# LANGUAGE TypeApplications #-} -- | Hash functions for lazy [[Data.ByteString.ByteString]]s @@ -10,35 +11,56 @@ module PlutusCore.Crypto.Hash , ripemd_160 ) where +import Data.ByteString qualified as BS + +#ifdef WITH_CRYPTO 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 import Data.Proxy +#else +{- C-free build (see Note [The with-crypto flag] in PlutusCore.Crypto.Utils). +Unlike the signature and BLS12-381 primitives, the hashes are needed at COMPILE +time (e.g. PlutusLedgerApi computes script hashes with blake2b_224), so they +cannot be stubbed. They are all standard algorithms, so we compute them with +@crypton@, which vendors its C sources and declares no @pkgconfig-depends@ (so +it needs no system C library) and produces byte-identical output. -} +import Crypto.Hash (hashWith) +import Crypto.Hash.Algorithms + ( Blake2b_224 (..) + , Blake2b_256 (..) + , Keccak_256 (..) + , RIPEMD160 (..) + , SHA256 (..) + , SHA3_256 (..) + ) +import Data.ByteArray qualified as BA +#endif --- | Hash a `ByteString` using the SHA-256 hash function. -sha2_256 :: BS.ByteString -> BS.ByteString -sha2_256 = digest (Proxy @SHA256) +sha2_256, sha3_256, blake2b_224, blake2b_256, keccak_256, ripemd_160 + :: BS.ByteString -> BS.ByteString --- | Hash a `ByteString` using the SHA3-256 hash function. -sha3_256 :: BS.ByteString -> BS.ByteString -sha3_256 = digest (Proxy @SHA3_256) +#ifdef WITH_CRYPTO --- | Hash a `ByteString` using the Blake2b-224 hash function. -blake2b_224 :: BS.ByteString -> BS.ByteString +-- cardano-crypto-class (libsodium-backed) implementations. +sha2_256 = digest (Proxy @SHA256) +sha3_256 = digest (Proxy @SHA3_256) blake2b_224 = digest (Proxy @Blake2b_224) - --- | Hash a `ByteString` using the Blake2b-256 hash function. -blake2b_256 :: BS.ByteString -> BS.ByteString 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) + +#else + +-- crypton (vendored C, no system library) implementations. +sha2_256 = BA.convert . hashWith SHA256 +sha3_256 = BA.convert . hashWith SHA3_256 +blake2b_224 = BA.convert . hashWith Blake2b_224 +blake2b_256 = BA.convert . hashWith Blake2b_256 +keccak_256 = BA.convert . hashWith Keccak_256 +ripemd_160 = BA.convert . hashWith RIPEMD160 + +#endif diff --git a/plutus-core/plutus-core/src/PlutusCore/Crypto/Secp256k1.hs b/plutus-core/plutus-core/src/PlutusCore/Crypto/Secp256k1.hs index 009fd80539c..69eec20dbe0 100644 --- a/plutus-core/plutus-core/src/PlutusCore/Crypto/Secp256k1.hs +++ b/plutus-core/plutus-core/src/PlutusCore/Crypto/Secp256k1.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE CPP #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TypeApplications #-} @@ -9,11 +10,14 @@ module PlutusCore.Crypto.Secp256k1 import PlutusCore.Builtin.Result import PlutusCore.Crypto.Utils +import Data.ByteString qualified as BS + +#ifdef WITH_CRYPTO import Cardano.Crypto.DSIGN.Class qualified as DSIGN import Cardano.Crypto.DSIGN.EcdsaSecp256k1 (EcdsaSecp256k1DSIGN, toMessageHash) import Cardano.Crypto.DSIGN.SchnorrSecp256k1 (SchnorrSecp256k1DSIGN) -import Data.ByteString qualified as BS import Data.Text (Text) +#endif {-| Verify an ECDSA signature made using the SECP256k1 curve. @@ -45,6 +49,7 @@ verifyEcdsaSecp256k1Signature -> BS.ByteString -- ^ Signature (64 bytes) -> BuiltinResult Bool +#ifdef WITH_CRYPTO verifyEcdsaSecp256k1Signature pk msg sig = case DSIGN.rawDeserialiseVerKeyDSIGN @EcdsaSecp256k1DSIGN pk of Nothing -> failWithMessage loc "Invalid verification key." @@ -58,6 +63,10 @@ verifyEcdsaSecp256k1Signature pk msg sig = where loc :: Text loc = "ECDSA SECP256k1 signature verification" +#else +-- See Note [The with-crypto flag] in PlutusCore.Crypto.Utils. +verifyEcdsaSecp256k1Signature _pk _msg _sig = cryptoDisabled "verifyEcdsaSecp256k1Signature" +#endif {-| Verify a Schnorr signature made using the SECP256k1 curve. @@ -84,6 +93,7 @@ verifySchnorrSecp256k1Signature -> BS.ByteString -- ^ Signature (64 bytes) -> BuiltinResult Bool +#ifdef WITH_CRYPTO verifySchnorrSecp256k1Signature pk msg sig = case DSIGN.rawDeserialiseVerKeyDSIGN @SchnorrSecp256k1DSIGN pk of Nothing -> failWithMessage loc "Invalid verification key." @@ -95,3 +105,7 @@ verifySchnorrSecp256k1Signature pk msg sig = where loc :: Text loc = "Schnorr SECP256k1 signature verification" +#else +-- See Note [The with-crypto flag] in PlutusCore.Crypto.Utils. +verifySchnorrSecp256k1Signature _pk _msg _sig = cryptoDisabled "verifySchnorrSecp256k1Signature" +#endif diff --git a/plutus-core/plutus-core/src/PlutusCore/Crypto/Utils.hs b/plutus-core/plutus-core/src/PlutusCore/Crypto/Utils.hs index 9cfe12d0441..8657dffeacb 100644 --- a/plutus-core/plutus-core/src/PlutusCore/Crypto/Utils.hs +++ b/plutus-core/plutus-core/src/PlutusCore/Crypto/Utils.hs @@ -4,6 +4,7 @@ module PlutusCore.Crypto.Utils ( failWithMessage , byteStringAsHex + , cryptoDisabled ) where import PlutusCore.Builtin.Result @@ -17,6 +18,42 @@ import Data.Kind (Type) import Data.Text (Text) import Text.Printf (printf) +{- Note [The with-crypto flag] +The cryptographic builtins (the hashes, the signature-verification primitives, +and the BLS12-381 primitives) are implemented in cardano-crypto-class, which +binds the C libraries libsodium, libblst and libsecp256k1. Because Cabal resolves +a package's @pkgconfig-depends@ at solve time for the whole package (see +https://github.com/haskell/cabal/issues/4087), merely depending on +cardano-crypto-class forces those C libraries to be present in order to even +/configure/ a build — which makes it impossible to write and compile a Plinth/ +Plutus script in an environment that does not have them installed. + +The @with-crypto@ Cabal flag (enabled by default) controls this. When it is on, +the modules under @PlutusCore.Crypto@ link cardano-crypto-class and behave +exactly as before. When it is off (@-with-crypto@), those modules compile a +C-free stub instead: the builtin /types/ (e.g. BLS12-381 group elements) keep a +representation good enough for the universe and the compiler, but the builtin +/operations/ are replaced by 'cryptoDisabled'. The upshot is that a @-with-crypto@ +build links no C cryptography library and can therefore be configured and built +anywhere, and Plinth scripts that use the cryptographic builtins can still be +COMPILED — but those builtins cannot be EVALUATED in such a build. + +The default build (@with-crypto@) is completely unchanged, so on-chain +evaluation, conformance and costing are unaffected. -} + +-- | The denotation of a cryptographic builtin in a @-with-crypto@ build: the +-- operation is unavailable because the C cryptography libraries were not linked. +-- Used only by the C-free stubs under "PlutusCore.Crypto"; see +-- Note [The with-crypto flag]. +cryptoDisabled :: forall (a :: Type). String -> a +cryptoDisabled op = + error $ + "This build of Plutus Core was compiled without cryptographic support \ + \(the with-crypto Cabal flag is disabled), so the builtin " + <> op + <> " cannot be evaluated. Rebuild with the with-crypto flag enabled to \ + \obtain an evaluator that links the C cryptography libraries." + failWithMessage :: forall (a :: Type). Text -> Text -> BuiltinResult a failWithMessage location reason = do emit $ location <> ": " <> reason diff --git a/plutus-core/test-crypto-hash-parity/Spec.hs b/plutus-core/test-crypto-hash-parity/Spec.hs new file mode 100644 index 00000000000..ba560fc989c --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/Spec.hs @@ -0,0 +1,68 @@ +{-# LANGUAGE OverloadedStrings #-} + +{- | Parity goldens for the cryptographic hash builtins. + +The golden files are generated by the DEFAULT (@with-crypto@) build, where +'PlutusCore.Crypto.Hash' is backed by cardano-crypto-class (libsodium). Running +the same suite in a C-free (@-with-crypto@) build, where the hashes are backed by +crypton, must reproduce them byte-for-byte. That is the parity guarantee: the +C-free build's hashes are identical to the on-chain implementation's. See +Note [The with-crypto flag] in PlutusCore.Crypto.Utils. + +Generate/refresh the goldens (with-crypto build): cabal test crypto-hash-parity-test --test-options=--accept +Check parity (C-free build): cabal test crypto-hash-parity-test --flags=-with-crypto +-} +module Main (main) where + +import PlutusCore.Crypto.Hash qualified as Hash + +import Data.ByteString (ByteString) +import Data.ByteString qualified as BS +import Data.ByteString.Base16 qualified as Base16 +import Data.ByteString.Lazy qualified as LBS +import Data.Word (Word8) +import Test.Tasty +import Test.Tasty.Golden (goldenVsString) + +-- | Each hash builtin, exercised through the flag-gated 'PlutusCore.Crypto.Hash' +-- module (so we test whatever implementation the build actually uses). +hashImpls :: [(String, ByteString -> ByteString)] +hashImpls = + [ ("sha2_256", Hash.sha2_256) + , ("sha3_256", Hash.sha3_256) + , ("blake2b_224", Hash.blake2b_224) + , ("blake2b_256", Hash.blake2b_256) + , ("keccak_256", Hash.keccak_256) + , ("ripemd_160", Hash.ripemd_160) + ] + +-- | Inputs chosen to exercise empty input, small inputs, all byte values, and +-- the block/rate boundaries of the various algorithms (SHA-2 64-byte blocks and +-- 55/56-byte padding edges, BLAKE2b 128-byte blocks, SHA-3/Keccak-256 136-byte +-- rate), plus a long and a pseudo-random input. +inputs :: [(String, ByteString)] +inputs = + [ ("empty", BS.empty) + , ("abc", "abc") + , ("fox", "The quick brown fox jumps over the lazy dog") + , ("byte00", BS.singleton 0x00) + , ("byteff", BS.singleton 0xff) + , ("allbytes", BS.pack [0 .. 255]) + , ("pseudorandom333", BS.pack [fromIntegral (i * 7 + 3) :: Word8 | i <- [0 .. 332 :: Int]]) + ] + ++ [("len" ++ show n, BS.replicate n 0x61) | n <- [55, 56, 63, 64, 65, 127, 128, 129, 135, 136, 137, 1000]] + +main :: IO () +main = + defaultMain $ + testGroup + "cryptographic hash goldens (with-crypto vs C-free parity)" + [ testGroup hname + [ goldenVsString + iname + ("test-crypto-hash-parity/golden/" ++ hname ++ "-" ++ iname ++ ".golden") + (pure (LBS.fromStrict (Base16.encode (impl input)))) + | (iname, input) <- inputs + ] + | (hname, impl) <- hashImpls + ] diff --git a/plutus-core/test-crypto-hash-parity/golden/blake2b_224-abc.golden b/plutus-core/test-crypto-hash-parity/golden/blake2b_224-abc.golden new file mode 100644 index 00000000000..f6e6ab45fd3 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/blake2b_224-abc.golden @@ -0,0 +1 @@ +9bd237b02a29e43bdd6738afa5b53ff0eee178d6210b618e4511aec8 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/blake2b_224-allbytes.golden b/plutus-core/test-crypto-hash-parity/golden/blake2b_224-allbytes.golden new file mode 100644 index 00000000000..44f9fe410c4 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/blake2b_224-allbytes.golden @@ -0,0 +1 @@ +36b87bde0ee2893d8f0e7fe59f60c6cb4a2d8aebdc8b1966380bfd57 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/blake2b_224-byte00.golden b/plutus-core/test-crypto-hash-parity/golden/blake2b_224-byte00.golden new file mode 100644 index 00000000000..7302b3abaf4 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/blake2b_224-byte00.golden @@ -0,0 +1 @@ +0d94e174732ef9aae73f395ab44507bfa983d65023c11a951f0c32e4 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/blake2b_224-byteff.golden b/plutus-core/test-crypto-hash-parity/golden/blake2b_224-byteff.golden new file mode 100644 index 00000000000..2ed7c31ff7d --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/blake2b_224-byteff.golden @@ -0,0 +1 @@ +17f65d97f383cf41985ff2f90ce52351ace2ab239d9eadf4269a2882 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/blake2b_224-empty.golden b/plutus-core/test-crypto-hash-parity/golden/blake2b_224-empty.golden new file mode 100644 index 00000000000..94f79a36859 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/blake2b_224-empty.golden @@ -0,0 +1 @@ +836cc68931c2e4e3e838602eca1902591d216837bafddfe6f0c8cb07 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/blake2b_224-fox.golden b/plutus-core/test-crypto-hash-parity/golden/blake2b_224-fox.golden new file mode 100644 index 00000000000..8b7b50b4749 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/blake2b_224-fox.golden @@ -0,0 +1 @@ +477c3985751dd4d1b8c93827ea5310b33bb02a26463a050dffd3e857 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/blake2b_224-len1000.golden b/plutus-core/test-crypto-hash-parity/golden/blake2b_224-len1000.golden new file mode 100644 index 00000000000..95e9d074eff --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/blake2b_224-len1000.golden @@ -0,0 +1 @@ +c145e8be163c70538fa23ad8f73aed376b7f505f7abe7bdbd16227fa \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/blake2b_224-len127.golden b/plutus-core/test-crypto-hash-parity/golden/blake2b_224-len127.golden new file mode 100644 index 00000000000..36bb27085ab --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/blake2b_224-len127.golden @@ -0,0 +1 @@ +8c69dc34c82eb6333eaadc3c2f32a50378bef2cedb0da2242524bdab \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/blake2b_224-len128.golden b/plutus-core/test-crypto-hash-parity/golden/blake2b_224-len128.golden new file mode 100644 index 00000000000..917be51af0a --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/blake2b_224-len128.golden @@ -0,0 +1 @@ +d5df9e9a3d386e984c5464df2c67c4c2b2e74ff4f60fa19f3f37d479 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/blake2b_224-len129.golden b/plutus-core/test-crypto-hash-parity/golden/blake2b_224-len129.golden new file mode 100644 index 00000000000..667c2d6a749 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/blake2b_224-len129.golden @@ -0,0 +1 @@ +39d2c78556ad2b0fdcfdfdce9c017310a84e5609cfe3ace0804827b7 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/blake2b_224-len135.golden b/plutus-core/test-crypto-hash-parity/golden/blake2b_224-len135.golden new file mode 100644 index 00000000000..853bd9b0f11 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/blake2b_224-len135.golden @@ -0,0 +1 @@ +64c5eae369759049d44a22e515de34b9607a83238b9511cb85e271a3 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/blake2b_224-len136.golden b/plutus-core/test-crypto-hash-parity/golden/blake2b_224-len136.golden new file mode 100644 index 00000000000..877c99cf412 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/blake2b_224-len136.golden @@ -0,0 +1 @@ +d17873cda702cec5f4f43e9ed552310ca980f984e2e0df0a9d5cb881 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/blake2b_224-len137.golden b/plutus-core/test-crypto-hash-parity/golden/blake2b_224-len137.golden new file mode 100644 index 00000000000..81b7f371f6c --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/blake2b_224-len137.golden @@ -0,0 +1 @@ +4ab6c8e2bfc39a17cfa9f7eaf97f6c6455c306aa74b0bb1e6d524a77 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/blake2b_224-len55.golden b/plutus-core/test-crypto-hash-parity/golden/blake2b_224-len55.golden new file mode 100644 index 00000000000..0955e7cbcd4 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/blake2b_224-len55.golden @@ -0,0 +1 @@ +3b5b6098086cdb71d54cfdf6accb1f724294fd1f84f2c2c368692a2e \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/blake2b_224-len56.golden b/plutus-core/test-crypto-hash-parity/golden/blake2b_224-len56.golden new file mode 100644 index 00000000000..ecaf53addb4 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/blake2b_224-len56.golden @@ -0,0 +1 @@ +aabf6271a7c52fd0120aa019ea25377d7d1f4cff464f031bc1deefef \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/blake2b_224-len63.golden b/plutus-core/test-crypto-hash-parity/golden/blake2b_224-len63.golden new file mode 100644 index 00000000000..2bf20c69ede --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/blake2b_224-len63.golden @@ -0,0 +1 @@ +99e0c337385cad2a57fbf814142c11986b8c4858bd5d06e6467809bb \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/blake2b_224-len64.golden b/plutus-core/test-crypto-hash-parity/golden/blake2b_224-len64.golden new file mode 100644 index 00000000000..dc803e222dd --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/blake2b_224-len64.golden @@ -0,0 +1 @@ +774d28b31bbe7d48fb48e0d489c17e8537548d344c44250e4bef2a6a \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/blake2b_224-len65.golden b/plutus-core/test-crypto-hash-parity/golden/blake2b_224-len65.golden new file mode 100644 index 00000000000..a5680c65100 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/blake2b_224-len65.golden @@ -0,0 +1 @@ +04323f452133f56f77abbfe4897d6e132f5c1f5c3e4855a0fceb80c6 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/blake2b_224-pseudorandom333.golden b/plutus-core/test-crypto-hash-parity/golden/blake2b_224-pseudorandom333.golden new file mode 100644 index 00000000000..0097d1032a9 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/blake2b_224-pseudorandom333.golden @@ -0,0 +1 @@ +3da509b63b1ab34ecc6083a07c7026a2c737cb56ffe2766df35d41e5 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/blake2b_256-abc.golden b/plutus-core/test-crypto-hash-parity/golden/blake2b_256-abc.golden new file mode 100644 index 00000000000..fc39c2259dd --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/blake2b_256-abc.golden @@ -0,0 +1 @@ +bddd813c634239723171ef3fee98579b94964e3bb1cb3e427262c8c068d52319 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/blake2b_256-allbytes.golden b/plutus-core/test-crypto-hash-parity/golden/blake2b_256-allbytes.golden new file mode 100644 index 00000000000..01ce98cc004 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/blake2b_256-allbytes.golden @@ -0,0 +1 @@ +39a7eb9fedc19aabc83425c6755dd90e6f9d0c804964a1f4aaeea3b9fb599835 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/blake2b_256-byte00.golden b/plutus-core/test-crypto-hash-parity/golden/blake2b_256-byte00.golden new file mode 100644 index 00000000000..d11e969b2d4 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/blake2b_256-byte00.golden @@ -0,0 +1 @@ +03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/blake2b_256-byteff.golden b/plutus-core/test-crypto-hash-parity/golden/blake2b_256-byteff.golden new file mode 100644 index 00000000000..7ac09d82b71 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/blake2b_256-byteff.golden @@ -0,0 +1 @@ +ac4e4076a883937282f1377ef5cacb8edd00e3c79629e43532464eb3be277367 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/blake2b_256-empty.golden b/plutus-core/test-crypto-hash-parity/golden/blake2b_256-empty.golden new file mode 100644 index 00000000000..cba27a1e500 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/blake2b_256-empty.golden @@ -0,0 +1 @@ +0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/blake2b_256-fox.golden b/plutus-core/test-crypto-hash-parity/golden/blake2b_256-fox.golden new file mode 100644 index 00000000000..9c98898037e --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/blake2b_256-fox.golden @@ -0,0 +1 @@ +01718cec35cd3d796dd00020e0bfecb473ad23457d063b75eff29c0ffa2e58a9 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/blake2b_256-len1000.golden b/plutus-core/test-crypto-hash-parity/golden/blake2b_256-len1000.golden new file mode 100644 index 00000000000..9a3e139964b --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/blake2b_256-len1000.golden @@ -0,0 +1 @@ +e00b0ddbf1e2cdaf5c898e1a5e8826ea3a2c339bcf2a478da2e5fca9ff126672 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/blake2b_256-len127.golden b/plutus-core/test-crypto-hash-parity/golden/blake2b_256-len127.golden new file mode 100644 index 00000000000..68943bb862d --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/blake2b_256-len127.golden @@ -0,0 +1 @@ +59e2f1aba240f20aa591016f5ef429990bc9c2131dcd0d30f0ffd75ed18f317d \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/blake2b_256-len128.golden b/plutus-core/test-crypto-hash-parity/golden/blake2b_256-len128.golden new file mode 100644 index 00000000000..6df003ceba1 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/blake2b_256-len128.golden @@ -0,0 +1 @@ +ae2aa48507885c4c950fb809b2076f959cde9f8ea6da260d9a3587df33dac450 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/blake2b_256-len129.golden b/plutus-core/test-crypto-hash-parity/golden/blake2b_256-len129.golden new file mode 100644 index 00000000000..b52c403676c --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/blake2b_256-len129.golden @@ -0,0 +1 @@ +2f64744a6de0d2c0b56e64cf6e29a5aaa255010d415d51c75ccc82f73dccd865 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/blake2b_256-len135.golden b/plutus-core/test-crypto-hash-parity/golden/blake2b_256-len135.golden new file mode 100644 index 00000000000..c0425ceba66 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/blake2b_256-len135.golden @@ -0,0 +1 @@ +b5612841c46eda21e2b861ab2ae1731540ff19c1529768db77e9238c10d0717b \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/blake2b_256-len136.golden b/plutus-core/test-crypto-hash-parity/golden/blake2b_256-len136.golden new file mode 100644 index 00000000000..36fd86a146f --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/blake2b_256-len136.golden @@ -0,0 +1 @@ +998802defa23a4df8f053d4fa9fd2a97a085a4ffb15d5494be644a8f05b4eb4e \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/blake2b_256-len137.golden b/plutus-core/test-crypto-hash-parity/golden/blake2b_256-len137.golden new file mode 100644 index 00000000000..3b2d49e64d1 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/blake2b_256-len137.golden @@ -0,0 +1 @@ +b9184415945cf6935cba82c6e4e22971e5cd659bdafddaf085c3de0123b5cfe3 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/blake2b_256-len55.golden b/plutus-core/test-crypto-hash-parity/golden/blake2b_256-len55.golden new file mode 100644 index 00000000000..9a41259d7f5 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/blake2b_256-len55.golden @@ -0,0 +1 @@ +94ac361af706e2cb330ec00a01b685140fba6c8d9b6079640906593e7753114e \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/blake2b_256-len56.golden b/plutus-core/test-crypto-hash-parity/golden/blake2b_256-len56.golden new file mode 100644 index 00000000000..d02c394d012 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/blake2b_256-len56.golden @@ -0,0 +1 @@ +749373b29d21d245933e0e994a0070b5db951a9169c3d84f84bc3ca707fce3c8 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/blake2b_256-len63.golden b/plutus-core/test-crypto-hash-parity/golden/blake2b_256-len63.golden new file mode 100644 index 00000000000..90bffe8ad5b --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/blake2b_256-len63.golden @@ -0,0 +1 @@ +d39b5f09c195d09dd90d0e5706bf31c484434275a56d4e8f853f594e947083fb \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/blake2b_256-len64.golden b/plutus-core/test-crypto-hash-parity/golden/blake2b_256-len64.golden new file mode 100644 index 00000000000..446081d1c5b --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/blake2b_256-len64.golden @@ -0,0 +1 @@ +b1e70fb5c59f0727f1c099e3ddccadc0857c8d21a4b5cd9b637ef964e94c2b29 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/blake2b_256-len65.golden b/plutus-core/test-crypto-hash-parity/golden/blake2b_256-len65.golden new file mode 100644 index 00000000000..bcf2823264c --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/blake2b_256-len65.golden @@ -0,0 +1 @@ +03613697396dfc5f9dd33064ee3bb913c89491192ac0f8fd07efd4659d6ba011 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/blake2b_256-pseudorandom333.golden b/plutus-core/test-crypto-hash-parity/golden/blake2b_256-pseudorandom333.golden new file mode 100644 index 00000000000..6271619a637 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/blake2b_256-pseudorandom333.golden @@ -0,0 +1 @@ +db477eeafc7148b47bf732505f488c8b7ae46854a87b027bd4fc78ae357718d9 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/keccak_256-abc.golden b/plutus-core/test-crypto-hash-parity/golden/keccak_256-abc.golden new file mode 100644 index 00000000000..510901e8d6b --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/keccak_256-abc.golden @@ -0,0 +1 @@ +4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/keccak_256-allbytes.golden b/plutus-core/test-crypto-hash-parity/golden/keccak_256-allbytes.golden new file mode 100644 index 00000000000..1f6b3593920 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/keccak_256-allbytes.golden @@ -0,0 +1 @@ +dc924469b334aed2a19fac7252e9961aea41f8d91996366029dbe0884229bf36 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/keccak_256-byte00.golden b/plutus-core/test-crypto-hash-parity/golden/keccak_256-byte00.golden new file mode 100644 index 00000000000..acc5a340f33 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/keccak_256-byte00.golden @@ -0,0 +1 @@ +bc36789e7a1e281436464229828f817d6612f7b477d66591ff96a9e064bcc98a \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/keccak_256-byteff.golden b/plutus-core/test-crypto-hash-parity/golden/keccak_256-byteff.golden new file mode 100644 index 00000000000..7e75773a287 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/keccak_256-byteff.golden @@ -0,0 +1 @@ +8b1a944cf13a9a1c08facb2c9e98623ef3254d2ddb48113885c3e8e97fec8db9 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/keccak_256-empty.golden b/plutus-core/test-crypto-hash-parity/golden/keccak_256-empty.golden new file mode 100644 index 00000000000..62e457fd5e1 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/keccak_256-empty.golden @@ -0,0 +1 @@ +c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/keccak_256-fox.golden b/plutus-core/test-crypto-hash-parity/golden/keccak_256-fox.golden new file mode 100644 index 00000000000..947598268ea --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/keccak_256-fox.golden @@ -0,0 +1 @@ +4d741b6f1eb29cb2a9b9911c82f56fa8d73b04959d3d9d222895df6c0b28aa15 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/keccak_256-len1000.golden b/plutus-core/test-crypto-hash-parity/golden/keccak_256-len1000.golden new file mode 100644 index 00000000000..3b6d7bb5cb6 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/keccak_256-len1000.golden @@ -0,0 +1 @@ +b6a4ac1f51884d71f30fa397a5e155de3099e11fc0edef5d08b646e621e19de9 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/keccak_256-len127.golden b/plutus-core/test-crypto-hash-parity/golden/keccak_256-len127.golden new file mode 100644 index 00000000000..843d05d8651 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/keccak_256-len127.golden @@ -0,0 +1 @@ +2985b12ded0bf77d3a81e1b504266c2ef82a7abc05aab74dfd3fcd9bf9d25ff2 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/keccak_256-len128.golden b/plutus-core/test-crypto-hash-parity/golden/keccak_256-len128.golden new file mode 100644 index 00000000000..b3d1b7ede53 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/keccak_256-len128.golden @@ -0,0 +1 @@ +81555b8e18b3c117311c16373b1aa78c0a84aad7b8f7f4c753d0021fd9a6700e \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/keccak_256-len129.golden b/plutus-core/test-crypto-hash-parity/golden/keccak_256-len129.golden new file mode 100644 index 00000000000..88aafd10bd7 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/keccak_256-len129.golden @@ -0,0 +1 @@ +64aa8a28a772ee76c84d6ebde75064fc5282e22a8cf617af1d7e5e08ef9a3248 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/keccak_256-len135.golden b/plutus-core/test-crypto-hash-parity/golden/keccak_256-len135.golden new file mode 100644 index 00000000000..11b2a0fe644 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/keccak_256-len135.golden @@ -0,0 +1 @@ +34367dc248bbd832f4e3e69dfaac2f92638bd0bbd18f2912ba4ef454919cf446 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/keccak_256-len136.golden b/plutus-core/test-crypto-hash-parity/golden/keccak_256-len136.golden new file mode 100644 index 00000000000..9e17969cbb8 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/keccak_256-len136.golden @@ -0,0 +1 @@ +a6c4d403279fe3e0af03729caada8374b5ca54d8065329a3ebcaeb4b60aa386e \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/keccak_256-len137.golden b/plutus-core/test-crypto-hash-parity/golden/keccak_256-len137.golden new file mode 100644 index 00000000000..821b35459ee --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/keccak_256-len137.golden @@ -0,0 +1 @@ +d869f639c7046b4929fc92a4d988a8b22c55fbadb802c0c66ebcd484f1915f39 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/keccak_256-len55.golden b/plutus-core/test-crypto-hash-parity/golden/keccak_256-len55.golden new file mode 100644 index 00000000000..5f0bf393ccc --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/keccak_256-len55.golden @@ -0,0 +1 @@ +bb17c0a497f956eb60406de77632af5a598833dac1d41a5f171943dc6aaa519a \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/keccak_256-len56.golden b/plutus-core/test-crypto-hash-parity/golden/keccak_256-len56.golden new file mode 100644 index 00000000000..81590e71fd4 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/keccak_256-len56.golden @@ -0,0 +1 @@ +86e098d28db0370fc43ce9ced16fa20fd031f0f85f2c200dfc615a46661c4647 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/keccak_256-len63.golden b/plutus-core/test-crypto-hash-parity/golden/keccak_256-len63.golden new file mode 100644 index 00000000000..d5eb37a8b3a --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/keccak_256-len63.golden @@ -0,0 +1 @@ +665d33bbec07cf132a7ac9b1724f4027d12fcba1e506332fa68b247329ed6de4 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/keccak_256-len64.golden b/plutus-core/test-crypto-hash-parity/golden/keccak_256-len64.golden new file mode 100644 index 00000000000..b6bdf46bbd2 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/keccak_256-len64.golden @@ -0,0 +1 @@ +1036d73cc8350b0635393d79759b10488165e792073f84d4462e22edec243b92 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/keccak_256-len65.golden b/plutus-core/test-crypto-hash-parity/golden/keccak_256-len65.golden new file mode 100644 index 00000000000..7e83382aac1 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/keccak_256-len65.golden @@ -0,0 +1 @@ +c970b103fd7a66de650b6fc134af4bbf8cb7445d7ff7b32150975686ba7a47a6 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/keccak_256-pseudorandom333.golden b/plutus-core/test-crypto-hash-parity/golden/keccak_256-pseudorandom333.golden new file mode 100644 index 00000000000..da03a31bf55 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/keccak_256-pseudorandom333.golden @@ -0,0 +1 @@ +7bda3cc33e0919740c7c6300d0178d22043d99f8958901570a70695d104ed254 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/ripemd_160-abc.golden b/plutus-core/test-crypto-hash-parity/golden/ripemd_160-abc.golden new file mode 100644 index 00000000000..a01a6510b67 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/ripemd_160-abc.golden @@ -0,0 +1 @@ +8eb208f7e05d987a9b044a8e98c6b087f15a0bfc \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/ripemd_160-allbytes.golden b/plutus-core/test-crypto-hash-parity/golden/ripemd_160-allbytes.golden new file mode 100644 index 00000000000..884a4980f6c --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/ripemd_160-allbytes.golden @@ -0,0 +1 @@ +9c4fa072db2c871a5635e37f791e93ab45049676 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/ripemd_160-byte00.golden b/plutus-core/test-crypto-hash-parity/golden/ripemd_160-byte00.golden new file mode 100644 index 00000000000..c73d4284453 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/ripemd_160-byte00.golden @@ -0,0 +1 @@ +c81b94933420221a7ac004a90242d8b1d3e5070d \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/ripemd_160-byteff.golden b/plutus-core/test-crypto-hash-parity/golden/ripemd_160-byteff.golden new file mode 100644 index 00000000000..dd3345993d0 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/ripemd_160-byteff.golden @@ -0,0 +1 @@ +2c0c45d3ecab80fe060e5f1d7057cd2f8de5e557 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/ripemd_160-empty.golden b/plutus-core/test-crypto-hash-parity/golden/ripemd_160-empty.golden new file mode 100644 index 00000000000..dc94d948852 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/ripemd_160-empty.golden @@ -0,0 +1 @@ +9c1185a5c5e9fc54612808977ee8f548b2258d31 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/ripemd_160-fox.golden b/plutus-core/test-crypto-hash-parity/golden/ripemd_160-fox.golden new file mode 100644 index 00000000000..ec5370aa435 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/ripemd_160-fox.golden @@ -0,0 +1 @@ +37f332f68db77bd9d7edd4969571ad671cf9dd3b \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/ripemd_160-len1000.golden b/plutus-core/test-crypto-hash-parity/golden/ripemd_160-len1000.golden new file mode 100644 index 00000000000..3e9815c46b3 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/ripemd_160-len1000.golden @@ -0,0 +1 @@ +aa69deee9a8922e92f8105e007f76110f381e9cf \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/ripemd_160-len127.golden b/plutus-core/test-crypto-hash-parity/golden/ripemd_160-len127.golden new file mode 100644 index 00000000000..90cb50bfc74 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/ripemd_160-len127.golden @@ -0,0 +1 @@ +64f2d68b85f394e2e4f49009c4bd50224c2698ed \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/ripemd_160-len128.golden b/plutus-core/test-crypto-hash-parity/golden/ripemd_160-len128.golden new file mode 100644 index 00000000000..31663e4b333 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/ripemd_160-len128.golden @@ -0,0 +1 @@ +8dfdfb32b2ed5cb41a73478b4fd60cc5b4648b15 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/ripemd_160-len129.golden b/plutus-core/test-crypto-hash-parity/golden/ripemd_160-len129.golden new file mode 100644 index 00000000000..0fa62e66817 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/ripemd_160-len129.golden @@ -0,0 +1 @@ +62bb9091f499f294f15aa5b951df4d9744d50cf2 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/ripemd_160-len135.golden b/plutus-core/test-crypto-hash-parity/golden/ripemd_160-len135.golden new file mode 100644 index 00000000000..c93732a1d68 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/ripemd_160-len135.golden @@ -0,0 +1 @@ +45ce81f2cf08a01135ba1895452d5431d6b013f9 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/ripemd_160-len136.golden b/plutus-core/test-crypto-hash-parity/golden/ripemd_160-len136.golden new file mode 100644 index 00000000000..0a80ac6d4da --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/ripemd_160-len136.golden @@ -0,0 +1 @@ +4dbcc675e256fcd05507c62d91a7186d7cd021d3 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/ripemd_160-len137.golden b/plutus-core/test-crypto-hash-parity/golden/ripemd_160-len137.golden new file mode 100644 index 00000000000..8e6820d852f --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/ripemd_160-len137.golden @@ -0,0 +1 @@ +a80a52ac17965045d1f497683228eb07d2fe5fff \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/ripemd_160-len55.golden b/plutus-core/test-crypto-hash-parity/golden/ripemd_160-len55.golden new file mode 100644 index 00000000000..b8556fa150a --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/ripemd_160-len55.golden @@ -0,0 +1 @@ +0d8a8c9063a48576a7c97e9f95253a6e53ff6765 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/ripemd_160-len56.golden b/plutus-core/test-crypto-hash-parity/golden/ripemd_160-len56.golden new file mode 100644 index 00000000000..bea14ea7474 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/ripemd_160-len56.golden @@ -0,0 +1 @@ +e72334b46c83cc70bef979e15453706c95b888be \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/ripemd_160-len63.golden b/plutus-core/test-crypto-hash-parity/golden/ripemd_160-len63.golden new file mode 100644 index 00000000000..72ca2298961 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/ripemd_160-len63.golden @@ -0,0 +1 @@ +e640041293fe663b9bf3f8c21ffecac03819e6b2 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/ripemd_160-len64.golden b/plutus-core/test-crypto-hash-parity/golden/ripemd_160-len64.golden new file mode 100644 index 00000000000..a43b18876f8 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/ripemd_160-len64.golden @@ -0,0 +1 @@ +9dfb7d374ad924f3f88de96291c33e9abed53e32 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/ripemd_160-len65.golden b/plutus-core/test-crypto-hash-parity/golden/ripemd_160-len65.golden new file mode 100644 index 00000000000..aea5808a111 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/ripemd_160-len65.golden @@ -0,0 +1 @@ +99724bb11811e7166af38f671b6a082d8ab4960b \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/ripemd_160-pseudorandom333.golden b/plutus-core/test-crypto-hash-parity/golden/ripemd_160-pseudorandom333.golden new file mode 100644 index 00000000000..385852b056e --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/ripemd_160-pseudorandom333.golden @@ -0,0 +1 @@ +6a25ab740c5f27204335283037fc8c3e49eb3cff \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/sha2_256-abc.golden b/plutus-core/test-crypto-hash-parity/golden/sha2_256-abc.golden new file mode 100644 index 00000000000..876ad58ca41 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/sha2_256-abc.golden @@ -0,0 +1 @@ +ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/sha2_256-allbytes.golden b/plutus-core/test-crypto-hash-parity/golden/sha2_256-allbytes.golden new file mode 100644 index 00000000000..3b7af151b0f --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/sha2_256-allbytes.golden @@ -0,0 +1 @@ +40aff2e9d2d8922e47afd4648e6967497158785fbd1da870e7110266bf944880 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/sha2_256-byte00.golden b/plutus-core/test-crypto-hash-parity/golden/sha2_256-byte00.golden new file mode 100644 index 00000000000..d7fd8785b76 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/sha2_256-byte00.golden @@ -0,0 +1 @@ +6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/sha2_256-byteff.golden b/plutus-core/test-crypto-hash-parity/golden/sha2_256-byteff.golden new file mode 100644 index 00000000000..cd56f399b8b --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/sha2_256-byteff.golden @@ -0,0 +1 @@ +a8100ae6aa1940d0b663bb31cd466142ebbdbd5187131b92d93818987832eb89 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/sha2_256-empty.golden b/plutus-core/test-crypto-hash-parity/golden/sha2_256-empty.golden new file mode 100644 index 00000000000..293ce40fd6b --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/sha2_256-empty.golden @@ -0,0 +1 @@ +e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/sha2_256-fox.golden b/plutus-core/test-crypto-hash-parity/golden/sha2_256-fox.golden new file mode 100644 index 00000000000..3712fb92bfb --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/sha2_256-fox.golden @@ -0,0 +1 @@ +d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/sha2_256-len1000.golden b/plutus-core/test-crypto-hash-parity/golden/sha2_256-len1000.golden new file mode 100644 index 00000000000..ad875b0cbe1 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/sha2_256-len1000.golden @@ -0,0 +1 @@ +41edece42d63e8d9bf515a9ba6932e1c20cbc9f5a5d134645adb5db1b9737ea3 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/sha2_256-len127.golden b/plutus-core/test-crypto-hash-parity/golden/sha2_256-len127.golden new file mode 100644 index 00000000000..df17095b1e4 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/sha2_256-len127.golden @@ -0,0 +1 @@ +c57e9278af78fa3cab38667bef4ce29d783787a2f731d4e12200270f0c32320a \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/sha2_256-len128.golden b/plutus-core/test-crypto-hash-parity/golden/sha2_256-len128.golden new file mode 100644 index 00000000000..68a41eaf47d --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/sha2_256-len128.golden @@ -0,0 +1 @@ +6836cf13bac400e9105071cd6af47084dfacad4e5e302c94bfed24e013afb73e \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/sha2_256-len129.golden b/plutus-core/test-crypto-hash-parity/golden/sha2_256-len129.golden new file mode 100644 index 00000000000..d727f5e7c41 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/sha2_256-len129.golden @@ -0,0 +1 @@ +c12cb024a2e5551cca0e08fce8f1c5e314555cc3fef6329ee994a3db752166ae \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/sha2_256-len135.golden b/plutus-core/test-crypto-hash-parity/golden/sha2_256-len135.golden new file mode 100644 index 00000000000..acd32b6b87f --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/sha2_256-len135.golden @@ -0,0 +1 @@ +dfa58dfd72f3c7080d0249a7758fd3636872f63fa24b18473ed36f031e248347 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/sha2_256-len136.golden b/plutus-core/test-crypto-hash-parity/golden/sha2_256-len136.golden new file mode 100644 index 00000000000..a6851d8b3c8 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/sha2_256-len136.golden @@ -0,0 +1 @@ +6f0e44b9ce4ea61d52a3479c10f60ef916937f799f11964b7f1c7771063905c4 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/sha2_256-len137.golden b/plutus-core/test-crypto-hash-parity/golden/sha2_256-len137.golden new file mode 100644 index 00000000000..0f2cfce389b --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/sha2_256-len137.golden @@ -0,0 +1 @@ +b6dc2da678c065ebdce374ebe1842728277203ee1a9a29832f058cf013d5ad85 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/sha2_256-len55.golden b/plutus-core/test-crypto-hash-parity/golden/sha2_256-len55.golden new file mode 100644 index 00000000000..250bcd18234 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/sha2_256-len55.golden @@ -0,0 +1 @@ +9f4390f8d30c2dd92ec9f095b65e2b9ae9b0a925a5258e241c9f1e910f734318 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/sha2_256-len56.golden b/plutus-core/test-crypto-hash-parity/golden/sha2_256-len56.golden new file mode 100644 index 00000000000..3742105d485 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/sha2_256-len56.golden @@ -0,0 +1 @@ +b35439a4ac6f0948b6d6f9e3c6af0f5f590ce20f1bde7090ef7970686ec6738a \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/sha2_256-len63.golden b/plutus-core/test-crypto-hash-parity/golden/sha2_256-len63.golden new file mode 100644 index 00000000000..ef8629ceb69 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/sha2_256-len63.golden @@ -0,0 +1 @@ +7d3e74a05d7db15bce4ad9ec0658ea98e3f06eeecf16b4c6fff2da457ddc2f34 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/sha2_256-len64.golden b/plutus-core/test-crypto-hash-parity/golden/sha2_256-len64.golden new file mode 100644 index 00000000000..18083185b5f --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/sha2_256-len64.golden @@ -0,0 +1 @@ +ffe054fe7ae0cb6dc65c3af9b61d5209f439851db43d0ba5997337df154668eb \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/sha2_256-len65.golden b/plutus-core/test-crypto-hash-parity/golden/sha2_256-len65.golden new file mode 100644 index 00000000000..ec6d4b6395d --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/sha2_256-len65.golden @@ -0,0 +1 @@ +635361c48bb9eab14198e76ea8ab7f1a41685d6ad62aa9146d301d4f17eb0ae0 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/sha2_256-pseudorandom333.golden b/plutus-core/test-crypto-hash-parity/golden/sha2_256-pseudorandom333.golden new file mode 100644 index 00000000000..b092bf16d3d --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/sha2_256-pseudorandom333.golden @@ -0,0 +1 @@ +71be879b3acf9bdfac8db256edd7e75ec80bbbdda17a105d84249a90889539a6 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/sha3_256-abc.golden b/plutus-core/test-crypto-hash-parity/golden/sha3_256-abc.golden new file mode 100644 index 00000000000..e7bd6f1079f --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/sha3_256-abc.golden @@ -0,0 +1 @@ +3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/sha3_256-allbytes.golden b/plutus-core/test-crypto-hash-parity/golden/sha3_256-allbytes.golden new file mode 100644 index 00000000000..8944bd44c2e --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/sha3_256-allbytes.golden @@ -0,0 +1 @@ +9b04c091da96b997afb8f2585d608aebe9c4a904f7d52c8f28c7e4d2dd9fba5f \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/sha3_256-byte00.golden b/plutus-core/test-crypto-hash-parity/golden/sha3_256-byte00.golden new file mode 100644 index 00000000000..15282994142 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/sha3_256-byte00.golden @@ -0,0 +1 @@ +5d53469f20fef4f8eab52b88044ede69c77a6a68a60728609fc4a65ff531e7d0 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/sha3_256-byteff.golden b/plutus-core/test-crypto-hash-parity/golden/sha3_256-byteff.golden new file mode 100644 index 00000000000..714b219676c --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/sha3_256-byteff.golden @@ -0,0 +1 @@ +444b89ecce395aec5dc98f19defd3a23bca0822fc72226f58ca46a17eeeca442 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/sha3_256-empty.golden b/plutus-core/test-crypto-hash-parity/golden/sha3_256-empty.golden new file mode 100644 index 00000000000..da0dffd7671 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/sha3_256-empty.golden @@ -0,0 +1 @@ +a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/sha3_256-fox.golden b/plutus-core/test-crypto-hash-parity/golden/sha3_256-fox.golden new file mode 100644 index 00000000000..790d8940cfb --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/sha3_256-fox.golden @@ -0,0 +1 @@ +69070dda01975c8c120c3aada1b282394e7f032fa9cf32f4cb2259a0897dfc04 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/sha3_256-len1000.golden b/plutus-core/test-crypto-hash-parity/golden/sha3_256-len1000.golden new file mode 100644 index 00000000000..fafefbe16a6 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/sha3_256-len1000.golden @@ -0,0 +1 @@ +8f3934e6f7a15698fe0f396b95d8c4440929a8fa6eae140171c068b4549fbf81 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/sha3_256-len127.golden b/plutus-core/test-crypto-hash-parity/golden/sha3_256-len127.golden new file mode 100644 index 00000000000..da4e83852f5 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/sha3_256-len127.golden @@ -0,0 +1 @@ +7e377c5822478a844727ef215210bf8d4ae994ccc2088421bd984bc752fc5737 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/sha3_256-len128.golden b/plutus-core/test-crypto-hash-parity/golden/sha3_256-len128.golden new file mode 100644 index 00000000000..7ee761eef15 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/sha3_256-len128.golden @@ -0,0 +1 @@ +6ea6efe1dbf991d7f6d442dfe3d6036003071fa55fd438149fb845cb13f15906 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/sha3_256-len129.golden b/plutus-core/test-crypto-hash-parity/golden/sha3_256-len129.golden new file mode 100644 index 00000000000..5c70d699098 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/sha3_256-len129.golden @@ -0,0 +1 @@ +84ee1a04bcce09fb1f4507fbdfb81655d71a95e7b546f6859859ccf86d175ae8 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/sha3_256-len135.golden b/plutus-core/test-crypto-hash-parity/golden/sha3_256-len135.golden new file mode 100644 index 00000000000..2fbd297d1ea --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/sha3_256-len135.golden @@ -0,0 +1 @@ +8094bb53c44cfb1e67b7c30447f9a1c33696d2463ecc1d9c92538913392843c9 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/sha3_256-len136.golden b/plutus-core/test-crypto-hash-parity/golden/sha3_256-len136.golden new file mode 100644 index 00000000000..54927d6258c --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/sha3_256-len136.golden @@ -0,0 +1 @@ +3fc5559f14db8e453a0a3091edbd2bc25e11528d81c66fa570a4efdcc2695ee1 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/sha3_256-len137.golden b/plutus-core/test-crypto-hash-parity/golden/sha3_256-len137.golden new file mode 100644 index 00000000000..bdf52968c35 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/sha3_256-len137.golden @@ -0,0 +1 @@ +f8d6846cedd2ccfadf15c5879ef95af724d799eed7391fb1c91f95344e738614 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/sha3_256-len55.golden b/plutus-core/test-crypto-hash-parity/golden/sha3_256-len55.golden new file mode 100644 index 00000000000..6ce7cc53542 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/sha3_256-len55.golden @@ -0,0 +1 @@ +78c2a04624b9328ae0e40cb8cdd29980f6ff55abf2dca68e3412d09eed4b9d03 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/sha3_256-len56.golden b/plutus-core/test-crypto-hash-parity/golden/sha3_256-len56.golden new file mode 100644 index 00000000000..b60f2ba3649 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/sha3_256-len56.golden @@ -0,0 +1 @@ +f6fe8de5c8f5014786f07e9f7b08130f920dd55e587d47021686b26cf2323deb \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/sha3_256-len63.golden b/plutus-core/test-crypto-hash-parity/golden/sha3_256-len63.golden new file mode 100644 index 00000000000..2e9840c4f82 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/sha3_256-len63.golden @@ -0,0 +1 @@ +552b1c47d42b5591c4d191324be3a567d8f054dfed89eefa6674eaf3dec9ad86 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/sha3_256-len64.golden b/plutus-core/test-crypto-hash-parity/golden/sha3_256-len64.golden new file mode 100644 index 00000000000..eaf7e286220 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/sha3_256-len64.golden @@ -0,0 +1 @@ +043d104b5480439c7acff8831ee195183928d9b7f8fcb0c655a086a87923ffee \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/sha3_256-len65.golden b/plutus-core/test-crypto-hash-parity/golden/sha3_256-len65.golden new file mode 100644 index 00000000000..1f4d03a7932 --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/sha3_256-len65.golden @@ -0,0 +1 @@ +ac95a2d33713281e64db879a478235f492e80f584df4acd2466462bce4110154 \ No newline at end of file diff --git a/plutus-core/test-crypto-hash-parity/golden/sha3_256-pseudorandom333.golden b/plutus-core/test-crypto-hash-parity/golden/sha3_256-pseudorandom333.golden new file mode 100644 index 00000000000..9a2442efd7f --- /dev/null +++ b/plutus-core/test-crypto-hash-parity/golden/sha3_256-pseudorandom333.golden @@ -0,0 +1 @@ +7151ec07c27d45d03af0341be78249fb4c37549833b23b01c3a794cc427bfd55 \ No newline at end of file diff --git a/plutus-metatheory/plutus-metatheory.cabal b/plutus-metatheory/plutus-metatheory.cabal index 4ff1837e100..0eaea66e8f4 100644 --- a/plutus-metatheory/plutus-metatheory.cabal +++ b/plutus-metatheory/plutus-metatheory.cabal @@ -20,6 +20,14 @@ data-files: extra-source-files: file-embed/certificate-README.md +-- Mirrors plutus-core's with-crypto flag (default ON). When disabled +-- (-with-crypto), components that depend on plutus-core's crypto-using test +-- library are unavailable. See Note [The with-crypto flag] in +-- PlutusCore.Crypto.Utils. +flag with-crypto + manual: True + default: True + common lang default-language: Haskell2010 default-extensions: @@ -430,6 +438,12 @@ test-suite test-NEAT test-suite test-certifier import: lang, os-support, ghc-version-support + + -- Depends on plutus-core:untyped-plutus-core-testlib, which is unavailable + -- in a C-free (-with-crypto) build. See Note [The with-crypto flag]. + if !flag(with-crypto) + buildable: False + type: exitcode-stdio-1.0 main-is: Spec.hs hs-source-dirs: test/certifier From 3cf545181cf10ad70f6f5ba58fb75c61b345ca6b Mon Sep 17 00:00:00 2001 From: zeme Date: Wed, 1 Jul 2026 15:39:12 +0200 Subject: [PATCH 2/4] wip --- .github/workflows/cabal-build-all.yml | 2 +- cfree-plinth-flag-demo.sh | 209 ------------------ plinth-template | 1 - plutus-core/plutus-core.cabal | 54 ++--- .../src/PlutusCore/Crypto/BLS12_381/G1.hs | 21 -- .../src/PlutusCore/Crypto/BLS12_381/G2.hs | 21 -- .../PlutusCore/Crypto/BLS12_381/Pairing.hs | 5 - .../src/PlutusCore/Crypto/Ed25519.hs | 1 - .../plutus-core/src/PlutusCore/Crypto/Hash.hs | 17 +- .../src/PlutusCore/Crypto/Secp256k1.hs | 2 - .../src/PlutusCore/Crypto/Utils.hs | 27 --- plutus-core/test-crypto-hash-parity/Spec.hs | 37 +--- plutus-metatheory/plutus-metatheory.cabal | 7 +- 13 files changed, 42 insertions(+), 362 deletions(-) delete mode 100755 cfree-plinth-flag-demo.sh delete mode 160000 plinth-template diff --git a/.github/workflows/cabal-build-all.yml b/.github/workflows/cabal-build-all.yml index 47bd323adae..74e5dd41b08 100644 --- a/.github/workflows/cabal-build-all.yml +++ b/.github/workflows/cabal-build-all.yml @@ -31,6 +31,6 @@ jobs: uses: actions/checkout@v6.0.1 - name: Cold Build / ${{ matrix.ghc }} / x86_64-linux - run: | + run: | nix develop --no-warn-dirty --accept-flake-config .#${{ matrix.ghc }} \ --command bash -c 'cabal clean && cabal update && cabal build all --ghc-options=-Werror' diff --git a/cfree-plinth-flag-demo.sh b/cfree-plinth-flag-demo.sh deleted file mode 100755 index 0cbb5eb1b2f..00000000000 --- a/cfree-plinth-flag-demo.sh +++ /dev/null @@ -1,209 +0,0 @@ -#!/usr/bin/env bash -# -# cfree-plinth-flag-demo.sh -# -# Demonstrate that a Plinth script (IntersectMBO/plinth-template) can be WRITTEN -# and COMPILED with NO system cryptography C libraries (libsodium / libblst / -# libsecp256k1), in a self-contained non-nix sandbox, using ONLY the new -# `with-crypto` Cabal flag on plutus-core. -# -# Unlike the sub-library carve, the consumer makes NO source or .cabal changes: -# plinth-template depends on the ordinary plutus-core / plutus-tx / -# plutus-ledger-api / plutus-tx-plugin and merely sets -# -# package plutus-core -# flags: -with-crypto -# -# in its cabal.project. The flag drops cardano-crypto-class (and therefore the C -# libraries) from plutus-core's dependency closure; the cryptographic builtins -# become compile-only stubs. -# -# It: -# 1. Creates an isolated sandbox (its own ghcup + cabal store). -# 2. Downloads GHC 9.6.7 + cabal from ghcup (the web). -# 3. sdist's the monorepo plutus packages into a local file+noindex repo. -# 4. Clones plinth-template UNMODIFIED and adds only the -with-crypto flag. -# 5. Solves + builds, asserting cardano-crypto-class is never solved or built. -# 6. Runs the compiled validator to emit a CIP-57 blueprint. -# -# Usage: ./cfree-plinth-flag-demo.sh -set -euo pipefail - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -PLUTUS_REPO="${PLUTUS_REPO:-$(git -C "$SCRIPT_DIR" rev-parse --show-toplevel)}" -SANDBOX="${SANDBOX:-/tmp/plinth-flag-sandbox}" - -GHC_VERSION="${GHC_VERSION:-9.6.7}" -CABAL_VERSION="${CABAL_VERSION:-3.14.2.0}" -PLINTH_TEMPLATE_URL="https://github.com/IntersectMBO/plinth-template.git" - -# index-states matching the monorepo's cabal.project. -HACKAGE_INDEX="2026-06-22T23:30:49Z" -CHAP_INDEX="2026-06-18T17:45:00Z" - -# The monorepo packages plinth-template depends on (transitively). Only -# plutus-core carries the with-crypto flag; the rest inherit C-free-ness. -PLUTUS_PKGS=(plutus-core plutus-tx plutus-tx-plugin plutus-ledger-api) - -say() { printf '\n\033[1;36m== %s ==\033[0m\n' "$*"; } -die() { printf '\n\033[1;31mFAIL: %s\033[0m\n' "$*" >&2; exit 1; } - -# --------------------------------------------------------------------------- -# 1. Isolated sandbox -# --------------------------------------------------------------------------- -say "1. Creating isolated sandbox at $SANDBOX" -mkdir -p "$SANDBOX" -export GHCUP_INSTALL_BASE_PREFIX="$SANDBOX" -export CABAL_DIR="$SANDBOX/.cabal" -export BOOTSTRAP_HASKELL_NONINTERACTIVE=1 -export BOOTSTRAP_HASKELL_NO_UPGRADE=1 -export BOOTSTRAP_HASKELL_ADJUST_BASHRC=0 -export BOOTSTRAP_HASKELL_INSTALL_NO_STACK=1 -export BOOTSTRAP_HASKELL_GHC_VERSION="$GHC_VERSION" -export BOOTSTRAP_HASKELL_CABAL_VERSION="$CABAL_VERSION" -GHCUP_BIN="$SANDBOX/.ghcup/bin" -[ -d "$PLUTUS_REPO/plutus-core" ] || die "PLUTUS_REPO ($PLUTUS_REPO) is not the plutus monorepo" - -# --------------------------------------------------------------------------- -# 2. ghcup + GHC + cabal from the web -# --------------------------------------------------------------------------- -say "2. Installing ghcup + GHC $GHC_VERSION + cabal $CABAL_VERSION" -if [ ! -x "$GHCUP_BIN/ghcup" ]; then - curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh -fi -export PATH="$GHCUP_BIN:$PATH" -ghcup install ghc "$GHC_VERSION" --set || true -ghcup install cabal "$CABAL_VERSION" --set || true -hash -r 2>/dev/null || true -ghc --version >/dev/null 2>&1 || ghcup install ghc "$GHC_VERSION" --force --set -cabal --version >/dev/null 2>&1 || ghcup install cabal "$CABAL_VERSION" --force --set -hash -r 2>/dev/null || true -say "Toolchain:"; ghc --version; cabal --version -cabal update - -# --------------------------------------------------------------------------- -# 3. Show the host has NO crypto C libraries -# --------------------------------------------------------------------------- -say "3. System cryptography C libraries on this host" -for lib in libblst libsodium libsecp256k1; do - if command -v pkg-config >/dev/null 2>&1 && pkg-config --exists "$lib" 2>/dev/null; then - printf ' %-14s PRESENT\n' "$lib" - else - printf ' %-14s absent\n' "$lib" - fi -done -echo " (the C-free build below must not need any of them; we assert" -echo " cardano-crypto-class is never solved or built.)" - -# --------------------------------------------------------------------------- -# 4. sdist the monorepo plutus packages into a local repo -# --------------------------------------------------------------------------- -say "4. Building source tarballs of the monorepo plutus packages -> file+noindex repo" -REPO="$SANDBOX/local-plutus-repo" -rm -rf "$REPO"; mkdir -p "$REPO" -SDIST_PROJECT="$SANDBOX/cabal.project.sdist" -{ echo "packages:"; for p in "${PLUTUS_PKGS[@]}"; do echo " $PLUTUS_REPO/$p"; done; } > "$SDIST_PROJECT" -cabal sdist --project-file="$SDIST_PROJECT" "${PLUTUS_PKGS[@]}" --output-dir "$REPO" -ls -1 "$REPO"/*.tar.gz - -# --------------------------------------------------------------------------- -# 5. Clone plinth-template UNMODIFIED; add only the -with-crypto flag -# --------------------------------------------------------------------------- -say "5. Cloning plinth-template (no source/.cabal changes) and setting -with-crypto" -cd "$SANDBOX" -rm -rf plinth-template -git clone --depth 1 "$PLINTH_TEMPLATE_URL" plinth-template -cd plinth-template - -cat > cabal.project <=0.19.0.0 - --- Mirror the monorepo cabal.project's allow-newer (needed at this index-state, --- e.g. deriving-aeson hasn't bumped its aeson upper bound). -allow-newer: - , deriving-aeson:aeson - , microstache:aeson - , turtle:containers - , turtle:optparse-applicative -EOF - -# --------------------------------------------------------------------------- -# 6. Solve (must be crypto-free) -# --------------------------------------------------------------------------- -say "6. Checking the build plan is crypto-free" -cabal update -PLAN="$(cabal build all --dry-run 2>&1)" -echo "$PLAN" | grep -E "plutus-(core|tx|ledger-api)" || true -if echo "$PLAN" | grep -qi "cardano-crypto-class"; then - echo "$PLAN" | grep -i "cardano-crypto-class" - die "build plan pulls cardano-crypto-class -> NOT C-free" -fi -echo " -> build plan contains NO cardano-crypto-class. C-free solve confirmed." - -# --------------------------------------------------------------------------- -# 7. Build and assert cardano-crypto-class is never built -# --------------------------------------------------------------------------- -say "7. Building plinth-template (no crypto C libraries)" -BUILD_LOG="$SANDBOX/build.log" -cabal build all 2>&1 | tee "$BUILD_LOG" -grep -qiE "cardano-crypto-class.* \((lib|exe)" "$BUILD_LOG" \ - && die "cardano-crypto-class was built -> NOT C-free" || true -grep -qE "Compiling AuctionValidator" "$BUILD_LOG" \ - || die "the Plinth validator was not compiled by the plugin" -echo " -> plugin compiled the Plinth scripts; cardano-crypto-class was never built." - -# --------------------------------------------------------------------------- -# 8. Run the C-free-compiled validator: emit a CIP-57 blueprint -# --------------------------------------------------------------------------- -say "8. Running the C-free-compiled validator to emit a blueprint" -OUT="$SANDBOX/auction-blueprint.json" -cabal run -v0 gen-auction-validator-blueprint -- "$OUT" -[ -s "$OUT" ] || die "no blueprint produced" -echo " -> wrote $(wc -c < "$OUT") bytes to $OUT" -head -c 300 "$OUT"; echo - -say "SUCCESS" -cat <=0.13.2 - -- The cryptographic builtins (hashes, signature verification, BLS12-381) are - -- the only part of the library that needs the C cryptography libraries, all - -- via cardano-crypto-class. When -with-crypto is set, the modules under - -- PlutusCore.Crypto compile a C-free stub instead (see Note [The with-crypto - -- flag] in PlutusCore.Crypto.Utils), so the library has no C dependency. if flag(with-crypto) - -- >=2.3.1.0 for the bls12-381 multi-scalar-multiplication binding (blsMSM). build-depends: cardano-crypto-class >=2.3.1.0 cpp-options: -DWITH_CRYPTO else - -- C-free build: the hashes (needed at compile time) are computed with - -- crypton, which vendors its C sources and needs no system C library. - -- Pinned to the 1.0.x line, which depends on the standalone `memory` - -- package (so `Data.ByteArray.convert` has the needed instances; crypton - -- 1.1.x vendored its own byte-array and dropped that dependency). build-depends: , crypton ^>=1.0 , memory --- Verifies the C-free (crypton) hashes are byte-identical to the --- cardano-crypto-class hashes of the default build. Builds in BOTH flag modes --- (it only uses the flag-gated PlutusCore.Crypto.Hash, no crypto lib directly): --- the with-crypto build generates the goldens, the -with-crypto build checks --- them. See Note [The with-crypto flag] in PlutusCore.Crypto.Utils. test-suite crypto-hash-parity-test import: lang type: exitcode-stdio-1.0 @@ -484,8 +480,6 @@ test-suite untyped-plutus-core-test if (os(windows) || arch(wasm32)) buildable: False - -- Depends on untyped-plutus-core-testlib, which uses cardano-crypto-class and - -- is unavailable in a C-free (-with-crypto) build. See Note [The with-crypto flag]. if !flag(with-crypto) buildable: False @@ -509,8 +503,6 @@ library untyped-plutus-core-testlib if (os(windows) || arch(wasm32)) buildable: False - -- Uses cardano-crypto-class directly (signature/BLS test helpers), so it is - -- unavailable in a C-free (-with-crypto) build. See Note [The with-crypto flag]. if !flag(with-crypto) buildable: False @@ -874,8 +866,6 @@ executable cost-model-budgeting-bench import: lang main-is: Main.hs - -- Benchmarks the cryptographic builtins, so it uses cardano-crypto-class - -- directly and is unavailable in a C-free (-with-crypto) build. if !flag(with-crypto) buildable: False diff --git a/plutus-core/plutus-core/src/PlutusCore/Crypto/BLS12_381/G1.hs b/plutus-core/plutus-core/src/PlutusCore/Crypto/BLS12_381/G1.hs index 3efae596c09..95e9519d3ca 100644 --- a/plutus-core/plutus-core/src/PlutusCore/Crypto/BLS12_381/G1.hs +++ b/plutus-core/plutus-core/src/PlutusCore/Crypto/BLS12_381/G1.hs @@ -70,10 +70,6 @@ See also Note [Wrapping the BLS12-381 types in PlutusTx]. newtype Element = Element {unElement :: BlstBindings.Point1} deriving newtype (Eq) #else -{- See Note [The with-crypto flag] in PlutusCore.Crypto.Utils. Without the C -cryptography libraries a G1 element is represented by its compressed-point bytes; -this is enough to carry the type through the universe and to compile scripts, but -the group operations below are unavailable. -} newtype Element = Element {unElement :: ByteString} deriving newtype (Eq) #endif @@ -220,11 +216,6 @@ multiScalarMul ss p #else --- C-free stubs. See Note [The with-crypto flag] in PlutusCore.Crypto.Utils. --- The group operations require the blst C library and are therefore unavailable; --- 'compress'/'uncompress' remain total so the type can still be carried through --- the universe, parsed, and compiled. - add :: Element -> Element -> Element add = cryptoDisabled "bls12_381_G1_add" @@ -237,24 +228,15 @@ scalarMul = cryptoDisabled "bls12_381_G1_scalarMul" scalarMulE :: Integer -> Element -> BuiltinResult Element scalarMulE = cryptoDisabled "bls12_381_G1_scalarMul" --- | Just exposes the stored bytes: the only G1 operation that stays total in a --- C-free build, so that 'Show'/'Hashable' keep working. compress :: Element -> ByteString compress = unElement --- | Cannot validate the point without the C library, so it just stores the --- bytes. This lets the textual parser accept G1 literals when compiling scripts; --- the bytes are never interpreted as a curve point in a C-free build. uncompress :: ByteString -> Either BLS12_381_Error Element uncompress = Right . Element hashToGroup :: ByteString -> ByteString -> Either BLS12_381_Error Element hashToGroup = cryptoDisabled "bls12_381_G1_hashToGroup" --- The compressed zero/generator are fixed constants that PlutusTx lifts at --- COMPILE time, so they must be real values (not stubs) even in a C-free build. --- These literals are golden-checked (in a with-crypto build) to equal --- @compress blsZero@ / @compress blsGenerator@. offchain_zero :: Element offchain_zero = Element compressed_zero @@ -266,18 +248,15 @@ compressed_generator :: ByteString compressed_generator = unhex "97f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb" --- | Decode a hex string to a 'ByteString'. C-free helper for the constants above. unhex :: String -> ByteString unhex = pack . go where go (a : b : rest) = fromIntegral (digitToInt a * 16 + digitToInt b) : go rest go _ = [] --- | Memory usage of a G1 point (144 bytes) memSizeBytes :: Int memSizeBytes = 144 --- | Compressed size of a G1 point (48 bytes) compressedSizeBytes :: Int compressedSizeBytes = 48 diff --git a/plutus-core/plutus-core/src/PlutusCore/Crypto/BLS12_381/G2.hs b/plutus-core/plutus-core/src/PlutusCore/Crypto/BLS12_381/G2.hs index a69105233be..ab4b0520ba2 100644 --- a/plutus-core/plutus-core/src/PlutusCore/Crypto/BLS12_381/G2.hs +++ b/plutus-core/plutus-core/src/PlutusCore/Crypto/BLS12_381/G2.hs @@ -56,10 +56,6 @@ import PlutusCore.Crypto.Utils (cryptoDisabled) newtype Element = Element {unElement :: BlstBindings.Point2} deriving newtype (Eq) #else -{- See Note [The with-crypto flag] in PlutusCore.Crypto.Utils. Without the C -cryptography libraries a G2 element is represented by its compressed-point bytes; -this is enough to carry the type through the universe and to compile scripts, but -the group operations below are unavailable. -} newtype Element = Element {unElement :: ByteString} deriving newtype (Eq) #endif @@ -177,11 +173,6 @@ multiScalarMul ss p #else --- C-free stubs. See Note [The with-crypto flag] in PlutusCore.Crypto.Utils. --- The group operations require the blst C library and are therefore unavailable; --- 'compress'/'uncompress' remain total so the type can still be carried through --- the universe, parsed, and compiled. - add :: Element -> Element -> Element add = cryptoDisabled "bls12_381_G2_add" @@ -194,24 +185,15 @@ scalarMul = cryptoDisabled "bls12_381_G2_scalarMul" scalarMulE :: Integer -> Element -> BuiltinResult Element scalarMulE = cryptoDisabled "bls12_381_G2_scalarMul" --- | Just exposes the stored bytes: the only G2 operation that stays total in a --- C-free build, so that 'Show'/'Hashable' keep working. compress :: Element -> ByteString compress = unElement --- | Cannot validate the point without the C library, so it just stores the --- bytes. This lets the textual parser accept G2 literals when compiling scripts; --- the bytes are never interpreted as a curve point in a C-free build. uncompress :: ByteString -> Either BLS12_381_Error Element uncompress = Right . Element hashToGroup :: ByteString -> ByteString -> Either BLS12_381_Error Element hashToGroup = cryptoDisabled "bls12_381_G2_hashToGroup" --- The compressed zero/generator are fixed constants that PlutusTx lifts at --- COMPILE time, so they must be real values (not stubs) even in a C-free build. --- These literals are golden-checked (in a with-crypto build) to equal --- @compress blsZero@ / @compress blsGenerator@. offchain_zero :: Element offchain_zero = Element compressed_zero @@ -223,18 +205,15 @@ compressed_generator :: ByteString compressed_generator = unhex "93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8" --- | Decode a hex string to a 'ByteString'. C-free helper for the constants above. unhex :: String -> ByteString unhex = pack . go where go (a : b : rest) = fromIntegral (digitToInt a * 16 + digitToInt b) : go rest go _ = [] --- | Memory usage of a G2 point (288 bytes) memSizeBytes :: Int memSizeBytes = 288 --- | Compressed size of a G2 point (96 bytes) compressedSizeBytes :: Int compressedSizeBytes = 96 diff --git a/plutus-core/plutus-core/src/PlutusCore/Crypto/BLS12_381/Pairing.hs b/plutus-core/plutus-core/src/PlutusCore/Crypto/BLS12_381/Pairing.hs index bc4ce3ea6db..2f2c777f72c 100644 --- a/plutus-core/plutus-core/src/PlutusCore/Crypto/BLS12_381/Pairing.hs +++ b/plutus-core/plutus-core/src/PlutusCore/Crypto/BLS12_381/Pairing.hs @@ -39,9 +39,6 @@ import PlutusCore.Crypto.Utils (cryptoDisabled) newtype MlResult = MlResult {unMlResult :: BlstBindings.PT} deriving newtype (Eq) #else --- See Note [The with-crypto flag] in PlutusCore.Crypto.Utils. MlResult values --- are only ever created during evaluation, which is unavailable in a C-free --- build, so the representation is a placeholder. newtype MlResult = MlResult {unMlResult :: ByteString} deriving newtype (Eq) #endif @@ -95,8 +92,6 @@ identityMlResult = millerLoop G1.offchain_zero G2.offchain_zero #else --- C-free stubs. See Note [The with-crypto flag] in PlutusCore.Crypto.Utils. - millerLoop :: G1.Element -> G2.Element -> MlResult millerLoop = cryptoDisabled "bls12_381_millerLoop" diff --git a/plutus-core/plutus-core/src/PlutusCore/Crypto/Ed25519.hs b/plutus-core/plutus-core/src/PlutusCore/Crypto/Ed25519.hs index a3afafd1c4b..034cc1337c8 100644 --- a/plutus-core/plutus-core/src/PlutusCore/Crypto/Ed25519.hs +++ b/plutus-core/plutus-core/src/PlutusCore/Crypto/Ed25519.hs @@ -43,6 +43,5 @@ verifyEd25519Signature pk msg sig = loc :: Text loc = "Ed25519 signature verification" #else --- See Note [The with-crypto flag] in PlutusCore.Crypto.Utils. verifyEd25519Signature _pk _msg _sig = cryptoDisabled "verifyEd25519Signature" #endif diff --git a/plutus-core/plutus-core/src/PlutusCore/Crypto/Hash.hs b/plutus-core/plutus-core/src/PlutusCore/Crypto/Hash.hs index 42f68ba89fe..97c91917f8c 100644 --- a/plutus-core/plutus-core/src/PlutusCore/Crypto/Hash.hs +++ b/plutus-core/plutus-core/src/PlutusCore/Crypto/Hash.hs @@ -22,12 +22,6 @@ import Cardano.Crypto.Hash.SHA256 import Cardano.Crypto.Hash.SHA3_256 import Data.Proxy #else -{- C-free build (see Note [The with-crypto flag] in PlutusCore.Crypto.Utils). -Unlike the signature and BLS12-381 primitives, the hashes are needed at COMPILE -time (e.g. PlutusLedgerApi computes script hashes with blake2b_224), so they -cannot be stubbed. They are all standard algorithms, so we compute them with -@crypton@, which vendors its C sources and declares no @pkgconfig-depends@ (so -it needs no system C library) and produces byte-identical output. -} import Crypto.Hash (hashWith) import Crypto.Hash.Algorithms ( Blake2b_224 (..) @@ -40,12 +34,16 @@ import Crypto.Hash.Algorithms import Data.ByteArray qualified as BA #endif -sha2_256, sha3_256, blake2b_224, blake2b_256, keccak_256, ripemd_160 - :: BS.ByteString -> BS.ByteString +sha2_256 + , sha3_256 + , blake2b_224 + , blake2b_256 + , keccak_256 + , ripemd_160 + :: BS.ByteString -> BS.ByteString #ifdef WITH_CRYPTO --- cardano-crypto-class (libsodium-backed) implementations. sha2_256 = digest (Proxy @SHA256) sha3_256 = digest (Proxy @SHA3_256) blake2b_224 = digest (Proxy @Blake2b_224) @@ -55,7 +53,6 @@ ripemd_160 = digest (Proxy @RIPEMD160) #else --- crypton (vendored C, no system library) implementations. sha2_256 = BA.convert . hashWith SHA256 sha3_256 = BA.convert . hashWith SHA3_256 blake2b_224 = BA.convert . hashWith Blake2b_224 diff --git a/plutus-core/plutus-core/src/PlutusCore/Crypto/Secp256k1.hs b/plutus-core/plutus-core/src/PlutusCore/Crypto/Secp256k1.hs index 69eec20dbe0..95a934c1016 100644 --- a/plutus-core/plutus-core/src/PlutusCore/Crypto/Secp256k1.hs +++ b/plutus-core/plutus-core/src/PlutusCore/Crypto/Secp256k1.hs @@ -64,7 +64,6 @@ verifyEcdsaSecp256k1Signature pk msg sig = loc :: Text loc = "ECDSA SECP256k1 signature verification" #else --- See Note [The with-crypto flag] in PlutusCore.Crypto.Utils. verifyEcdsaSecp256k1Signature _pk _msg _sig = cryptoDisabled "verifyEcdsaSecp256k1Signature" #endif @@ -106,6 +105,5 @@ verifySchnorrSecp256k1Signature pk msg sig = loc :: Text loc = "Schnorr SECP256k1 signature verification" #else --- See Note [The with-crypto flag] in PlutusCore.Crypto.Utils. verifySchnorrSecp256k1Signature _pk _msg _sig = cryptoDisabled "verifySchnorrSecp256k1Signature" #endif diff --git a/plutus-core/plutus-core/src/PlutusCore/Crypto/Utils.hs b/plutus-core/plutus-core/src/PlutusCore/Crypto/Utils.hs index 8657dffeacb..d9efe7602ab 100644 --- a/plutus-core/plutus-core/src/PlutusCore/Crypto/Utils.hs +++ b/plutus-core/plutus-core/src/PlutusCore/Crypto/Utils.hs @@ -18,33 +18,6 @@ import Data.Kind (Type) import Data.Text (Text) import Text.Printf (printf) -{- Note [The with-crypto flag] -The cryptographic builtins (the hashes, the signature-verification primitives, -and the BLS12-381 primitives) are implemented in cardano-crypto-class, which -binds the C libraries libsodium, libblst and libsecp256k1. Because Cabal resolves -a package's @pkgconfig-depends@ at solve time for the whole package (see -https://github.com/haskell/cabal/issues/4087), merely depending on -cardano-crypto-class forces those C libraries to be present in order to even -/configure/ a build — which makes it impossible to write and compile a Plinth/ -Plutus script in an environment that does not have them installed. - -The @with-crypto@ Cabal flag (enabled by default) controls this. When it is on, -the modules under @PlutusCore.Crypto@ link cardano-crypto-class and behave -exactly as before. When it is off (@-with-crypto@), those modules compile a -C-free stub instead: the builtin /types/ (e.g. BLS12-381 group elements) keep a -representation good enough for the universe and the compiler, but the builtin -/operations/ are replaced by 'cryptoDisabled'. The upshot is that a @-with-crypto@ -build links no C cryptography library and can therefore be configured and built -anywhere, and Plinth scripts that use the cryptographic builtins can still be -COMPILED — but those builtins cannot be EVALUATED in such a build. - -The default build (@with-crypto@) is completely unchanged, so on-chain -evaluation, conformance and costing are unaffected. -} - --- | The denotation of a cryptographic builtin in a @-with-crypto@ build: the --- operation is unavailable because the C cryptography libraries were not linked. --- Used only by the C-free stubs under "PlutusCore.Crypto"; see --- Note [The with-crypto flag]. cryptoDisabled :: forall (a :: Type). String -> a cryptoDisabled op = error $ diff --git a/plutus-core/test-crypto-hash-parity/Spec.hs b/plutus-core/test-crypto-hash-parity/Spec.hs index ba560fc989c..f40b496d8b0 100644 --- a/plutus-core/test-crypto-hash-parity/Spec.hs +++ b/plutus-core/test-crypto-hash-parity/Spec.hs @@ -1,17 +1,5 @@ {-# LANGUAGE OverloadedStrings #-} -{- | Parity goldens for the cryptographic hash builtins. - -The golden files are generated by the DEFAULT (@with-crypto@) build, where -'PlutusCore.Crypto.Hash' is backed by cardano-crypto-class (libsodium). Running -the same suite in a C-free (@-with-crypto@) build, where the hashes are backed by -crypton, must reproduce them byte-for-byte. That is the parity guarantee: the -C-free build's hashes are identical to the on-chain implementation's. See -Note [The with-crypto flag] in PlutusCore.Crypto.Utils. - -Generate/refresh the goldens (with-crypto build): cabal test crypto-hash-parity-test --test-options=--accept -Check parity (C-free build): cabal test crypto-hash-parity-test --flags=-with-crypto --} module Main (main) where import PlutusCore.Crypto.Hash qualified as Hash @@ -24,8 +12,6 @@ import Data.Word (Word8) import Test.Tasty import Test.Tasty.Golden (goldenVsString) --- | Each hash builtin, exercised through the flag-gated 'PlutusCore.Crypto.Hash' --- module (so we test whatever implementation the build actually uses). hashImpls :: [(String, ByteString -> ByteString)] hashImpls = [ ("sha2_256", Hash.sha2_256) @@ -36,10 +22,6 @@ hashImpls = , ("ripemd_160", Hash.ripemd_160) ] --- | Inputs chosen to exercise empty input, small inputs, all byte values, and --- the block/rate boundaries of the various algorithms (SHA-2 64-byte blocks and --- 55/56-byte padding edges, BLAKE2b 128-byte blocks, SHA-3/Keccak-256 136-byte --- rate), plus a long and a pseudo-random input. inputs :: [(String, ByteString)] inputs = [ ("empty", BS.empty) @@ -50,19 +32,22 @@ inputs = , ("allbytes", BS.pack [0 .. 255]) , ("pseudorandom333", BS.pack [fromIntegral (i * 7 + 3) :: Word8 | i <- [0 .. 332 :: Int]]) ] - ++ [("len" ++ show n, BS.replicate n 0x61) | n <- [55, 56, 63, 64, 65, 127, 128, 129, 135, 136, 137, 1000]] + ++ [ ("len" ++ show n, BS.replicate n 0x61) + | n <- [55, 56, 63, 64, 65, 127, 128, 129, 135, 136, 137, 1000] + ] main :: IO () main = defaultMain $ testGroup "cryptographic hash goldens (with-crypto vs C-free parity)" - [ testGroup hname - [ goldenVsString - iname - ("test-crypto-hash-parity/golden/" ++ hname ++ "-" ++ iname ++ ".golden") - (pure (LBS.fromStrict (Base16.encode (impl input)))) - | (iname, input) <- inputs - ] + [ testGroup + hname + [ goldenVsString + iname + ("test-crypto-hash-parity/golden/" ++ hname ++ "-" ++ iname ++ ".golden") + (pure (LBS.fromStrict (Base16.encode (impl input)))) + | (iname, input) <- inputs + ] | (hname, impl) <- hashImpls ] diff --git a/plutus-metatheory/plutus-metatheory.cabal b/plutus-metatheory/plutus-metatheory.cabal index 0eaea66e8f4..7ce54f2973a 100644 --- a/plutus-metatheory/plutus-metatheory.cabal +++ b/plutus-metatheory/plutus-metatheory.cabal @@ -20,10 +20,7 @@ data-files: extra-source-files: file-embed/certificate-README.md --- Mirrors plutus-core's with-crypto flag (default ON). When disabled --- (-with-crypto), components that depend on plutus-core's crypto-using test --- library are unavailable. See Note [The with-crypto flag] in --- PlutusCore.Crypto.Utils. +-- Mirrors plutus-core's with-crypto flag; see plutus-core.cabal. flag with-crypto manual: True default: True @@ -439,8 +436,6 @@ test-suite test-NEAT test-suite test-certifier import: lang, os-support, ghc-version-support - -- Depends on plutus-core:untyped-plutus-core-testlib, which is unavailable - -- in a C-free (-with-crypto) build. See Note [The with-crypto flag]. if !flag(with-crypto) buildable: False From 63e193270349c2dab0c0446935188d06db1837c5 Mon Sep 17 00:00:00 2001 From: zeme Date: Wed, 1 Jul 2026 16:11:09 +0200 Subject: [PATCH 3/4] wi --- plutus-core/plutus-core.cabal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plutus-core/plutus-core.cabal b/plutus-core/plutus-core.cabal index 3260e9a8dd4..dcf0f7c5f44 100644 --- a/plutus-core/plutus-core.cabal +++ b/plutus-core/plutus-core.cabal @@ -61,7 +61,7 @@ flag with-cert -- The with-crypto flag (enabled by default) selects Plutus Core's cryptography -- backend, and is the single control for building without the system C crypto --- libraries. It is the only place this design is documented. +-- libraries. -- -- Enabled: the hash, signature-verification and BLS12-381 builtins are backed by -- cardano-crypto-class, which binds the system libraries libsodium, libblst and From 83d27d642e6d895ce2cbc6dbb2e51b617c5816f2 Mon Sep 17 00:00:00 2001 From: zeme Date: Thu, 2 Jul 2026 12:13:53 +0200 Subject: [PATCH 4/4] wip --- ...15332_lorenzo.calegari_with_crypto_flag.md | 12 +++++++++ plutus-core/plutus-core.cabal | 3 ++- .../src/PlutusCore/Crypto/BLS12_381/Error.hs | 25 +++++++++++++++++++ .../src/PlutusCore/Crypto/BLS12_381/G1.hs | 17 ++++--------- .../src/PlutusCore/Crypto/BLS12_381/G2.hs | 17 ++++--------- .../plutus-core/src/PlutusCore/Crypto/Hash.hs | 24 ++++++++++++------ 6 files changed, 66 insertions(+), 32 deletions(-) create mode 100644 plutus-core/changelog.d/20260702_115332_lorenzo.calegari_with_crypto_flag.md diff --git a/plutus-core/changelog.d/20260702_115332_lorenzo.calegari_with_crypto_flag.md b/plutus-core/changelog.d/20260702_115332_lorenzo.calegari_with_crypto_flag.md new file mode 100644 index 00000000000..54b24f44b64 --- /dev/null +++ b/plutus-core/changelog.d/20260702_115332_lorenzo.calegari_with_crypto_flag.md @@ -0,0 +1,12 @@ +### Added + +- A new `with-crypto` Cabal flag (enabled by default) for `plutus-core`. When + disabled (`-with-crypto`), `plutus-core` links no system cryptography C library + (libsodium / libblst / libsecp256k1): the hash builtins are computed by + `crypton` (byte-identical — see the `crypto-hash-parity-test`), the BLS12-381 + constants stay as their real hardcoded values, and the signature-verification + and BLS12-381 group/pairing operations become compile-only stubs. This lets + Plinth/Plutus scripts *compile* in environments where those C libraries are not + installed (Cabal otherwise cannot even solve, because `cardano-crypto-class` + declares them as `pkgconfig-depends`). Those builtins can still be compiled and + serialised but not *evaluated*; the default build is unaffected. diff --git a/plutus-core/plutus-core.cabal b/plutus-core/plutus-core.cabal index dcf0f7c5f44..bb80fcfee0d 100644 --- a/plutus-core/plutus-core.cabal +++ b/plutus-core/plutus-core.cabal @@ -397,7 +397,8 @@ library else build-depends: - , crypton ^>=1.0 + , base16-bytestring ^>=1.0 + , crypton ^>=1.0 , memory test-suite crypto-hash-parity-test diff --git a/plutus-core/plutus-core/src/PlutusCore/Crypto/BLS12_381/Error.hs b/plutus-core/plutus-core/src/PlutusCore/Crypto/BLS12_381/Error.hs index 35eb1d9a326..7419876515b 100644 --- a/plutus-core/plutus-core/src/PlutusCore/Crypto/BLS12_381/Error.hs +++ b/plutus-core/plutus-core/src/PlutusCore/Crypto/BLS12_381/Error.hs @@ -1,6 +1,31 @@ module PlutusCore.Crypto.BLS12_381.Error where +import Data.Bits (testBit) +import Data.ByteString qualified as BS + data BLS12_381_Error = HashToCurveDstTooBig -- DSTs can be at most 255 bytes long. + | BadCompressedData -- A compressed point failed structural (length/flag) validation. deriving stock (Show) + +{-| Structural validation of a compressed BLS12-381 point, shared by the C-free +G1 and G2 `uncompress` stubs (@expectedLen@ is 48 for G1, 96 for G2). It checks +exactly what can be checked without field arithmetic: the length, and the three +metadata bits of the leading byte -- the compression bit must be set, and if the +infinity bit is set the encoding must be the canonical @0xc0 00..00@. It +deliberately does NOT verify that the bytes encode a point on the curve or in the +subgroup (that needs blst), so it is weaker than the real `blsUncompress`; but it +rejects the malformed inputs the real decoder rejects on structure alone, rather +than accepting anything. -} +checkCompressed :: Int -> BS.ByteString -> Either BLS12_381_Error BS.ByteString +checkCompressed expectedLen bs + | BS.length bs /= expectedLen = Left BadCompressedData + | not (testBit b0 7) = Left BadCompressedData -- must be the compressed form + | testBit b0 6 = -- point at infinity: must be exactly 0xc0 00..00 + if b0 == 0xc0 && BS.all (== 0) (BS.drop 1 bs) + then Right bs + else Left BadCompressedData + | otherwise = Right bs + where + b0 = BS.head bs diff --git a/plutus-core/plutus-core/src/PlutusCore/Crypto/BLS12_381/G1.hs b/plutus-core/plutus-core/src/PlutusCore/Crypto/BLS12_381/G1.hs index 95e9519d3ca..1c4624422b5 100644 --- a/plutus-core/plutus-core/src/PlutusCore/Crypto/BLS12_381/G1.hs +++ b/plutus-core/plutus-core/src/PlutusCore/Crypto/BLS12_381/G1.hs @@ -45,9 +45,8 @@ import Data.Proxy (Proxy (..)) import PlutusCore.Crypto.BLS12_381.Bounds (msmScalarOutOfBounds) import PlutusCore.Crypto.BLS12_381.Error (BLS12_381_Error (..)) #else -import Data.ByteString (pack) -import Data.Char (digitToInt) -import PlutusCore.Crypto.BLS12_381.Error (BLS12_381_Error) +import Data.ByteString.Base16 qualified as Base16 +import PlutusCore.Crypto.BLS12_381.Error (BLS12_381_Error, checkCompressed) import PlutusCore.Crypto.Utils (cryptoDisabled) #endif @@ -232,7 +231,7 @@ compress :: Element -> ByteString compress = unElement uncompress :: ByteString -> Either BLS12_381_Error Element -uncompress = Right . Element +uncompress = fmap Element . checkCompressed compressedSizeBytes hashToGroup :: ByteString -> ByteString -> Either BLS12_381_Error Element hashToGroup = cryptoDisabled "bls12_381_G1_hashToGroup" @@ -242,17 +241,11 @@ offchain_zero = Element compressed_zero compressed_zero :: ByteString compressed_zero = - unhex "c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + Base16.decodeLenient "c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" compressed_generator :: ByteString compressed_generator = - unhex "97f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb" - -unhex :: String -> ByteString -unhex = pack . go - where - go (a : b : rest) = fromIntegral (digitToInt a * 16 + digitToInt b) : go rest - go _ = [] + Base16.decodeLenient "97f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb" memSizeBytes :: Int memSizeBytes = 144 diff --git a/plutus-core/plutus-core/src/PlutusCore/Crypto/BLS12_381/G2.hs b/plutus-core/plutus-core/src/PlutusCore/Crypto/BLS12_381/G2.hs index ab4b0520ba2..477f790592d 100644 --- a/plutus-core/plutus-core/src/PlutusCore/Crypto/BLS12_381/G2.hs +++ b/plutus-core/plutus-core/src/PlutusCore/Crypto/BLS12_381/G2.hs @@ -45,9 +45,8 @@ import Data.Proxy (Proxy (..)) import PlutusCore.Crypto.BLS12_381.Bounds (msmScalarOutOfBounds) import PlutusCore.Crypto.BLS12_381.Error (BLS12_381_Error (..)) #else -import Data.ByteString (pack) -import Data.Char (digitToInt) -import PlutusCore.Crypto.BLS12_381.Error (BLS12_381_Error) +import Data.ByteString.Base16 qualified as Base16 +import PlutusCore.Crypto.BLS12_381.Error (BLS12_381_Error, checkCompressed) import PlutusCore.Crypto.Utils (cryptoDisabled) #endif @@ -189,7 +188,7 @@ compress :: Element -> ByteString compress = unElement uncompress :: ByteString -> Either BLS12_381_Error Element -uncompress = Right . Element +uncompress = fmap Element . checkCompressed compressedSizeBytes hashToGroup :: ByteString -> ByteString -> Either BLS12_381_Error Element hashToGroup = cryptoDisabled "bls12_381_G2_hashToGroup" @@ -199,17 +198,11 @@ offchain_zero = Element compressed_zero compressed_zero :: ByteString compressed_zero = - unhex "c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + Base16.decodeLenient "c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" compressed_generator :: ByteString compressed_generator = - unhex "93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8" - -unhex :: String -> ByteString -unhex = pack . go - where - go (a : b : rest) = fromIntegral (digitToInt a * 16 + digitToInt b) : go rest - go _ = [] + Base16.decodeLenient "93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8" memSizeBytes :: Int memSizeBytes = 288 diff --git a/plutus-core/plutus-core/src/PlutusCore/Crypto/Hash.hs b/plutus-core/plutus-core/src/PlutusCore/Crypto/Hash.hs index 97c91917f8c..511fb15db3b 100644 --- a/plutus-core/plutus-core/src/PlutusCore/Crypto/Hash.hs +++ b/plutus-core/plutus-core/src/PlutusCore/Crypto/Hash.hs @@ -34,13 +34,23 @@ import Crypto.Hash.Algorithms import Data.ByteArray qualified as BA #endif -sha2_256 - , sha3_256 - , blake2b_224 - , blake2b_256 - , keccak_256 - , ripemd_160 - :: BS.ByteString -> BS.ByteString +-- | Hash a `ByteString` using the SHA-256 hash function. +sha2_256 :: BS.ByteString -> BS.ByteString + +-- | Hash a `ByteString` using the SHA3-256 hash function. +sha3_256 :: BS.ByteString -> BS.ByteString + +-- | Hash a `ByteString` using the Blake2b-224 hash function. +blake2b_224 :: BS.ByteString -> BS.ByteString + +-- | Hash a `ByteString` using the Blake2b-256 hash function. +blake2b_256 :: BS.ByteString -> BS.ByteString + +-- | Hash a `ByteString` using the Keccak-256 hash function. +keccak_256 :: BS.ByteString -> BS.ByteString + +-- | Hash a `ByteString` using the RIPEMD-160 hash function. +ripemd_160 :: BS.ByteString -> BS.ByteString #ifdef WITH_CRYPTO