diff --git a/config/gasCost.go b/config/gasCost.go index 8cf0b3638..cc20f4cfb 100644 --- a/config/gasCost.go +++ b/config/gasCost.go @@ -200,6 +200,11 @@ type CryptoAPICost struct { VerifySecp256r1 uint64 VerifyBLSSignatureShare uint64 VerifyBLSMultiSig uint64 + VerifyPlonkSig uint64 + VerifyGroth16Sig uint64 + MapToCurveECC uint64 + PairingCheckECC uint64 + MultiExpECC uint64 } // ManagedBufferAPICost defines the managed buffer operations gas cost config structure diff --git a/config/gasSchedule.go b/config/gasSchedule.go index 55866fd55..f8f810744 100644 --- a/config/gasSchedule.go +++ b/config/gasSchedule.go @@ -465,6 +465,11 @@ func FillGasMapCryptoAPICosts(value uint64) map[string]uint64 { gasMap["VerifySecp256r1"] = value gasMap["VerifyBLSSignatureShare"] = value gasMap["VerifyBLSMultiSig"] = value + gasMap["VerifyPlonkSig"] = value + gasMap["VerifyGroth16Sig"] = value + gasMap["MapToCurveECC"] = value + gasMap["PairingCheckECC"] = value + gasMap["MultiExpECC"] = value return gasMap } diff --git a/executor/vmHooks.go b/executor/vmHooks.go index 31ad90ddb..df1eede0a 100644 --- a/executor/vmHooks.go +++ b/executor/vmHooks.go @@ -17,6 +17,7 @@ type VMHooks interface { SmallIntVMHooks CryptoVMHooks UnsafeVMHooks + ZKCryptoVMHooks } type MainVMHooks interface { @@ -327,3 +328,13 @@ type UnsafeVMHooks interface { ManagedGetErrorWithIndex(index int32, errorHandle int32) ManagedGetLastError(errorHandle int32) } + +type ZKCryptoVMHooks interface { + ManagedVerifyGroth16(curveID int32, proofHandle int32, vkHandle int32, pubWitnessHandle int32) int32 + ManagedVerifyPlonk(curveID int32, proofHandle int32, vkHandle int32, pubWitnessHandle int32) int32 + ManagedAddEC(curveID int32, groupID int32, point1Handle int32, point2Handle int32, resultHandle int32) int32 + ManagedMulEC(curveID int32, groupID int32, pointHandle int32, scalarHandle int32, resultHandle int32) int32 + ManagedMultiExpEC(curveID int32, groupID int32, pointsHandle int32, scalarsHandle int32, resultHandle int32) int32 + ManagedMapToCurveEC(curveID int32, groupID int32, elementHandle int32, resultHandle int32) int32 + ManagedPairingChecksEC(curveID int32, pointsG1Handle int32, pointsG2Handle int32) int32 +} diff --git a/executor/wrapper/wrapperVMHooks.go b/executor/wrapper/wrapperVMHooks.go index 96e2e4cae..8069fd4f2 100644 --- a/executor/wrapper/wrapperVMHooks.go +++ b/executor/wrapper/wrapperVMHooks.go @@ -2450,3 +2450,66 @@ func (w *WrapperVMHooks) ManagedGetLastError(errorHandle int32) { w.wrappedVMHooks.ManagedGetLastError(errorHandle) w.logger.LogVMHookCallAfter(callInfo) } + +// ManagedVerifyGroth16 VM hook wrapper +func (w *WrapperVMHooks) ManagedVerifyGroth16(curveID int32, proofHandle int32, vkHandle int32, pubWitnessHandle int32) int32 { + callInfo := fmt.Sprintf("ManagedVerifyGroth16(%d, %d, %d, %d)", curveID, proofHandle, vkHandle, pubWitnessHandle) + w.logger.LogVMHookCallBefore(callInfo) + result := w.wrappedVMHooks.ManagedVerifyGroth16(curveID, proofHandle, vkHandle, pubWitnessHandle) + w.logger.LogVMHookCallAfter(callInfo) + return result +} + +// ManagedVerifyPlonk VM hook wrapper +func (w *WrapperVMHooks) ManagedVerifyPlonk(curveID int32, proofHandle int32, vkHandle int32, pubWitnessHandle int32) int32 { + callInfo := fmt.Sprintf("ManagedVerifyPlonk(%d, %d, %d, %d)", curveID, proofHandle, vkHandle, pubWitnessHandle) + w.logger.LogVMHookCallBefore(callInfo) + result := w.wrappedVMHooks.ManagedVerifyPlonk(curveID, proofHandle, vkHandle, pubWitnessHandle) + w.logger.LogVMHookCallAfter(callInfo) + return result +} + +// ManagedAddEC VM hook wrapper +func (w *WrapperVMHooks) ManagedAddEC(curveID int32, groupID int32, point1Handle int32, point2Handle int32, resultHandle int32) int32 { + callInfo := fmt.Sprintf("ManagedAddEC(%d, %d, %d, %d, %d)", curveID, groupID, point1Handle, point2Handle, resultHandle) + w.logger.LogVMHookCallBefore(callInfo) + result := w.wrappedVMHooks.ManagedAddEC(curveID, groupID, point1Handle, point2Handle, resultHandle) + w.logger.LogVMHookCallAfter(callInfo) + return result +} + +// ManagedMulEC VM hook wrapper +func (w *WrapperVMHooks) ManagedMulEC(curveID int32, groupID int32, pointHandle int32, scalarHandle int32, resultHandle int32) int32 { + callInfo := fmt.Sprintf("ManagedMulEC(%d, %d, %d, %d, %d)", curveID, groupID, pointHandle, scalarHandle, resultHandle) + w.logger.LogVMHookCallBefore(callInfo) + result := w.wrappedVMHooks.ManagedMulEC(curveID, groupID, pointHandle, scalarHandle, resultHandle) + w.logger.LogVMHookCallAfter(callInfo) + return result +} + +// ManagedMultiExpEC VM hook wrapper +func (w *WrapperVMHooks) ManagedMultiExpEC(curveID int32, groupID int32, pointsHandle int32, scalarsHandle int32, resultHandle int32) int32 { + callInfo := fmt.Sprintf("ManagedMultiExpEC(%d, %d, %d, %d, %d)", curveID, groupID, pointsHandle, scalarsHandle, resultHandle) + w.logger.LogVMHookCallBefore(callInfo) + result := w.wrappedVMHooks.ManagedMultiExpEC(curveID, groupID, pointsHandle, scalarsHandle, resultHandle) + w.logger.LogVMHookCallAfter(callInfo) + return result +} + +// ManagedMapToCurveEC VM hook wrapper +func (w *WrapperVMHooks) ManagedMapToCurveEC(curveID int32, groupID int32, elementHandle int32, resultHandle int32) int32 { + callInfo := fmt.Sprintf("ManagedMapToCurveEC(%d, %d, %d, %d)", curveID, groupID, elementHandle, resultHandle) + w.logger.LogVMHookCallBefore(callInfo) + result := w.wrappedVMHooks.ManagedMapToCurveEC(curveID, groupID, elementHandle, resultHandle) + w.logger.LogVMHookCallAfter(callInfo) + return result +} + +// ManagedPairingChecksEC VM hook wrapper +func (w *WrapperVMHooks) ManagedPairingChecksEC(curveID int32, pointsG1Handle int32, pointsG2Handle int32) int32 { + callInfo := fmt.Sprintf("ManagedPairingChecksEC(%d, %d, %d)", curveID, pointsG1Handle, pointsG2Handle) + w.logger.LogVMHookCallBefore(callInfo) + result := w.wrappedVMHooks.ManagedPairingChecksEC(curveID, pointsG1Handle, pointsG2Handle) + w.logger.LogVMHookCallAfter(callInfo) + return result +} diff --git a/go.mod b/go.mod index 97166a2d4..2c3865bfb 100644 --- a/go.mod +++ b/go.mod @@ -6,40 +6,53 @@ require ( github.com/awalterschulze/gographviz v2.0.3+incompatible github.com/btcsuite/btcd/btcec/v2 v2.3.2 github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 + github.com/consensys/gnark v0.12.0 + github.com/consensys/gnark-crypto v0.17.0 github.com/gogo/protobuf v1.3.2 github.com/mitchellh/mapstructure v1.5.0 github.com/multiversx/mx-chain-core-go v1.4.0 - github.com/multiversx/mx-chain-crypto-go v1.3.0 + github.com/multiversx/mx-chain-crypto-go v1.3.1-0.20250821174823-216aa95326f0 github.com/multiversx/mx-chain-logger-go v1.1.0 github.com/multiversx/mx-chain-scenario-go v1.6.0 github.com/multiversx/mx-chain-storage-go v1.1.0 github.com/multiversx/mx-chain-vm-common-go v1.6.0 github.com/multiversx/mx-components-big-int v1.1.0 github.com/pelletier/go-toml v1.9.3 - github.com/stretchr/testify v1.8.1 + github.com/stretchr/testify v1.10.0 github.com/urfave/cli/v2 v2.27.1 - golang.org/x/crypto v0.3.0 + golang.org/x/crypto v0.33.0 ) require ( github.com/TwiN/go-color v1.1.0 // indirect + github.com/bits-and-blooms/bitset v1.20.0 // indirect + github.com/blang/semver/v4 v4.0.0 // indirect github.com/btcsuite/btcd/btcutil v1.1.3 // indirect + github.com/consensys/bavard v0.1.29 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect github.com/denisbrodbeck/machineid v1.0.1 // indirect + github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/golang/protobuf v1.5.2 // indirect + github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 // indirect github.com/hashicorp/golang-lru v0.6.0 // indirect github.com/herumi/bls-go-binary v1.28.2 // indirect - github.com/kr/pretty v0.3.0 // indirect + github.com/ingonyama-zk/icicle/v3 v3.1.1-0.20241118092657-fccdb2f0921b // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/mr-tron/base58 v1.2.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/rogpeppe/go-internal v1.8.0 // indirect + github.com/ronanh/intcomp v1.1.0 // indirect + github.com/rs/zerolog v1.33.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/stretchr/objx v0.5.0 // indirect + github.com/stretchr/objx v0.5.2 // indirect + github.com/x448/float16 v0.8.4 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect - golang.org/x/sys v0.2.0 // indirect + golang.org/x/sync v0.11.0 // indirect + golang.org/x/sys v0.30.0 // indirect google.golang.org/protobuf v1.28.0 // indirect - gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v3 v3.0.1 // indirect + rsc.io/tmplfunc v0.0.3 // indirect ) diff --git a/go.sum b/go.sum index afd8927f6..dafa4d8e5 100644 --- a/go.sum +++ b/go.sum @@ -3,6 +3,10 @@ github.com/TwiN/go-color v1.1.0/go.mod h1:aKVf4e1mD4ai2FtPifkDPP5iyoCwiK08YGzGwe github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/awalterschulze/gographviz v2.0.3+incompatible h1:9sVEXJBJLwGX7EQVhLm2elIKCm7P2YHFC8v6096G09E= github.com/awalterschulze/gographviz v2.0.3+incompatible/go.mod h1:GEV5wmg4YquNw7v1kkyoX9etIk8yVmXj+AkDHuuETHs= +github.com/bits-and-blooms/bitset v1.20.0 h1:2F+rfL86jE2d/bmw7OhqUg2Sj/1rURkBn3MdfoPyRVU= +github.com/bits-and-blooms/bitset v1.20.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= +github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= github.com/btcsuite/btcd v0.22.0-beta.0.20220111032746-97732e52810c/go.mod h1:tjmYdS6MLJ5/s0Fj4DbLgSbDHbEqLJrtnHecBFkdz5M= github.com/btcsuite/btcd v0.23.0/go.mod h1:0QJIIN1wwIXF/3G/m87gIwGniDMDQqjVn4SZgnFpsYY= @@ -26,9 +30,15 @@ github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/consensys/bavard v0.1.29 h1:fobxIYksIQ+ZSrTJUuQgu+HIJwclrAPcdXqd7H2hh1k= +github.com/consensys/bavard v0.1.29/go.mod h1:k/zVjHHC4B+PQy1Pg7fgvG3ALicQw540Crag8qx+dZs= +github.com/consensys/gnark v0.12.0 h1:XgQ1kh2R6fHuf5fBYl+i7TxR+QTbGQuZaaqqkk5nLO0= +github.com/consensys/gnark v0.12.0/go.mod h1:WDvuIQ8qrRvWT9NhTrib84WeLVBSGhSTrbQBXs1yR5w= +github.com/consensys/gnark-crypto v0.17.0 h1:vKDhZMOrySbpZDCvGMOELrHFv/A9mJ7+9I8HEfRZSkI= +github.com/consensys/gnark-crypto v0.17.0/go.mod h1:A2URlMHUT81ifJ0UlLzSlm7TmnE3t7VxEThApdMukJw= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -42,6 +52,9 @@ github.com/denisbrodbeck/machineid v1.0.1 h1:geKr9qtkB876mXguW2X6TU4ZynleN6ezuMS github.com/denisbrodbeck/machineid v1.0.1/go.mod h1:dJUwb7PTidGDeYyUBmXZ2GphQBbjJCrnectwCyxcUSI= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= +github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -58,35 +71,48 @@ github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k= +github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= +github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/hashicorp/golang-lru v0.6.0 h1:uL2shRDx7RTrOrTCUZEGP/wJUFiUI8QT6E7z5o8jga4= github.com/hashicorp/golang-lru v0.6.0/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/herumi/bls-go-binary v1.28.2 h1:F0AezsC0M1a9aZjk7g0l2hMb1F56Xtpfku97pDndNZE= github.com/herumi/bls-go-binary v1.28.2/go.mod h1:O4Vp1AfR4raRGwFeQpr9X/PQtncEicMoOe6BQt1oX0Y= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ingonyama-zk/icicle/v3 v3.1.1-0.20241118092657-fccdb2f0921b h1:AvQTK7l0PTHODD06PVQX1Tn2o29sRIaKIDOvTJmKurY= +github.com/ingonyama-zk/icicle/v3 v3.1.1-0.20241118092657-fccdb2f0921b/go.mod h1:e0JHb27/P6WorCJS3YolbY5XffS4PGBuoW38OthLkDs= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= -github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leanovate/gopter v0.2.11 h1:vRjThO1EKPb/1NsDXuDrzldR28RLkBflWYcU9CvzWu4= +github.com/leanovate/gopter v0.2.11/go.mod h1:aK3tzZP/C+p1m3SPRE4SYZFGP7jjkuSI4f7Xvpt0S9c= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= +github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= +github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/multiversx/mx-chain-core-go v1.4.0 h1:p6FbfCzvMXF54kpS0B5mrjNWYpq4SEQqo0UvrMF7YVY= github.com/multiversx/mx-chain-core-go v1.4.0/go.mod h1:IO+vspNan+gT0WOHnJ95uvWygiziHZvfXpff6KnxV7g= -github.com/multiversx/mx-chain-crypto-go v1.3.0 h1:0eK2bkDOMi8VbSPrB1/vGJSYT81IBtfL4zw+C4sWe/k= -github.com/multiversx/mx-chain-crypto-go v1.3.0/go.mod h1:nPIkxxzyTP8IquWKds+22Q2OJ9W7LtusC7cAosz7ojM= +github.com/multiversx/mx-chain-crypto-go v1.3.1-0.20250821174823-216aa95326f0 h1:66z2V72M9CALNFNblpumbZThrRV3AZ0HwwBt206HVwQ= +github.com/multiversx/mx-chain-crypto-go v1.3.1-0.20250821174823-216aa95326f0/go.mod h1:N0rpNxga3jeG5NwewP1idornaS/IzAAAT4CRURDi+XI= github.com/multiversx/mx-chain-logger-go v1.1.0 h1:97x84A6L4RfCa6YOx1HpAFxZp1cf/WI0Qh112whgZNM= github.com/multiversx/mx-chain-logger-go v1.1.0/go.mod h1:K9XgiohLwOsNACETMNL0LItJMREuEvTH6NsoXWXWg7g= github.com/multiversx/mx-chain-scenario-go v1.6.0 h1:cwDFuS1pSc4YXnfiKKDTEb+QDY4fulPQaiRgIebnKxI= @@ -108,26 +134,29 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ= github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= -github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/ronanh/intcomp v1.1.0 h1:i54kxmpmSoOZFcWPMWryuakN0vLxLswASsGa07zkvLU= +github.com/ronanh/intcomp v1.1.0/go.mod h1:7FOLy3P3Zj3er/kVrU/pl+Ql7JFZj7bwliMGketo0IU= +github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= +github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/urfave/cli/v2 v2.27.1 h1:8xSQ6szndafKVRmfyeUMxkNUJQMjL1F2zmsZ+qHpfho= github.com/urfave/cli/v2 v2.27.1/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= +github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= +github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -136,8 +165,8 @@ golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.3.0 h1:a06MkbcxBrEFc0w0QIZWXrH/9cCX6KJyWbBOIwAn+7A= -golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus= +golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -152,6 +181,8 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= +golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -162,8 +193,11 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A= -golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -174,7 +208,6 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -187,15 +220,17 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= +rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= diff --git a/mock/context/executorMockFunc.go b/mock/context/executorMockFunc.go index 0791f23a4..4ef37d229 100644 --- a/mock/context/executorMockFunc.go +++ b/mock/context/executorMockFunc.go @@ -291,4 +291,11 @@ var functionNames = map[string]struct{}{ "managedGetNumErrors": empty, "managedGetErrorWithIndex": empty, "managedGetLastError": empty, + "managedVerifyGroth16": empty, + "managedVerifyPlonk": empty, + "managedAddEC": empty, + "managedMulEC": empty, + "managedMultiExpEC": empty, + "managedMapToCurveEC": empty, + "managedPairingChecksEC": empty, } diff --git a/scenario/gasSchedules/gasScheduleEmbedGenerated.go b/scenario/gasSchedules/gasScheduleEmbedGenerated.go index 816a12ebf..da8e23223 100644 --- a/scenario/gasSchedules/gasScheduleEmbedGenerated.go +++ b/scenario/gasSchedules/gasScheduleEmbedGenerated.go @@ -123,10 +123,10 @@ const ( GetCodeHash = 100 IsBuiltinFunction = 100 IsReservedFunctionName = 100 - GetRoundTime = 100 - EpochStartBlockTimeStamp = 100 - EpochStartBlockNonce = 100 - EpochStartBlockRound = 100 + GetRoundTime = 10000 + EpochStartBlockTimeStamp = 10000 + EpochStartBlockNonce = 10000 + EpochStartBlockRound = 10000 [EthAPICost] UseGas = 100 @@ -250,6 +250,11 @@ const ( VerifySecp256r1 = 2000000 VerifyBLSSignatureShare = 2000000 VerifyBLSMultiSig = 2000000 + VerifyPlonkSig = 2000000 + VerifyGroth16Sig = 2000000 + MapToCurveECC = 2000000 + PairingCheckECC = 2000000 + MultiExpECC = 2000000 [ManagedBufferAPICost] MBufferNew = 2000 @@ -971,10 +976,10 @@ const ( GetCodeHash = 100 IsBuiltinFunction = 100 IsReservedFunctionName = 100 - GetRoundTime = 100 - EpochStartBlockTimeStamp = 100 - EpochStartBlockNonce = 100 - EpochStartBlockRound = 100 + GetRoundTime = 10000 + EpochStartBlockTimeStamp = 10000 + EpochStartBlockNonce = 10000 + EpochStartBlockRound = 10000 [EthAPICost] UseGas = 100 @@ -1098,6 +1103,11 @@ const ( VerifySecp256r1 = 2000000 VerifyBLSSignatureShare = 2000000 VerifyBLSMultiSig = 2000000 + VerifyPlonkSig = 2000000 + VerifyGroth16Sig = 2000000 + MapToCurveECC = 2000000 + PairingCheckECC = 2000000 + MultiExpECC = 2000000 [ManagedBufferAPICost] MBufferNew = 2000 diff --git a/scenario/gasSchedules/gasScheduleV3.toml b/scenario/gasSchedules/gasScheduleV3.toml index 12b246604..17a0a8c7e 100644 --- a/scenario/gasSchedules/gasScheduleV3.toml +++ b/scenario/gasSchedules/gasScheduleV3.toml @@ -238,6 +238,11 @@ VerifySecp256r1 = 2000000 VerifyBLSSignatureShare = 2000000 VerifyBLSMultiSig = 2000000 + VerifyPlonkSig = 2000000 + VerifyGroth16Sig = 2000000 + MapToCurveECC = 2000000 + PairingCheckECC = 2000000 + MultiExpECC = 2000000 [ManagedBufferAPICost] MBufferNew = 2000 diff --git a/scenario/gasSchedules/gasScheduleV4.toml b/scenario/gasSchedules/gasScheduleV4.toml index 4d10c167a..aa1ef1226 100644 --- a/scenario/gasSchedules/gasScheduleV4.toml +++ b/scenario/gasSchedules/gasScheduleV4.toml @@ -240,6 +240,11 @@ VerifySecp256r1 = 2000000 VerifyBLSSignatureShare = 2000000 VerifyBLSMultiSig = 2000000 + VerifyPlonkSig = 2000000 + VerifyGroth16Sig = 2000000 + MapToCurveECC = 2000000 + PairingCheckECC = 2000000 + MultiExpECC = 2000000 [ManagedBufferAPICost] MBufferNew = 2000 diff --git a/scenario/vmBuilder.go b/scenario/vmBuilder.go index 47f896851..09e8fc781 100644 --- a/scenario/vmBuilder.go +++ b/scenario/vmBuilder.go @@ -24,7 +24,7 @@ var DefaultVMType = []byte{5, 0} // DefaultTimeOutForSCExecutionInMilliseconds is the mainnet timeout. var DefaultTimeOutForSCExecutionInMilliseconds uint32 = 10000 -// VMTestExecutor parses, interprets and executes both .test.json tests and .scen.json scenarios with VM. +// ScenarioVMHostBuilder parses, interprets and executes both .test.json tests and .scen.json scenarios with VM. type ScenarioVMHostBuilder struct { OverrideVMExecutor executor.ExecutorAbstractFactory VMType []byte @@ -83,18 +83,18 @@ func (svb *ScenarioVMHostBuilder) NewVM( return hostCore.NewVMHost( world, &vmhost.VMHostParameters{ - VMType: svb.VMType, - OverrideVMExecutor: svb.OverrideVMExecutor, - BlockGasLimit: blockGasLimit, - GasSchedule: gasSchedule, - BuiltInFuncContainer: world.BuiltinFuncs.Container, - ProtectedKeyPrefix: []byte(core.ProtectedKeyPrefix), - ESDTTransferParser: esdtTransferParser, - EpochNotifier: &mock.EpochNotifierStub{}, - EnableEpochsHandler: world.EnableEpochsHandler, - WasmerSIGSEGVPassthrough: false, - Hasher: worldmock.DefaultHasher, - MapOpcodeAddressIsAllowed: map[string]map[string]struct{}{}, + VMType: svb.VMType, + OverrideVMExecutor: svb.OverrideVMExecutor, + BlockGasLimit: blockGasLimit, + GasSchedule: gasSchedule, + BuiltInFuncContainer: world.BuiltinFuncs.Container, + ProtectedKeyPrefix: []byte(core.ProtectedKeyPrefix), + ESDTTransferParser: esdtTransferParser, + EpochNotifier: &mock.EpochNotifierStub{}, + EnableEpochsHandler: world.EnableEpochsHandler, + WasmerSIGSEGVPassthrough: false, + Hasher: worldmock.DefaultHasher, + MapOpcodeAddressIsAllowed: map[string]map[string]struct{}{}, TimeOutForSCExecutionInMilliseconds: svb.TimeOutForSCExecutionInMilliseconds, }) diff --git a/vmhost/contexts/runtime.go b/vmhost/contexts/runtime.go index a8b87a39b..5457ed7bd 100644 --- a/vmhost/contexts/runtime.go +++ b/vmhost/contexts/runtime.go @@ -50,6 +50,16 @@ var mapFailConditionalOpcodes = map[string]struct{}{ "DeactivateUnsafeMode": {}, } +var mapZKCryptoOpCodes = map[string]struct{}{ + "ManagedVerifyGroth16": {}, + "ManagedVerifyPlonk": {}, + "ManagedAddEC": {}, + "ManagedMulEC": {}, + "ManagedMultiExpEC": {}, + "ManagedMapToCurveEC": {}, + "ManagedPairingChecksEC": {}, +} + const warmCacheSize = 100 type runtimeContext struct { @@ -731,6 +741,14 @@ func (context *runtimeContext) VerifyContractCode() error { } } + if !enableEpochsHandler.IsFlagEnabled(vmhost.ZKCryptoFlag) { + err = context.checkIfContainsZKCryptoOpcodes() + if err != nil { + logRuntime.Trace("verify contract code", "error", err) + return err + } + } + logRuntime.Trace("verified contract code") return nil @@ -763,6 +781,15 @@ func (context *runtimeContext) checkIfContainsFailConditionalOpcodes() error { return nil } +func (context *runtimeContext) checkIfContainsZKCryptoOpcodes() error { + for funcName := range mapZKCryptoOpCodes { + if context.iTracker.Instance().IsFunctionImported(funcName) { + return vmhost.ErrContractInvalid + } + } + return nil +} + // UseGasBoundedShouldFailExecution returns true when flag activated func (context *runtimeContext) UseGasBoundedShouldFailExecution() bool { return context.host.EnableEpochsHandler().IsFlagEnabled(vmhost.UseGasBoundedShouldFailExecutionFlag) diff --git a/vmhost/errors.go b/vmhost/errors.go index f11a56528..2f9f31cc8 100644 --- a/vmhost/errors.go +++ b/vmhost/errors.go @@ -340,3 +340,21 @@ var ErrTimeLockExpired = errors.New("time lock expired") // ErrWrongType signals that wrong type is read from buffer var ErrWrongType = errors.New("incompatible type") + +// ErrZKVerify signals that zk verification errors +var ErrZKVerify = errors.New("zk verification failed") + +// ErrEllipticCurveAddFailed signals that add operation failed +var ErrEllipticCurveAddFailed = errors.New("elliptic curve add failed") + +// ErrEllipticCurveMulFailed signals that mul operation failed +var ErrEllipticCurveMulFailed = errors.New("elliptic curve multiple failed") + +// ErrEllipticCurveMultiExpFailed signals that multi exp operation failed +var ErrEllipticCurveMultiExpFailed = errors.New("elliptic curve multi exp failed") + +// ErrEllipticCurveMapToCurveFailed signals that map to curve operation failed +var ErrEllipticCurveMapToCurveFailed = errors.New("elliptic curve map to curve failed") + +// ErrEllipticCurvePairingCheckFailed signals that pairing check operation failed +var ErrEllipticCurvePairingCheckFailed = errors.New("elliptic curve pair checking failed") diff --git a/vmhost/flags.go b/vmhost/flags.go index d863e301f..88597c116 100644 --- a/vmhost/flags.go +++ b/vmhost/flags.go @@ -39,5 +39,8 @@ const ( // FailConditionallyFlag defines the flag that activates the new opcodes and possibility for failing conditionally FailConditionallyFlag core.EnableEpochFlag = "FailConditionallyFlag" + // ZKCryptoFlag defines the flag that activates the new zk crypto opcodes + ZKCryptoFlag core.EnableEpochFlag = "ZKCryptoFlag" + // all new flags must be added to allFlags slice from hostCore/host ) diff --git a/vmhost/hostCore/host.go b/vmhost/hostCore/host.go index aef69a77f..f34225ef0 100644 --- a/vmhost/hostCore/host.go +++ b/vmhost/hostCore/host.go @@ -49,6 +49,7 @@ var allFlags = []core.EnableEpochFlag{ vmhost.AsyncV3FixesFlag, vmhost.AsyncV3Flag, vmhost.FailConditionallyFlag, + vmhost.ZKCryptoFlag, } // vmHost implements HostContext interface. diff --git a/vmhost/vmhooks/ec_generated_test.go b/vmhost/vmhooks/ec_generated_test.go new file mode 100644 index 000000000..4f9326d04 --- /dev/null +++ b/vmhost/vmhooks/ec_generated_test.go @@ -0,0 +1,320 @@ +package vmhooks + +import ( + "testing" + + "github.com/multiversx/mx-chain-crypto-go/zk/lowLevelFeatures" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" +) + +func TestManagedAddEC_Fail_GetPoint1Bytes(t *testing.T) { + vmHooks := createHooksWithBaseSetup() + managedType := vmHooks.managedType + runtime := vmHooks.runtime + + managedType.On("GetBytes", int32(1)).Return(nil, assert.AnError) + runtime.On("FailExecution", mock.Anything).Return() + + ret := vmHooks.hooks.ManagedAddEC(int32(lowLevelFeatures.BN254), int32(lowLevelFeatures.G1), 1, 2, 3) + assert.Equal(t, int32(-1), ret) + runtime.AssertCalled(t, "FailExecution", mock.Anything) +} + +func TestManagedPairingChecksEC_Fail_ReadVectors(t *testing.T) { + vmHooks := createHooksWithBaseSetup() + managedType := vmHooks.managedType + runtime := vmHooks.runtime + + managedType.On("ReadManagedVecOfManagedBuffers", int32(1)).Return(nil, uint64(0), assert.AnError) + runtime.On("FailExecution", mock.Anything).Return() + + ret := vmHooks.hooks.ManagedPairingChecksEC(int32(lowLevelFeatures.BN254), 1, 2) + assert.Equal(t, int32(-1), ret) + runtime.AssertCalled(t, "FailExecution", mock.Anything) +} + +func TestManagedPairingChecksEC_Fail_InvalidCurve(t *testing.T) { + vmHooks := createHooksWithBaseSetup() + managedType := vmHooks.managedType + runtime := vmHooks.runtime + + managedType.On("ReadManagedVecOfManagedBuffers", int32(1)).Return([][]byte{}, uint64(0), nil) + managedType.On("ReadManagedVecOfManagedBuffers", int32(2)).Return([][]byte{}, uint64(0), nil) + runtime.On("IsUnsafeMode").Return(true) + runtime.On("FailExecution", mock.Anything).Return() + + ret := vmHooks.hooks.ManagedPairingChecksEC(int32(42), 1, 2) + assert.Equal(t, int32(-1), ret) + runtime.AssertCalled(t, "FailExecution", mock.Anything) +} + +func TestManagedPairingChecksEC_Fail_PairingCheck(t *testing.T) { + vmHooks := createHooksWithBaseSetup() + managedType := vmHooks.managedType + runtime := vmHooks.runtime + + managedType.On("ReadManagedVecOfManagedBuffers", int32(1)).Return([][]byte{[]byte("dummy point")}, uint64(1), nil) + managedType.On("ReadManagedVecOfManagedBuffers", int32(2)).Return([][]byte{[]byte("dummy point")}, uint64(1), nil) + runtime.On("IsUnsafeMode").Return(true) + runtime.On("FailExecution", mock.Anything).Return() + + ret := vmHooks.hooks.ManagedPairingChecksEC(int32(lowLevelFeatures.BN254), 1, 2) + assert.Equal(t, int32(-1), ret) + runtime.AssertCalled(t, "FailExecution", mock.Anything) +} + +func TestManagedMultiExpEC_Fail_ReadVectors(t *testing.T) { + vmHooks := createHooksWithBaseSetup() + managedType := vmHooks.managedType + runtime := vmHooks.runtime + + managedType.On("ReadManagedVecOfManagedBuffers", int32(1)).Return(nil, uint64(0), assert.AnError) + runtime.On("FailExecution", mock.Anything).Return() + + ret := vmHooks.hooks.ManagedMultiExpEC(int32(lowLevelFeatures.BN254), int32(lowLevelFeatures.G1), 1, 2, 3) + assert.Equal(t, int32(-1), ret) + runtime.AssertCalled(t, "FailExecution", mock.Anything) +} + +func TestManagedMultiExpEC_Fail_InvalidCurve(t *testing.T) { + vmHooks := createHooksWithBaseSetup() + managedType := vmHooks.managedType + runtime := vmHooks.runtime + + managedType.On("ReadManagedVecOfManagedBuffers", int32(1)).Return([][]byte{}, uint64(0), nil) + managedType.On("ReadManagedVecOfManagedBuffers", int32(2)).Return([][]byte{}, uint64(0), nil) + runtime.On("IsUnsafeMode").Return(true) + runtime.On("FailExecution", mock.Anything).Return() + + ret := vmHooks.hooks.ManagedMultiExpEC(int32(42), int32(lowLevelFeatures.G1), 1, 2, 3) + assert.Equal(t, int32(-1), ret) + runtime.AssertCalled(t, "FailExecution", mock.Anything) +} + +func TestManagedMultiExpEC_Fail_InvalidGroup(t *testing.T) { + vmHooks := createHooksWithBaseSetup() + managedType := vmHooks.managedType + runtime := vmHooks.runtime + + managedType.On("ReadManagedVecOfManagedBuffers", int32(1)).Return([][]byte{}, uint64(0), nil) + managedType.On("ReadManagedVecOfManagedBuffers", int32(2)).Return([][]byte{}, uint64(0), nil) + runtime.On("IsUnsafeMode").Return(true) + runtime.On("FailExecution", mock.Anything).Return() + + ret := vmHooks.hooks.ManagedMultiExpEC(int32(lowLevelFeatures.BN254), int32(42), 1, 2, 3) + assert.Equal(t, int32(-1), ret) + runtime.AssertCalled(t, "FailExecution", mock.Anything) +} + +func TestManagedMultiExpEC_Fail_MultiExp(t *testing.T) { + vmHooks := createHooksWithBaseSetup() + managedType := vmHooks.managedType + runtime := vmHooks.runtime + + managedType.On("ReadManagedVecOfManagedBuffers", int32(1)).Return([][]byte{[]byte("dummy point")}, uint64(1), nil) + managedType.On("ReadManagedVecOfManagedBuffers", int32(2)).Return([][]byte{[]byte("dummy scalar")}, uint64(1), nil) + runtime.On("IsUnsafeMode").Return(true) + runtime.On("FailExecution", mock.Anything).Return() + + ret := vmHooks.hooks.ManagedMultiExpEC(int32(lowLevelFeatures.BN254), int32(lowLevelFeatures.G1), 1, 2, 3) + assert.Equal(t, int32(-1), ret) + runtime.AssertCalled(t, "FailExecution", mock.Anything) +} + +func TestManagedMapToCurveEC_Fail_GetElementBytes(t *testing.T) { + vmHooks := createHooksWithBaseSetup() + managedType := vmHooks.managedType + runtime := vmHooks.runtime + + managedType.On("GetBytes", int32(1)).Return(nil, assert.AnError) + runtime.On("FailExecution", mock.Anything).Return() + + ret := vmHooks.hooks.ManagedMapToCurveEC(int32(lowLevelFeatures.BN254), int32(lowLevelFeatures.G1), 1, 2) + assert.Equal(t, int32(-1), ret) + runtime.AssertCalled(t, "FailExecution", mock.Anything) +} + +func TestManagedMapToCurveEC_Fail_InvalidCurve(t *testing.T) { + vmHooks := createHooksWithBaseSetup() + managedType := vmHooks.managedType + runtime := vmHooks.runtime + + managedType.On("GetBytes", int32(1)).Return([]byte("dummy element"), nil) + managedType.On("ConsumeGasForBytes", mock.Anything).Return(nil) + runtime.On("IsUnsafeMode").Return(true) + runtime.On("FailExecution", mock.Anything).Return() + + ret := vmHooks.hooks.ManagedMapToCurveEC(int32(42), int32(lowLevelFeatures.G1), 1, 2) + assert.Equal(t, int32(-1), ret) + runtime.AssertCalled(t, "FailExecution", mock.Anything) +} + +func TestManagedMapToCurveEC_Fail_InvalidGroup(t *testing.T) { + vmHooks := createHooksWithBaseSetup() + managedType := vmHooks.managedType + runtime := vmHooks.runtime + + managedType.On("GetBytes", int32(1)).Return([]byte("dummy element"), nil) + managedType.On("ConsumeGasForBytes", mock.Anything).Return(nil) + runtime.On("IsUnsafeMode").Return(true) + runtime.On("FailExecution", mock.Anything).Return() + + ret := vmHooks.hooks.ManagedMapToCurveEC(int32(lowLevelFeatures.BN254), int32(42), 1, 2) + assert.Equal(t, int32(-1), ret) + runtime.AssertCalled(t, "FailExecution", mock.Anything) +} + +func TestManagedMapToCurveEC_Fail_Map(t *testing.T) { + vmHooks := createHooksWithBaseSetup() + managedType := vmHooks.managedType + runtime := vmHooks.runtime + + managedType.On("GetBytes", int32(1)).Return([]byte("dummy element"), nil) + managedType.On("ConsumeGasForBytes", mock.Anything).Return(nil) + runtime.On("IsUnsafeMode").Return(true) + runtime.On("FailExecution", mock.Anything).Return() + + ret := vmHooks.hooks.ManagedMapToCurveEC(int32(lowLevelFeatures.BN254), int32(lowLevelFeatures.G1), 1, 2) + assert.Equal(t, int32(-1), ret) + runtime.AssertCalled(t, "FailExecution", mock.Anything) +} + +func TestManagedMulEC_Fail_GetPointBytes(t *testing.T) { + vmHooks := createHooksWithBaseSetup() + managedType := vmHooks.managedType + runtime := vmHooks.runtime + + managedType.On("GetBytes", int32(1)).Return(nil, assert.AnError) + runtime.On("FailExecution", mock.Anything).Return() + + ret := vmHooks.hooks.ManagedMulEC(int32(lowLevelFeatures.BN254), int32(lowLevelFeatures.G1), 1, 2, 3) + assert.Equal(t, int32(-1), ret) + runtime.AssertCalled(t, "FailExecution", mock.Anything) +} + +func TestManagedMulEC_Fail_GetScalarBytes(t *testing.T) { + vmHooks := createHooksWithBaseSetup() + managedType := vmHooks.managedType + runtime := vmHooks.runtime + + managedType.On("GetBytes", int32(1)).Return([]byte("dummy point"), nil) + managedType.On("GetBytes", int32(2)).Return(nil, assert.AnError) + managedType.On("ConsumeGasForBytes", mock.Anything).Return(nil) + runtime.On("FailExecution", mock.Anything).Return() + + ret := vmHooks.hooks.ManagedMulEC(int32(lowLevelFeatures.BN254), int32(lowLevelFeatures.G1), 1, 2, 3) + assert.Equal(t, int32(-1), ret) + runtime.AssertCalled(t, "FailExecution", mock.Anything) +} + +func TestManagedMulEC_Fail_InvalidCurve(t *testing.T) { + vmHooks := createHooksWithBaseSetup() + managedType := vmHooks.managedType + runtime := vmHooks.runtime + + managedType.On("GetBytes", int32(1)).Return([]byte("dummy point"), nil) + managedType.On("GetBytes", int32(2)).Return([]byte("dummy scalar"), nil) + managedType.On("ConsumeGasForBytes", mock.Anything).Return(nil).Times(2) + runtime.On("IsUnsafeMode").Return(true) + runtime.On("FailExecution", mock.Anything).Return() + + ret := vmHooks.hooks.ManagedMulEC(int32(42), int32(lowLevelFeatures.G1), 1, 2, 3) + assert.Equal(t, int32(-1), ret) + runtime.AssertCalled(t, "FailExecution", mock.Anything) +} + +func TestManagedMulEC_Fail_InvalidGroup(t *testing.T) { + vmHooks := createHooksWithBaseSetup() + managedType := vmHooks.managedType + runtime := vmHooks.runtime + + managedType.On("GetBytes", int32(1)).Return([]byte("dummy point"), nil) + managedType.On("GetBytes", int32(2)).Return([]byte("dummy scalar"), nil) + managedType.On("ConsumeGasForBytes", mock.Anything).Return(nil).Times(2) + runtime.On("IsUnsafeMode").Return(true) + runtime.On("FailExecution", mock.Anything).Return() + + ret := vmHooks.hooks.ManagedMulEC(int32(lowLevelFeatures.BN254), int32(42), 1, 2, 3) + assert.Equal(t, int32(-1), ret) + runtime.AssertCalled(t, "FailExecution", mock.Anything) +} + +func TestManagedMulEC_Fail_Mul(t *testing.T) { + vmHooks := createHooksWithBaseSetup() + managedType := vmHooks.managedType + runtime := vmHooks.runtime + + managedType.On("GetBytes", int32(1)).Return([]byte("dummy point"), nil) + managedType.On("GetBytes", int32(2)).Return([]byte("dummy scalar"), nil) + managedType.On("ConsumeGasForBytes", mock.Anything).Return(nil).Times(2) + runtime.On("IsUnsafeMode").Return(true) + runtime.On("FailExecution", mock.Anything).Return() + + ret := vmHooks.hooks.ManagedMulEC(int32(lowLevelFeatures.BN254), int32(lowLevelFeatures.G1), 1, 2, 3) + assert.Equal(t, int32(-1), ret) + runtime.AssertCalled(t, "FailExecution", mock.Anything) +} + +func TestManagedAddEC_Fail_GetPoint2Bytes(t *testing.T) { + vmHooks := createHooksWithBaseSetup() + managedType := vmHooks.managedType + runtime := vmHooks.runtime + + managedType.On("GetBytes", int32(1)).Return([]byte("dummy point"), nil) + managedType.On("GetBytes", int32(2)).Return(nil, assert.AnError) + managedType.On("ConsumeGasForBytes", mock.Anything).Return(nil) + runtime.On("FailExecution", mock.Anything).Return() + + ret := vmHooks.hooks.ManagedAddEC(int32(lowLevelFeatures.BN254), int32(lowLevelFeatures.G1), 1, 2, 3) + assert.Equal(t, int32(-1), ret) + runtime.AssertCalled(t, "FailExecution", mock.Anything) +} + +func TestManagedAddEC_Fail_InvalidCurve(t *testing.T) { + vmHooks := createHooksWithBaseSetup() + managedType := vmHooks.managedType + runtime := vmHooks.runtime + + managedType.On("GetBytes", int32(1)).Return([]byte("dummy point 1"), nil) + managedType.On("GetBytes", int32(2)).Return([]byte("dummy point 2"), nil) + managedType.On("ConsumeGasForBytes", mock.Anything).Return(nil).Times(2) + runtime.On("IsUnsafeMode").Return(true) + runtime.On("FailExecution", mock.Anything).Return() + + ret := vmHooks.hooks.ManagedAddEC(int32(42), int32(lowLevelFeatures.G1), 1, 2, 3) + assert.Equal(t, int32(-1), ret) + runtime.AssertCalled(t, "FailExecution", mock.Anything) +} + +func TestManagedAddEC_Fail_InvalidGroup(t *testing.T) { + vmHooks := createHooksWithBaseSetup() + managedType := vmHooks.managedType + runtime := vmHooks.runtime + + managedType.On("GetBytes", int32(1)).Return([]byte("dummy point 1"), nil) + managedType.On("GetBytes", int32(2)).Return([]byte("dummy point 2"), nil) + managedType.On("ConsumeGasForBytes", mock.Anything).Return(nil).Times(2) + runtime.On("IsUnsafeMode").Return(true) + runtime.On("FailExecution", mock.Anything).Return() + + ret := vmHooks.hooks.ManagedAddEC(int32(lowLevelFeatures.BN254), int32(42), 1, 2, 3) + assert.Equal(t, int32(-1), ret) + runtime.AssertCalled(t, "FailExecution", mock.Anything) +} + +func TestManagedAddEC_Fail_Add(t *testing.T) { + vmHooks := createHooksWithBaseSetup() + managedType := vmHooks.managedType + runtime := vmHooks.runtime + + managedType.On("GetBytes", int32(1)).Return([]byte("dummy point 1"), nil) + managedType.On("GetBytes", int32(2)).Return([]byte("dummy point 2"), nil) + managedType.On("ConsumeGasForBytes", mock.Anything).Return(nil).Times(2) + runtime.On("IsUnsafeMode").Return(true) + runtime.On("FailExecution", mock.Anything).Return() + + ret := vmHooks.hooks.ManagedAddEC(int32(lowLevelFeatures.BN254), int32(lowLevelFeatures.G1), 1, 2, 3) + assert.Equal(t, int32(-1), ret) + runtime.AssertCalled(t, "FailExecution", mock.Anything) +} diff --git a/vmhost/vmhooks/generate/cmd/eiGenMain.go b/vmhost/vmhooks/generate/cmd/eiGenMain.go index 427cbebec..1a6d81ed6 100644 --- a/vmhost/vmhooks/generate/cmd/eiGenMain.go +++ b/vmhost/vmhooks/generate/cmd/eiGenMain.go @@ -28,6 +28,7 @@ func initEIMetadata() *eapigen.EIMetadata { {SourcePath: "smallIntOps.go", Name: "SmallInt"}, {SourcePath: "cryptoei.go", Name: "Crypto"}, {SourcePath: "unsafeOps.go", Name: "Unsafe"}, + {SourcePath: "zkcryptoei.go", Name: "ZKCrypto"}, }, AllFunctions: nil, } diff --git a/vmhost/vmhooks/zkcryptoei.go b/vmhost/vmhooks/zkcryptoei.go new file mode 100644 index 000000000..64b38b6fd --- /dev/null +++ b/vmhost/vmhooks/zkcryptoei.go @@ -0,0 +1,372 @@ +package vmhooks + +import ( + "github.com/multiversx/mx-chain-crypto-go/zk/groth16" + "github.com/multiversx/mx-chain-crypto-go/zk/lowLevelFeatures" + "github.com/multiversx/mx-chain-crypto-go/zk/plonk" + "github.com/multiversx/mx-chain-vm-go/math" + "github.com/multiversx/mx-chain-vm-go/vmhost" +) + +const ( + managedVerifyGroth16 = "ManagedVerifyGroth16" + managedVerifyPlonk = "ManagedVerifyPlonk" + managedAddEC = "ManagedAddEC" + managedMulEC = "ManagedMulEC" + managedMultiExpEC = "ManagedMultiExpEC" + managedMapToCurveEC = "ManagedMapToCurveEC" + managedPairingCheckEC = "ManagedPairingCheckEC" +) + +// ManagedVerifyGroth16 VMHooks implementation. +// @autogenerate(VMHooks) +func (context *VMHooksImpl) ManagedVerifyGroth16( + curveID int32, proofHandle, vkHandle, pubWitnessHandle int32, +) int32 { + host := context.GetVMHost() + return ManagedVerifyZKFunctionWithHost( + host, + managedVerifyGroth16, + host.Metering().GasSchedule().CryptoAPICost.VerifyGroth16Sig, + curveID, + proofHandle, + vkHandle, + pubWitnessHandle) +} + +// ManagedVerifyPlonk VMHooks implementation. +// @autogenerate(VMHooks) +func (context *VMHooksImpl) ManagedVerifyPlonk( + curveID int32, proofHandle, vkHandle, pubWitnessHandle int32, +) int32 { + host := context.GetVMHost() + return ManagedVerifyZKFunctionWithHost( + host, + managedVerifyPlonk, + host.Metering().GasSchedule().CryptoAPICost.VerifyPlonkSig, + curveID, + proofHandle, + vkHandle, + pubWitnessHandle) +} + +func getBytesAndConsumeGas(managedType vmhost.ManagedTypesContext, handle int32) ([]byte, error) { + bytesVec, err := managedType.GetBytes(handle) + if err != nil { + return nil, err + } + + err = managedType.ConsumeGasForBytes(bytesVec) + if err != nil { + return nil, err + } + + return bytesVec, nil +} + +// ManagedVerifyZKFunctionWithHost VMHooks implementation with host +func ManagedVerifyZKFunctionWithHost( + host vmhost.VMHost, + zkFunc string, + gasToUse uint64, + curveID int32, + proofHandle, vkHandle, pubWitnessHandle int32, +) int32 { + metering := host.Metering() + managedType := host.ManagedTypes() + + err := metering.UseGasBoundedAndAddTracedGas(zkFunc, gasToUse) + if err != nil { + FailExecution(host, err) + return -1 + } + + proofBytes, err := getBytesAndConsumeGas(managedType, proofHandle) + if err != nil { + FailExecution(host, err) + return -1 + } + + vkBytes, err := getBytesAndConsumeGas(managedType, vkHandle) + if err != nil { + FailExecution(host, err) + return -1 + } + + pubWitnessBytes, err := getBytesAndConsumeGas(managedType, pubWitnessHandle) + if err != nil { + FailExecution(host, err) + return -1 + } + + verified := false + invalidSigErr := vmhost.ErrInvalidArgument + switch zkFunc { + case managedVerifyGroth16: + verified, invalidSigErr = groth16.VerifyGroth16(uint16(curveID), proofBytes, vkBytes, pubWitnessBytes) + case managedVerifyPlonk: + verified, invalidSigErr = plonk.VerifyPlonk(uint16(curveID), proofBytes, vkBytes, pubWitnessBytes) + } + + if invalidSigErr != nil || !verified { + FailExecutionConditionally(host, vmhost.ErrZKVerify) + return -1 + } + + return 0 +} + +func managedECOperationWithHost( + host vmhost.VMHost, + operationName string, + gasCost uint64, + failureError error, + curveID int32, + groupID int32, + inputHandles []int32, + resultHandle int32, + execute func(curveID int32, groupID int32, inputs [][]byte) ([]byte, error), +) int32 { + metering := host.Metering() + managedType := host.ManagedTypes() + + err := metering.UseGasBoundedAndAddTracedGas(operationName, gasCost) + if err != nil { + FailExecution(host, err) + return -1 + } + + var inputsBytes [][]byte + for _, handle := range inputHandles { + bytes, err := getBytesAndConsumeGas(managedType, handle) + if err != nil { + FailExecution(host, err) + return -1 + } + inputsBytes = append(inputsBytes, bytes) + } + + result, err := execute(curveID, groupID, inputsBytes) + if err != nil { + FailExecutionConditionally(host, failureError) + return -1 + } + + err = managedType.ConsumeGasForBytes(result) + if err != nil { + FailExecution(host, err) + return -1 + } + + managedType.SetBytes(resultHandle, result) + return 0 +} + +func addEC(curveID int32, groupID int32, inputs [][]byte) ([]byte, error) { + if len(inputs) != 2 { + return nil, vmhost.ErrArgIndexOutOfRange + } + return lowLevelFeatures.PointAdd(lowLevelFeatures.ID(curveID), lowLevelFeatures.GroupID(groupID), inputs[0], inputs[1]) +} + +func mulEC(curveID int32, groupID int32, inputs [][]byte) ([]byte, error) { + if len(inputs) != 2 { + return nil, vmhost.ErrArgIndexOutOfRange + } + return lowLevelFeatures.ScalarMul(lowLevelFeatures.ID(curveID), lowLevelFeatures.GroupID(groupID), inputs[0], inputs[1]) +} + +func mapToCurveEC(curveID int32, groupID int32, inputs [][]byte) ([]byte, error) { + if len(inputs) != 1 { + return nil, vmhost.ErrArgIndexOutOfRange + } + return lowLevelFeatures.MapToCurve(lowLevelFeatures.ID(curveID), lowLevelFeatures.GroupID(groupID), inputs[0]) +} + +// ManagedAddEC VMHooks implementation. +// @autogenerate(VMHooks) +func (context *VMHooksImpl) ManagedAddEC( + curveID int32, + groupID int32, + point1Handle, point2Handle int32, + resultHandle int32, +) int32 { + host := context.GetVMHost() + return managedECOperationWithHost( + host, + managedAddEC, + host.Metering().GasSchedule().CryptoAPICost.AddECC, + vmhost.ErrEllipticCurveAddFailed, + curveID, + groupID, + []int32{point1Handle, point2Handle}, + resultHandle, + addEC, + ) +} + +// ManagedMulEC VMHooks implementation. +// @autogenerate(VMHooks) +func (context *VMHooksImpl) ManagedMulEC( + curveID int32, + groupID int32, + pointHandle, scalarHandle int32, + resultHandle int32, +) int32 { + host := context.GetVMHost() + return managedECOperationWithHost( + host, + managedMulEC, + host.Metering().GasSchedule().CryptoAPICost.ScalarMultECC, + vmhost.ErrEllipticCurveMulFailed, + curveID, + groupID, + []int32{pointHandle, scalarHandle}, + resultHandle, + mulEC, + ) +} + +// ManagedMapToCurveEC VMHooks implementation. +// @autogenerate(VMHooks) +func (context *VMHooksImpl) ManagedMapToCurveEC( + curveID int32, + groupID int32, + elementHandle int32, + resultHandle int32, +) int32 { + host := context.GetVMHost() + return managedECOperationWithHost( + host, + managedMapToCurveEC, + host.Metering().GasSchedule().CryptoAPICost.MapToCurveECC, + vmhost.ErrEllipticCurveMapToCurveFailed, + curveID, + groupID, + []int32{elementHandle}, + resultHandle, + mapToCurveEC, + ) +} + +func readManagedVectorsAndConsumeGas( + host vmhost.VMHost, + handle1, handle2 int32, +) ([][]byte, [][]byte, error) { + managedType := host.ManagedTypes() + metering := host.Metering() + + vec1, len1, err := managedType.ReadManagedVecOfManagedBuffers(handle1) + if err != nil { + return nil, nil, err + } + + vec2, len2, err := managedType.ReadManagedVecOfManagedBuffers(handle2) + if err != nil { + return nil, nil, err + } + + gasToUse := math.MulUint64(metering.GasSchedule().BaseOperationCost.DataCopyPerByte, len1+len2) + err = metering.UseGasBounded(gasToUse) + if err != nil { + return nil, nil, err + } + + return vec1, vec2, nil +} + +// ManagedMultiExpEC VMHooks implementation. +// @autogenerate(VMHooks) +func (context *VMHooksImpl) ManagedMultiExpEC( + curveID int32, + groupID int32, + pointsHandle, scalarsHandle int32, + resultHandle int32, +) int32 { + host := context.GetVMHost() + return ManagedMultiExpECWithHost(host, curveID, groupID, pointsHandle, scalarsHandle, resultHandle) +} + +// ManagedMultiExpECWithHost implements the MultiExp elliptic curves operation on the set of defined curves and group +func ManagedMultiExpECWithHost( + host vmhost.VMHost, + curveID int32, + groupID int32, + pointsHandle, scalarsHandle int32, + resultHandle int32, +) int32 { + metering := host.Metering() + + err := metering.UseGasBoundedAndAddTracedGas(managedMultiExpEC, metering.GasSchedule().CryptoAPICost.MultiExpECC) + if err != nil { + FailExecution(host, err) + return -1 + } + + pointsVec, scalarsVec, err := readManagedVectorsAndConsumeGas(host, pointsHandle, scalarsHandle) + if err != nil { + FailExecution(host, err) + return -1 + } + + err = metering.UseGasBoundedAndAddTracedGas(managedMultiExpEC, uint64(len(pointsVec))*metering.GasSchedule().CryptoAPICost.ScalarMultECC) + if err != nil { + FailExecution(host, err) + return -1 + } + + result, err := lowLevelFeatures.MultiExp(lowLevelFeatures.ID(curveID), lowLevelFeatures.GroupID(groupID), pointsVec, scalarsVec) + if err != nil { + FailExecutionConditionally(host, vmhost.ErrEllipticCurveMultiExpFailed) + return -1 + } + + managedType := host.ManagedTypes() + err = managedType.ConsumeGasForBytes(result) + if err != nil { + FailExecution(host, err) + return -1 + } + + managedType.SetBytes(resultHandle, result) + + return 0 +} + +// ManagedPairingChecksEC VMHooks implementation. +// @autogenerate(VMHooks) +func (context *VMHooksImpl) ManagedPairingChecksEC( + curveID int32, + pointsG1Handle, pointsG2Handle int32, +) int32 { + host := context.GetVMHost() + return ManagedPairingChecksECWithHost(host, curveID, pointsG1Handle, pointsG2Handle) +} + +// ManagedPairingChecksECWithHost implements the pairing checks elliptic curves operation on the set of defined curves +func ManagedPairingChecksECWithHost( + host vmhost.VMHost, + curveID int32, + pointsG1Handle, pointsG2Handle int32, +) int32 { + pointsG1Vec, pointsG2Vec, err := readManagedVectorsAndConsumeGas(host, pointsG1Handle, pointsG2Handle) + if err != nil { + FailExecution(host, err) + return -1 + } + + metering := host.Metering() + err = metering.UseGasBoundedAndAddTracedGas(managedPairingCheckEC, uint64(len(pointsG1Vec))*metering.GasSchedule().CryptoAPICost.PairingCheckECC) + if err != nil { + FailExecution(host, err) + return -1 + } + + verified, err := lowLevelFeatures.PairingCheck(lowLevelFeatures.ID(curveID), pointsG1Vec, pointsG2Vec) + if err != nil || !verified { + FailExecutionConditionally(host, vmhost.ErrEllipticCurvePairingCheckFailed) + return -1 + } + + return 0 +} diff --git a/vmhost/vmhooks/zkcryptoei_test.go b/vmhost/vmhooks/zkcryptoei_test.go new file mode 100644 index 000000000..d80063b2e --- /dev/null +++ b/vmhost/vmhooks/zkcryptoei_test.go @@ -0,0 +1,400 @@ +package vmhooks + +import ( + "bytes" + "testing" + + "github.com/consensys/gnark-crypto/ecc" + gnarkgroth16 "github.com/consensys/gnark/backend/groth16" + gnarkplonk "github.com/consensys/gnark/backend/plonk" + "github.com/consensys/gnark/examples/exponentiate" + "github.com/consensys/gnark/frontend" + "github.com/consensys/gnark/frontend/cs/r1cs" + "github.com/consensys/gnark/frontend/cs/scs" + "github.com/consensys/gnark/test/unsafekzg" + "github.com/multiversx/mx-chain-crypto-go/curves/bn254" + "github.com/multiversx/mx-chain-crypto-go/zk/lowLevelFeatures" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" +) + +func TestManagedVerifyGroth16_Success(t *testing.T) { + css, err := frontend.Compile(ecc.BLS12_381.ScalarField(), r1cs.NewBuilder, &exponentiate.Circuit{}) + require.Nil(t, err) + + pk, vk, err := gnarkgroth16.Setup(css) + require.Nil(t, err) + + homework := &exponentiate.Circuit{ + X: 2, + Y: 16, + E: 4, + } + witness, err := frontend.NewWitness(homework, ecc.BLS12_381.ScalarField()) + require.Nil(t, err) + + proof, err := gnarkgroth16.Prove(css, pk, witness) + require.Nil(t, err) + + var serializedProof bytes.Buffer + _, err = proof.WriteTo(&serializedProof) + require.Nil(t, err) + + var serializedVK bytes.Buffer + _, err = vk.WriteTo(&serializedVK) + require.Nil(t, err) + + pubW, err := witness.Public() + require.Nil(t, err) + pubWBytes, err := pubW.MarshalBinary() + require.Nil(t, err) + + vmHooks := createHooksWithBaseSetup() + hooks := vmHooks.hooks + managedType := vmHooks.managedType + runtime := vmHooks.runtime + + managedType.On("GetBytes", int32(1)).Return(serializedProof.Bytes(), nil) + managedType.On("GetBytes", int32(2)).Return(serializedVK.Bytes(), nil) + managedType.On("GetBytes", int32(3)).Return(pubWBytes, nil) + managedType.On("ConsumeGasForBytes", mock.Anything).Return(nil) + runtime.On("IsUnsafeMode").Return(false) + runtime.On("FailExecution", mock.Anything).Return() + + ret := hooks.ManagedVerifyGroth16(int32(ecc.BLS12_381), 1, 2, 3) + + assert.Equal(t, int32(0), ret) + runtime.AssertNotCalled(t, "FailExecution", mock.Anything) +} + +func TestManagedVerifyPlonk_Success(t *testing.T) { + css, err := frontend.Compile(ecc.BLS12_381.ScalarField(), scs.NewBuilder, &exponentiate.Circuit{}) + require.Nil(t, err) + + srs, srsLagrange, err := unsafekzg.NewSRS(css) + require.Nil(t, err) + + pk, vk, err := gnarkplonk.Setup(css, srs, srsLagrange) + require.Nil(t, err) + + homework := &exponentiate.Circuit{ + X: 2, + Y: 16, + E: 4, + } + witness, err := frontend.NewWitness(homework, ecc.BLS12_381.ScalarField()) + require.Nil(t, err) + + proof, err := gnarkplonk.Prove(css, pk, witness) + require.Nil(t, err) + + var serializedProof bytes.Buffer + _, err = proof.WriteTo(&serializedProof) + require.Nil(t, err) + + var serializedVK bytes.Buffer + _, err = vk.WriteTo(&serializedVK) + require.Nil(t, err) + + pubW, err := witness.Public() + require.Nil(t, err) + pubWBytes, err := pubW.MarshalBinary() + require.Nil(t, err) + + vmHooks := createHooksWithBaseSetup() + hooks := vmHooks.hooks + managedType := vmHooks.managedType + runtime := vmHooks.runtime + + managedType.On("GetBytes", int32(1)).Return(serializedProof.Bytes(), nil) + managedType.On("GetBytes", int32(2)).Return(serializedVK.Bytes(), nil) + managedType.On("GetBytes", int32(3)).Return(pubWBytes, nil) + managedType.On("ConsumeGasForBytes", mock.Anything).Return(nil) + runtime.On("IsUnsafeMode").Return(false) + runtime.On("FailExecution", mock.Anything).Return() + + ret := hooks.ManagedVerifyPlonk(int32(ecc.BLS12_381), 1, 2, 3) + + assert.Equal(t, int32(0), ret) + runtime.AssertNotCalled(t, "FailExecution", mock.Anything) +} + +func TestManagedVerifyGroth16_InvalidProof(t *testing.T) { + css, err := frontend.Compile(ecc.BLS12_381.ScalarField(), r1cs.NewBuilder, &exponentiate.Circuit{}) + require.Nil(t, err) + + _, vk, err := gnarkgroth16.Setup(css) + require.Nil(t, err) + + homework := &exponentiate.Circuit{ + X: 2, + Y: 16, + E: 4, + } + witness, err := frontend.NewWitness(homework, ecc.BLS12_381.ScalarField()) + require.Nil(t, err) + + var serializedVK bytes.Buffer + _, err = vk.WriteTo(&serializedVK) + require.Nil(t, err) + + pubW, err := witness.Public() + require.Nil(t, err) + pubWBytes, err := pubW.MarshalBinary() + require.Nil(t, err) + + vmHooks := createHooksWithBaseSetup() + hooks := vmHooks.hooks + managedType := vmHooks.managedType + runtime := vmHooks.runtime + + managedType.On("GetBytes", int32(1)).Return([]byte("invalid proof"), nil) + managedType.On("GetBytes", int32(2)).Return(serializedVK.Bytes(), nil) + managedType.On("GetBytes", int32(3)).Return(pubWBytes, nil) + managedType.On("ConsumeGasForBytes", mock.Anything).Return(nil) + runtime.On("IsUnsafeMode").Return(false) + runtime.On("FailExecution", mock.Anything).Return() + + ret := hooks.ManagedVerifyGroth16(int32(ecc.BLS12_381), 1, 2, 3) + + assert.Equal(t, int32(-1), ret) + runtime.AssertCalled(t, "FailExecution", mock.Anything) +} + +func TestManagedVerifyPlonk_InvalidProof(t *testing.T) { + css, err := frontend.Compile(ecc.BLS12_381.ScalarField(), scs.NewBuilder, &exponentiate.Circuit{}) + require.Nil(t, err) + + srs, srsLagrange, err := unsafekzg.NewSRS(css) + require.Nil(t, err) + + _, vk, err := gnarkplonk.Setup(css, srs, srsLagrange) + require.Nil(t, err) + + homework := &exponentiate.Circuit{ + X: 2, + Y: 16, + E: 4, + } + witness, err := frontend.NewWitness(homework, ecc.BLS12_381.ScalarField()) + require.Nil(t, err) + + var serializedVK bytes.Buffer + _, err = vk.WriteTo(&serializedVK) + require.Nil(t, err) + + pubW, err := witness.Public() + require.Nil(t, err) + pubWBytes, err := pubW.MarshalBinary() + require.Nil(t, err) + + vmHooks := createHooksWithBaseSetup() + hooks := vmHooks.hooks + managedType := vmHooks.managedType + runtime := vmHooks.runtime + + managedType.On("GetBytes", int32(1)).Return([]byte("invalid proof"), nil) + managedType.On("GetBytes", int32(2)).Return(serializedVK.Bytes(), nil) + managedType.On("GetBytes", int32(3)).Return(pubWBytes, nil) + managedType.On("ConsumeGasForBytes", mock.Anything).Return(nil) + runtime.On("IsUnsafeMode").Return(false) + runtime.On("FailExecution", mock.Anything).Return() + + ret := hooks.ManagedVerifyPlonk(int32(ecc.BLS12_381), 1, 2, 3) + + assert.Equal(t, int32(-1), ret) + runtime.AssertCalled(t, "FailExecution", mock.Anything) +} + +func TestManagedAddEC_Success(t *testing.T) { + vmHooks := createHooksWithBaseSetup() + hooks := vmHooks.hooks + managedType := vmHooks.managedType + runtime := vmHooks.runtime + + p1, _ := bn254.NewPointG1().Pick() + p2, _ := bn254.NewPointG1().Pick() + p3, _ := p1.Add(p2) + p1Bytes, _ := p1.MarshalBinary() + p2Bytes, _ := p2.MarshalBinary() + p3Bytes, _ := p3.MarshalBinary() + + managedType.On("GetBytes", int32(1)).Return(p1Bytes, nil) + managedType.On("GetBytes", int32(2)).Return(p2Bytes, nil) + managedType.On("ConsumeGasForBytes", mock.Anything).Return(nil) + managedType.On("SetBytes", int32(3), p3Bytes).Return() + + ret := hooks.ManagedAddEC(int32(lowLevelFeatures.BN254), int32(lowLevelFeatures.G1), 1, 2, 3) + assert.Equal(t, int32(0), ret) + runtime.AssertNotCalled(t, "FailExecution", mock.Anything) +} + +func TestManagedMulEC_Success(t *testing.T) { + vmHooks := createHooksWithBaseSetup() + hooks := vmHooks.hooks + managedType := vmHooks.managedType + runtime := vmHooks.runtime + + p, _ := bn254.NewPointG1().Pick() + s, _ := bn254.NewScalar().Pick() + res, _ := p.Mul(s) + pBytes, _ := p.MarshalBinary() + sBytes, _ := s.MarshalBinary() + resBytes, _ := res.MarshalBinary() + + managedType.On("GetBytes", int32(1)).Return(pBytes, nil) + managedType.On("GetBytes", int32(2)).Return(sBytes, nil) + managedType.On("ConsumeGasForBytes", mock.Anything).Return(nil) + managedType.On("SetBytes", int32(3), resBytes).Return() + + ret := hooks.ManagedMulEC(int32(lowLevelFeatures.BN254), int32(lowLevelFeatures.G1), 1, 2, 3) + assert.Equal(t, int32(0), ret) + runtime.AssertNotCalled(t, "FailExecution", mock.Anything) +} + +func TestManagedVerifyGroth16_Fail_GetProofBytes(t *testing.T) { + vmHooks := createHooksWithBaseSetup() + managedType := vmHooks.managedType + runtime := vmHooks.runtime + managedType.On("GetBytes", int32(1)).Return(nil, assert.AnError) + runtime.On("FailExecution", mock.Anything).Return() + + ret := vmHooks.hooks.ManagedVerifyGroth16(int32(ecc.BLS12_381), 1, 2, 3) + assert.Equal(t, int32(-1), ret) + runtime.AssertCalled(t, "FailExecution", mock.Anything) +} + +func TestManagedVerifyGroth16_Fail_GetVKBytes(t *testing.T) { + vmHooks := createHooksWithBaseSetup() + managedType := vmHooks.managedType + runtime := vmHooks.runtime + managedType.On("GetBytes", int32(1)).Return([]byte("dummy proof"), nil) + managedType.On("GetBytes", int32(2)).Return(nil, assert.AnError) + managedType.On("ConsumeGasForBytes", mock.Anything).Return(nil) + runtime.On("FailExecution", mock.Anything).Return() + + ret := vmHooks.hooks.ManagedVerifyGroth16(int32(ecc.BLS12_381), 1, 2, 3) + assert.Equal(t, int32(-1), ret) + runtime.AssertCalled(t, "FailExecution", mock.Anything) +} + +func TestManagedVerifyGroth16_Fail_GetPubWitnessBytes(t *testing.T) { + vmHooks := createHooksWithBaseSetup() + managedType := vmHooks.managedType + runtime := vmHooks.runtime + managedType.On("GetBytes", int32(1)).Return([]byte("dummy proof"), nil) + managedType.On("GetBytes", int32(2)).Return([]byte("dummy vk"), nil) + managedType.On("GetBytes", int32(3)).Return(nil, assert.AnError) + managedType.On("ConsumeGasForBytes", mock.Anything).Return(nil).Times(2) + runtime.On("FailExecution", mock.Anything).Return() + + ret := vmHooks.hooks.ManagedVerifyGroth16(int32(ecc.BLS12_381), 1, 2, 3) + assert.Equal(t, int32(-1), ret) + runtime.AssertCalled(t, "FailExecution", mock.Anything) +} + +func TestManagedVerifyGroth16_Fail_Verification(t *testing.T) { + vmHooks := createHooksWithBaseSetup() + managedType := vmHooks.managedType + runtime := vmHooks.runtime + managedType.On("GetBytes", int32(1)).Return([]byte("dummy proof"), nil) + managedType.On("GetBytes", int32(2)).Return([]byte("dummy vk"), nil) + managedType.On("GetBytes", int32(3)).Return([]byte("dummy witness"), nil) + managedType.On("ConsumeGasForBytes", mock.Anything).Return(nil).Times(3) + runtime.On("IsUnsafeMode").Return(true) + runtime.On("FailExecution", mock.Anything).Return() + + ret := vmHooks.hooks.ManagedVerifyGroth16(int32(ecc.BLS12_381), 1, 2, 3) + assert.Equal(t, int32(-1), ret) + runtime.AssertCalled(t, "FailExecution", mock.Anything) +} + +func TestManagedVerifyGroth16_Fail_InvalidCurve(t *testing.T) { + vmHooks := createHooksWithBaseSetup() + managedType := vmHooks.managedType + runtime := vmHooks.runtime + managedType.On("GetBytes", int32(1)).Return([]byte("dummy proof"), nil) + managedType.On("GetBytes", int32(2)).Return([]byte("dummy vk"), nil) + managedType.On("GetBytes", int32(3)).Return([]byte("dummy witness"), nil) + managedType.On("ConsumeGasForBytes", mock.Anything).Return(nil).Times(3) + runtime.On("IsUnsafeMode").Return(true) + runtime.On("FailExecution", mock.Anything).Return() + + ret := vmHooks.hooks.ManagedVerifyGroth16(int32(42), 1, 2, 3) + assert.Equal(t, int32(-1), ret) + runtime.AssertCalled(t, "FailExecution", mock.Anything) +} + +func TestManagedVerifyPlonk_Fail_GetProofBytes(t *testing.T) { + vmHooks := createHooksWithBaseSetup() + managedType := vmHooks.managedType + runtime := vmHooks.runtime + managedType.On("GetBytes", int32(1)).Return(nil, assert.AnError) + runtime.On("FailExecution", mock.Anything).Return() + + ret := vmHooks.hooks.ManagedVerifyPlonk(int32(ecc.BLS12_381), 1, 2, 3) + assert.Equal(t, int32(-1), ret) + runtime.AssertCalled(t, "FailExecution", mock.Anything) +} + +func TestManagedVerifyPlonk_Fail_GetVKBytes(t *testing.T) { + vmHooks := createHooksWithBaseSetup() + managedType := vmHooks.managedType + runtime := vmHooks.runtime + managedType.On("GetBytes", int32(1)).Return([]byte("dummy proof"), nil) + managedType.On("GetBytes", int32(2)).Return(nil, assert.AnError) + managedType.On("ConsumeGasForBytes", mock.Anything).Return(nil) + runtime.On("FailExecution", mock.Anything).Return() + + ret := vmHooks.hooks.ManagedVerifyPlonk(int32(ecc.BLS12_381), 1, 2, 3) + assert.Equal(t, int32(-1), ret) + runtime.AssertCalled(t, "FailExecution", mock.Anything) +} + +func TestManagedVerifyPlonk_Fail_GetPubWitnessBytes(t *testing.T) { + vmHooks := createHooksWithBaseSetup() + managedType := vmHooks.managedType + runtime := vmHooks.runtime + managedType.On("GetBytes", int32(1)).Return([]byte("dummy proof"), nil) + managedType.On("GetBytes", int32(2)).Return([]byte("dummy vk"), nil) + managedType.On("GetBytes", int32(3)).Return(nil, assert.AnError) + managedType.On("ConsumeGasForBytes", mock.Anything).Return(nil).Times(2) + runtime.On("FailExecution", mock.Anything).Return() + + ret := vmHooks.hooks.ManagedVerifyPlonk(int32(ecc.BLS12_381), 1, 2, 3) + assert.Equal(t, int32(-1), ret) + runtime.AssertCalled(t, "FailExecution", mock.Anything) +} + +func TestManagedVerifyPlonk_Fail_Verification(t *testing.T) { + vmHooks := createHooksWithBaseSetup() + managedType := vmHooks.managedType + runtime := vmHooks.runtime + managedType.On("GetBytes", int32(1)).Return([]byte("dummy proof"), nil) + managedType.On("GetBytes", int32(2)).Return([]byte("dummy vk"), nil) + managedType.On("GetBytes", int32(3)).Return([]byte("dummy witness"), nil) + managedType.On("ConsumeGasForBytes", mock.Anything).Return(nil).Times(3) + runtime.On("IsUnsafeMode").Return(true) + runtime.On("FailExecution", mock.Anything).Return() + + ret := vmHooks.hooks.ManagedVerifyPlonk(int32(ecc.BLS12_381), 1, 2, 3) + assert.Equal(t, int32(-1), ret) + runtime.AssertCalled(t, "FailExecution", mock.Anything) +} + +func TestManagedVerifyPlonk_Fail_InvalidCurve(t *testing.T) { + vmHooks := createHooksWithBaseSetup() + managedType := vmHooks.managedType + runtime := vmHooks.runtime + managedType.On("GetBytes", int32(1)).Return([]byte("dummy proof"), nil) + managedType.On("GetBytes", int32(2)).Return([]byte("dummy vk"), nil) + managedType.On("GetBytes", int32(3)).Return([]byte("dummy witness"), nil) + managedType.On("ConsumeGasForBytes", mock.Anything).Return(nil).Times(3) + runtime.On("IsUnsafeMode").Return(true) + runtime.On("FailExecution", mock.Anything).Return() + + ret := vmHooks.hooks.ManagedVerifyPlonk(int32(42), 1, 2, 3) + assert.Equal(t, int32(-1), ret) + runtime.AssertCalled(t, "FailExecution", mock.Anything) +} diff --git a/wasmer2/libvmexeccapi.dylib b/wasmer2/libvmexeccapi.dylib index 1bc201858..0d36cac09 100755 Binary files a/wasmer2/libvmexeccapi.dylib and b/wasmer2/libvmexeccapi.dylib differ diff --git a/wasmer2/libvmexeccapi.h b/wasmer2/libvmexeccapi.h index bd83b544f..3cab72d42 100644 --- a/wasmer2/libvmexeccapi.h +++ b/wasmer2/libvmexeccapi.h @@ -320,6 +320,13 @@ typedef struct { int32_t (*managed_get_num_errors_func_ptr)(void *context); void (*managed_get_error_with_index_func_ptr)(void *context, int32_t index, int32_t error_handle); void (*managed_get_last_error_func_ptr)(void *context, int32_t error_handle); + int32_t (*managed_verify_groth16_func_ptr)(void *context, int32_t curve_id, int32_t proof_handle, int32_t vk_handle, int32_t pub_witness_handle); + int32_t (*managed_verify_plonk_func_ptr)(void *context, int32_t curve_id, int32_t proof_handle, int32_t vk_handle, int32_t pub_witness_handle); + int32_t (*managed_add_ec_func_ptr)(void *context, int32_t curve_id, int32_t group_id, int32_t point1_handle, int32_t point2_handle, int32_t result_handle); + int32_t (*managed_mul_ec_func_ptr)(void *context, int32_t curve_id, int32_t group_id, int32_t point_handle, int32_t scalar_handle, int32_t result_handle); + int32_t (*managed_multi_exp_ec_func_ptr)(void *context, int32_t curve_id, int32_t group_id, int32_t points_handle, int32_t scalars_handle, int32_t result_handle); + int32_t (*managed_map_to_curve_ec_func_ptr)(void *context, int32_t curve_id, int32_t group_id, int32_t element_handle, int32_t result_handle); + int32_t (*managed_pairing_checks_ec_func_ptr)(void *context, int32_t curve_id, int32_t points_g1_handle, int32_t points_g2_handle); } vm_exec_vm_hook_c_func_pointers; typedef struct { diff --git a/wasmer2/libvmexeccapi.so b/wasmer2/libvmexeccapi.so index bfb92d5df..1f41ad804 100755 Binary files a/wasmer2/libvmexeccapi.so and b/wasmer2/libvmexeccapi.so differ diff --git a/wasmer2/libvmexeccapi_arm.dylib b/wasmer2/libvmexeccapi_arm.dylib index 09a7afaae..18777c371 100755 Binary files a/wasmer2/libvmexeccapi_arm.dylib and b/wasmer2/libvmexeccapi_arm.dylib differ diff --git a/wasmer2/libvmexeccapi_arm.so b/wasmer2/libvmexeccapi_arm.so index 8f3202859..c2ff8c83e 100644 Binary files a/wasmer2/libvmexeccapi_arm.so and b/wasmer2/libvmexeccapi_arm.so differ diff --git a/wasmer2/wasmer2ImportsCgo.go b/wasmer2/wasmer2ImportsCgo.go index a755ccc2f..151fb63d0 100644 --- a/wasmer2/wasmer2ImportsCgo.go +++ b/wasmer2/wasmer2ImportsCgo.go @@ -293,6 +293,13 @@ package wasmer2 // extern int32_t w2_managedGetNumErrors(void* context); // extern void w2_managedGetErrorWithIndex(void* context, int32_t index, int32_t errorHandle); // extern void w2_managedGetLastError(void* context, int32_t errorHandle); +// extern int32_t w2_managedVerifyGroth16(void* context, int32_t curveID, int32_t proofHandle, int32_t vkHandle, int32_t pubWitnessHandle); +// extern int32_t w2_managedVerifyPlonk(void* context, int32_t curveID, int32_t proofHandle, int32_t vkHandle, int32_t pubWitnessHandle); +// extern int32_t w2_managedAddEC(void* context, int32_t curveID, int32_t groupID, int32_t point1Handle, int32_t point2Handle, int32_t resultHandle); +// extern int32_t w2_managedMulEC(void* context, int32_t curveID, int32_t groupID, int32_t pointHandle, int32_t scalarHandle, int32_t resultHandle); +// extern int32_t w2_managedMultiExpEC(void* context, int32_t curveID, int32_t groupID, int32_t pointsHandle, int32_t scalarsHandle, int32_t resultHandle); +// extern int32_t w2_managedMapToCurveEC(void* context, int32_t curveID, int32_t groupID, int32_t elementHandle, int32_t resultHandle); +// extern int32_t w2_managedPairingChecksEC(void* context, int32_t curveID, int32_t pointsG1Handle, int32_t pointsG2Handle); import "C" import ( @@ -586,6 +593,13 @@ func populateCgoFunctionPointers() *cWasmerVmHookPointers { managed_get_num_errors_func_ptr: funcPointer(C.w2_managedGetNumErrors), managed_get_error_with_index_func_ptr: funcPointer(C.w2_managedGetErrorWithIndex), managed_get_last_error_func_ptr: funcPointer(C.w2_managedGetLastError), + managed_verify_groth16_func_ptr: funcPointer(C.w2_managedVerifyGroth16), + managed_verify_plonk_func_ptr: funcPointer(C.w2_managedVerifyPlonk), + managed_add_ec_func_ptr: funcPointer(C.w2_managedAddEC), + managed_mul_ec_func_ptr: funcPointer(C.w2_managedMulEC), + managed_multi_exp_ec_func_ptr: funcPointer(C.w2_managedMultiExpEC), + managed_map_to_curve_ec_func_ptr: funcPointer(C.w2_managedMapToCurveEC), + managed_pairing_checks_ec_func_ptr: funcPointer(C.w2_managedPairingChecksEC), } } @@ -2280,3 +2294,45 @@ func w2_managedGetLastError(context unsafe.Pointer, errorHandle int32) { vmHooks := getVMHooksFromContextRawPtr(context) vmHooks.ManagedGetLastError(errorHandle) } + +//export w2_managedVerifyGroth16 +func w2_managedVerifyGroth16(context unsafe.Pointer, curveID int32, proofHandle int32, vkHandle int32, pubWitnessHandle int32) int32 { + vmHooks := getVMHooksFromContextRawPtr(context) + return vmHooks.ManagedVerifyGroth16(curveID, proofHandle, vkHandle, pubWitnessHandle) +} + +//export w2_managedVerifyPlonk +func w2_managedVerifyPlonk(context unsafe.Pointer, curveID int32, proofHandle int32, vkHandle int32, pubWitnessHandle int32) int32 { + vmHooks := getVMHooksFromContextRawPtr(context) + return vmHooks.ManagedVerifyPlonk(curveID, proofHandle, vkHandle, pubWitnessHandle) +} + +//export w2_managedAddEC +func w2_managedAddEC(context unsafe.Pointer, curveID int32, groupID int32, point1Handle int32, point2Handle int32, resultHandle int32) int32 { + vmHooks := getVMHooksFromContextRawPtr(context) + return vmHooks.ManagedAddEC(curveID, groupID, point1Handle, point2Handle, resultHandle) +} + +//export w2_managedMulEC +func w2_managedMulEC(context unsafe.Pointer, curveID int32, groupID int32, pointHandle int32, scalarHandle int32, resultHandle int32) int32 { + vmHooks := getVMHooksFromContextRawPtr(context) + return vmHooks.ManagedMulEC(curveID, groupID, pointHandle, scalarHandle, resultHandle) +} + +//export w2_managedMultiExpEC +func w2_managedMultiExpEC(context unsafe.Pointer, curveID int32, groupID int32, pointsHandle int32, scalarsHandle int32, resultHandle int32) int32 { + vmHooks := getVMHooksFromContextRawPtr(context) + return vmHooks.ManagedMultiExpEC(curveID, groupID, pointsHandle, scalarsHandle, resultHandle) +} + +//export w2_managedMapToCurveEC +func w2_managedMapToCurveEC(context unsafe.Pointer, curveID int32, groupID int32, elementHandle int32, resultHandle int32) int32 { + vmHooks := getVMHooksFromContextRawPtr(context) + return vmHooks.ManagedMapToCurveEC(curveID, groupID, elementHandle, resultHandle) +} + +//export w2_managedPairingChecksEC +func w2_managedPairingChecksEC(context unsafe.Pointer, curveID int32, pointsG1Handle int32, pointsG2Handle int32) int32 { + vmHooks := getVMHooksFromContextRawPtr(context) + return vmHooks.ManagedPairingChecksEC(curveID, pointsG1Handle, pointsG2Handle) +} diff --git a/wasmer2/wasmer2Names.go b/wasmer2/wasmer2Names.go index 5e654624a..141f8e1c6 100644 --- a/wasmer2/wasmer2Names.go +++ b/wasmer2/wasmer2Names.go @@ -291,4 +291,11 @@ var functionNames = map[string]struct{}{ "managedGetNumErrors": empty, "managedGetErrorWithIndex": empty, "managedGetLastError": empty, + "managedVerifyGroth16": empty, + "managedVerifyPlonk": empty, + "managedAddEC": empty, + "managedMulEC": empty, + "managedMultiExpEC": empty, + "managedMapToCurveEC": empty, + "managedPairingChecksEC": empty, }