Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

add plonk verifier plugin #1998

Draft
wants to merge 18 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@

ARG UBUNTU_VERSION=22.04
ARG GHC_VERSION=9.10.1
ARG GO_VERSION=1.23.0
ARG PROJECT_NAME=chainweb

# ############################################################################ #
Expand Down Expand Up @@ -100,6 +101,7 @@ RUN <<EOF
echo "TARGETPLATFORM: $TARGETPLATFORM"
EOF
ARG GHC_VERSION
ARG GO_VERSION
ARG TARGETPLATFORM
ARG DEBIAN_FRONTEND=noninteractive
RUN <<EOF
Expand Down Expand Up @@ -152,6 +154,26 @@ RUN --mount=type=cache,target=/root/.cabal,id=${TARGETPLATFORM} <<EOF
cabal update
EOF

# Install Go toolchain
ARG GO_TARGETPLATFORM=${TARGETPLATFORM/\//-}
ARG GOLANG_ARCHIVE=go${GO_VERSION}.${GO_TARGETPLATFORM}.tar.gz
ENV PATH="${PATH}:/usr/local/go/bin"
RUN <<EOF
curl -L https://go.dev/dl/$GOLANG_ARCHIVE -O
rm -rf /usr/local/go && tar -C /usr/local -xzf $GOLANG_ARCHIVE
rm -f go${GO_VERSION}.${GO_TARGETPLATFORM}.tar.gz
go version
EOF

# Install Rust toolchain
ENV PATH="${PATH}:/root/.cargo/bin"
RUN <<EOF
curl -sSf https://sh.rustup.rs | sh -s -- -y
curl -LsSf https://get.nexte.st/latest/linux | tar zxf - -C ${CARGO_HOME:-/root/.cargo}/bin
cargo version
rustc --version
EOF

# ############################################################################ #
# Builds
# ############################################################################ #
Expand Down Expand Up @@ -319,6 +341,7 @@ EOF
# Chainweb-node Application

FROM chainweb-runtime AS chainweb-node
ENV PATH=/chainweb:$PATH
COPY --from=chainweb-build-node /chainweb/artifacts/chainweb-node .
COPY --from=chainweb-build-node /chainweb/LICENSE .
COPY --from=chainweb-build-node /chainweb/README.md .
Expand Down
14 changes: 14 additions & 0 deletions cabal.project
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,20 @@ source-repository-package
tag: 174af3523616c8fe01449da5ccbb9f16df097ac3
--sha256: 0grssxgjygi4ijiqaa87diwv6sdqz77hldf3lr4k7p93w35lhlci


-- Required for the plonk verifier
source-repository-package
type: git
location: https://github.com/argumentcomputer/lurk-hs
tag: 77bdf6f4d289d8274f839822d590d05758bfb53d
--sha256: sha256-kVFIy+Aj3TNJpsM1Cs/5uGmzeWwHKYWjjCQ+L1/XOj8=

-- source-repository-package
-- type: git
-- location: https://github.com/rsoeldner/lurk-hs.git
-- tag: 9daa93205759d3752e73623bc1f77973b1617fd3
-- --sha256: sha256-kntJeZiLPx6SHmqIULwDRSri0z5GvbPXajC1aYkQMo8

-- -------------------------------------------------------------------------- --
-- Relaxed Bounds

Expand Down
8 changes: 5 additions & 3 deletions cabal.project.freeze
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,8 @@ constraints: any.Cabal ==3.10.2.0,
any.groups ==0.5.3,
any.growable-vector ==0.1,
any.half ==0.3.1,
any.happy ==1.20.1.1,
any.happy ==2.0.1,
any.happy-lib ==2.0.1,
any.hashable ==1.5.0.0,
hashable -arch-native -random-initial-seed,
any.hashes ==0.3.0.1,
Expand Down Expand Up @@ -267,6 +268,7 @@ constraints: any.Cabal ==3.10.2.0,
parsers +attoparsec +binary +parsec,
any.patience ==0.3,
any.pem ==0.2.4,
any.plonk-verify ==0.1.0,
any.poly ==0.5.1.0,
poly +sparse,
any.pretty ==1.1.3.6,
Expand Down Expand Up @@ -434,5 +436,5 @@ constraints: any.Cabal ==3.10.2.0,
yet-another-logger -tbmqueue,
any.zigzag ==0.1.0.0,
any.zlib ==0.7.1.0,
zlib -bundled-c-zlib +non-blocking-ffi +pkg-config
index-state: hackage.haskell.org 2024-09-18T21:54:46Z
zlib -bundled-c-zlib +non-blocking-ffi -pkg-config
index-state: hackage.haskell.org 2024-09-22T05:23:19Z
7 changes: 7 additions & 0 deletions chainweb.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ extra-source-files:

rewards/miner_rewards.csv

-- verifier assets

verifier-assets/v1.0.8-testnet.bin

-- pact test data

pact/coin-contract/*.repl
Expand Down Expand Up @@ -264,6 +268,7 @@ library
, Chainweb.VerifierPlugin.Hyperlane.Message.After225
, Chainweb.VerifierPlugin.Hyperlane.Message.Before225
, Chainweb.VerifierPlugin.Hyperlane.Utils
, Chainweb.VerifierPlugin.Plonk
, Chainweb.Version
, Chainweb.Version.Development
, Chainweb.Version.Guards
Expand Down Expand Up @@ -460,6 +465,7 @@ library
, warp-tls >= 3.4
, yaml >= 0.11
, yet-another-logger >= 0.4.1
, plonk-verify

if flag(ed25519)
cpp-options: -DWITH_ED25519=1
Expand Down Expand Up @@ -505,6 +511,7 @@ test-suite chainweb-tests
Chainweb.Test.Pact.GrandHash
Chainweb.Test.Pact.PactMultiChainTest
Chainweb.Test.Pact.VerifierPluginTest
Chainweb.Test.Pact.VerifierPluginTest.PlonkVerifier
Chainweb.Test.Pact.VerifierPluginTest.Transaction
Chainweb.Test.Pact.VerifierPluginTest.Transaction.Message.After225
Chainweb.Test.Pact.VerifierPluginTest.Transaction.Message.Before225
Expand Down
4 changes: 4 additions & 0 deletions default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ let haskellSrc = with nix-filter.lib; filter {
zlib
pkg-config
sqlite
cargo
rustc
cargo
go
];
modules = [
{
Expand Down
81 changes: 81 additions & 0 deletions src/Chainweb/VerifierPlugin/Plonk.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE ImportQualifiedPost #-}

-- |

module Chainweb.VerifierPlugin.Plonk
(plugin) where

import Control.Lens
import Control.Monad
import Control.Monad.Except
import Control.Monad.Trans.Class

import Data.Bifunctor
import Data.ByteString.Base16 qualified as B16
import Data.ByteString.Short qualified as BS
import Data.Map.Strict qualified as M
import Data.Maybe
import Data.Set qualified as Set
import Data.Text qualified as T
import Data.Text.Encoding qualified as T

import GHC.IO

import Pact.Types.Capability
import Pact.Types.Exp
import Pact.Types.PactValue

import PlonkBn254.Utils.EmbedVMKeys qualified as P
import PlonkBn254.Verify qualified as P

-- internal modules

import Chainweb.Utils
import Chainweb.VerifierPlugin

-- | Verifying Keys
--
-- Providing a (compile-time) mapping of the @VMKey@.
verifyingKeys :: M.Map T.Text P.VMKey
verifyingKeys = M.fromList $ map (over _1 T.pack) $$(P.embedVMKeys "bin" "verifier-assets")


-- The plugin verifies Plonk zero-knowledge proofs within the context of Pact transactions.
--
-- [@proof@] A Base-64 URL encoded message without padding.
--
-- [@caps@] A set containing precisely one 'SigCapability' with three arguments:
-- 1. A UTF-8 encoded string identifying the verifying key.
-- 2. A Base-64 URL encoded message (without padding) representing the program ID.
-- 3. A Base-16 encoded message representing the public parameters.
plugin :: VerifierPlugin
plugin = VerifierPlugin $ \_ proof caps gasRef -> do
chargeGas gasRef 100
case proof of
PLiteral (LString proofMsg) -> do
plonkProof <- P.Proof . BS.toShort <$> decodeB64UrlNoPaddingText proofMsg

SigCapability _ capArgs <- case Set.toList caps of
[cap] -> pure cap
_ -> throwError $ VerifierError "Expected single capability."

(vk, progId, pub) <- case capArgs of
[PLiteral (LString vk), PLiteral (LString progId), PLiteral (LString pub)] -> do
vk' <- maybe (throwError $ VerifierError "Unknown verifier key.") pure $ M.lookup vk verifyingKeys

progId' <- P.ProgramId . BS.toShort <$> decodeB64UrlNoPaddingText progId

let spub = fromMaybe pub $ T.stripPrefix "0x" pub
pub' <- liftEither . first (const (VerifierError "Base16 decoding failure.")) $
P.PublicParameter . BS.toShort <$> B16.decode (T.encodeUtf8 spub)

pure (vk', progId', pub')
_ -> throwError $ VerifierError "Incorrect number of capability arguments. Expected vk, progId, pub."

withness <- lift $ unsafeIOToST $ P.verify vk plonkProof progId pub
unless withness $ throwError $ VerifierError "Verification failed."

_ -> throwError $ VerifierError "Expected proof data as a string."
2 changes: 1 addition & 1 deletion src/Chainweb/Version/Development.hs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ devnet = ChainwebVersion
, _disableMempoolSync = False
}
, _versionVerifierPluginNames = AllChains $ End
$ Set.fromList $ map VerifierName ["hyperlane_v3_message", "allow"]
$ Set.fromList $ map VerifierName ["hyperlane_v3_message", "allow", "plonk"]
, _versionQuirks = noQuirks
, _versionServiceDate = Nothing
}
2 changes: 1 addition & 1 deletion src/Chainweb/Version/RecapDevelopment.hs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ recapDevnet = ChainwebVersion
, _disableMempoolSync = False
}
, _versionVerifierPluginNames = AllChains $
(600, Set.fromList $ map VerifierName ["hyperlane_v3_message", "allow"]) `Above`
(600, Set.fromList $ map VerifierName ["hyperlane_v3_message", "allow", "plonk"]) `Above`
End mempty
, _versionQuirks = noQuirks
, _versionServiceDate = Nothing
Expand Down
3 changes: 3 additions & 0 deletions src/Chainweb/Version/Utils.hs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ import Chainweb.VerifierPlugin
import qualified Chainweb.VerifierPlugin.Allow
import qualified Chainweb.VerifierPlugin.Hyperlane.Announcement
import qualified Chainweb.VerifierPlugin.Hyperlane.Message
import qualified Chainweb.VerifierPlugin.Plonk

import Control.Lens
import Data.Foldable
Expand Down Expand Up @@ -478,4 +479,6 @@ allVerifierPlugins = M.fromList $ map (over _1 VerifierName)

, ("hyperlane_v3_announcement", Chainweb.VerifierPlugin.Hyperlane.Announcement.plugin)
, ("hyperlane_v3_message", Chainweb.VerifierPlugin.Hyperlane.Message.plugin)

, ("plonk", Chainweb.VerifierPlugin.Plonk.plugin)
]
4 changes: 3 additions & 1 deletion test/Chainweb/Test/Pact/VerifierPluginTest.hs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ import Test.Tasty

import qualified Chainweb.Test.Pact.VerifierPluginTest.Transaction
import qualified Chainweb.Test.Pact.VerifierPluginTest.Unit
import qualified Chainweb.Test.Pact.VerifierPluginTest.PlonkVerifier

tests :: TestTree
tests = testGroup "Chainweb.Test.Pact.VerifierPluginTest"
[ Chainweb.Test.Pact.VerifierPluginTest.Unit.tests
, Chainweb.Test.Pact.VerifierPluginTest.Transaction.tests
]
, Chainweb.Test.Pact.VerifierPluginTest.PlonkVerifier.tests
]
Loading
Loading