Skip to content

Commit

Permalink
Merge pull request #835 from multiversx/rc/v1.7.next1
Browse files Browse the repository at this point in the history
rc/1.7.next1
  • Loading branch information
sstanculeanu authored Nov 13, 2024
2 parents 24baab0 + ed43cb5 commit 814ac75
Show file tree
Hide file tree
Showing 86 changed files with 4,619 additions and 1,459 deletions.
25 changes: 0 additions & 25 deletions .github/workflows/build-test-macos-arm64.yml

This file was deleted.

14 changes: 11 additions & 3 deletions .github/workflows/build-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ jobs:
go-version: ${{ matrix.go-version }}
- name: Checkout code
uses: actions/checkout@v2
- name: Test
run: |
make test

- name: Test (Linux)
if: runner.os == 'Linux'
run: |
make test
- name: Test (MacOS ARM64)
if: runner.os == 'macOS'
run: |
make test-w2
1 change: 1 addition & 0 deletions config/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
DeleteFromReturnData = 10
GetCodeMetadata = 10
IsBuiltinFunction = 10
IsReservedFunctionName = 10

[EthAPICost]
UseGas = 10
Expand Down
38 changes: 21 additions & 17 deletions config/gasCost.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ type BaseOpsAPICost struct {
DeleteFromReturnData uint64
GetCodeMetadata uint64
IsBuiltinFunction uint64
IsReservedFunctionName uint64
}

// DynamicStorageLoadCostCoefficients holds the signed coefficients of the func that will compute the gas cost
Expand Down Expand Up @@ -173,23 +174,26 @@ type BigFloatAPICost struct {

// CryptoAPICost defines the crypto operations gas cost config structure
type CryptoAPICost struct {
SHA256 uint64
Keccak256 uint64
Ripemd160 uint64
VerifyBLS uint64
VerifyEd25519 uint64
VerifySecp256k1 uint64
EllipticCurveNew uint64
AddECC uint64
DoubleECC uint64
IsOnCurveECC uint64
ScalarMultECC uint64
MarshalECC uint64
MarshalCompressedECC uint64
UnmarshalECC uint64
UnmarshalCompressedECC uint64
GenerateKeyECC uint64
EncodeDERSig uint64
SHA256 uint64
Keccak256 uint64
Ripemd160 uint64
VerifyBLS uint64
VerifyEd25519 uint64
VerifySecp256k1 uint64
EllipticCurveNew uint64
AddECC uint64
DoubleECC uint64
IsOnCurveECC uint64
ScalarMultECC uint64
MarshalECC uint64
MarshalCompressedECC uint64
UnmarshalECC uint64
UnmarshalCompressedECC uint64
GenerateKeyECC uint64
EncodeDERSig uint64
VerifySecp256r1 uint64
VerifyBLSSignatureShare uint64
VerifyBLSMultiSig uint64
}

// ManagedBufferAPICost defines the managed buffer operations gas cost config structure
Expand Down
9 changes: 9 additions & 0 deletions config/gasSchedule.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,11 @@ func FillGasMapBuiltInCosts(value uint64) map[string]uint64 {
gasMap["ESDTNFTAddUri"] = value
gasMap["ESDTNFTUpdateAttributes"] = value
gasMap["ESDTNFTMultiTransfer"] = value
gasMap["ESDTModifyRoyalties"] = value
gasMap["ESDTModifyCreator"] = value
gasMap["ESDTNFTRecreate"] = value
gasMap["ESDTNFTUpdate"] = value
gasMap["ESDTNFTSetNewURIs"] = value
gasMap["SetGuardian"] = value
gasMap["GuardAccount"] = value
gasMap["UnGuardAccount"] = value
Expand Down Expand Up @@ -308,6 +313,7 @@ func FillGasMapBaseOpsAPICosts(value, asyncCallbackGasLock uint64) map[string]ui
gasMap["DeleteFromReturnData"] = value
gasMap["GetCodeMetadata"] = value
gasMap["IsBuiltinFunction"] = value
gasMap["IsReservedFunctionName"] = value

return gasMap
}
Expand Down Expand Up @@ -443,6 +449,9 @@ func FillGasMapCryptoAPICosts(value uint64) map[string]uint64 {
gasMap["UnmarshalCompressedECC"] = value
gasMap["GenerateKeyECC"] = value
gasMap["EncodeDERSig"] = value
gasMap["VerifySecp256r1"] = value
gasMap["VerifyBLSSignatureShare"] = value
gasMap["VerifyBLSMultiSig"] = value

return gasMap
}
Expand Down
26 changes: 18 additions & 8 deletions crypto/factory/cryptovm.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,30 @@ import (
"github.com/multiversx/mx-chain-vm-go/crypto/hashing"
"github.com/multiversx/mx-chain-vm-go/crypto/signing/bls"
"github.com/multiversx/mx-chain-vm-go/crypto/signing/ed25519"
"github.com/multiversx/mx-chain-vm-go/crypto/signing/secp256k1"
"github.com/multiversx/mx-chain-vm-go/crypto/signing/secp256"
)

// NewVMCrypto returns a composite struct containing VMCrypto functionality implementations
func NewVMCrypto() crypto.VMCrypto {
func NewVMCrypto() (crypto.VMCrypto, error) {
blsVerifier, err := bls.NewBLS()
if err != nil {
return nil, err
}

secp, err := secp256.NewSecp256()
if err != nil {
return nil, err
}

return struct {
crypto.Hasher
crypto.Ed25519
crypto.BLS
crypto.Secp256k1
crypto.Secp256
}{
Hasher: hashing.NewHasher(),
Ed25519: ed25519.NewEd25519Signer(),
BLS: bls.NewBLS(),
Secp256k1: secp256k1.NewSecp256k1(),
}
Hasher: hashing.NewHasher(),
Ed25519: ed25519.NewEd25519Signer(),
BLS: blsVerifier,
Secp256: secp,
}, nil
}
9 changes: 6 additions & 3 deletions crypto/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,26 @@ type Hasher interface {
// BLS defines the functionality of a component able to verify BLS signatures
type BLS interface {
VerifyBLS(key []byte, msg []byte, sig []byte) error
VerifySignatureShare(publicKey []byte, message []byte, sig []byte) error
VerifyAggregatedSig(pubKeysSigners [][]byte, message []byte, aggSig []byte) error
}

// Ed25519 defines the functionality of a component able to verify Ed25519 signatures
type Ed25519 interface {
VerifyEd25519(key []byte, msg []byte, sig []byte) error
}

// Secp256k1 defines the functionality of a component able to verify and encode Secp256k1 signatures
type Secp256k1 interface {
// Secp256 defines the functionality of a component able to verify and encode Secp256 signatures
type Secp256 interface {
VerifySecp256k1(key []byte, msg []byte, sig []byte, hashType uint8) error
EncodeSecp256k1DERSignature(r, s []byte) []byte
VerifySecp256r1(key []byte, msg []byte, sig []byte) error
}

// VMCrypto will provide the interface to the main crypto functionalities of the vm
type VMCrypto interface {
Hasher
Ed25519
BLS
Secp256k1
Secp256
}
21 changes: 19 additions & 2 deletions crypto/signing/bls/bls.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,29 @@ import (
"github.com/multiversx/mx-chain-crypto-go"
"github.com/multiversx/mx-chain-crypto-go/signing"
"github.com/multiversx/mx-chain-crypto-go/signing/mcl"
mclMultiSig "github.com/multiversx/mx-chain-crypto-go/signing/mcl/multisig"
"github.com/multiversx/mx-chain-crypto-go/signing/mcl/singlesig"
"github.com/multiversx/mx-chain-crypto-go/signing/multisig"
)

type bls struct {
keyGenerator crypto.KeyGenerator
signer crypto.SingleSigner

multiSigner crypto.MultiSigner
}

// NewBLS returns the component able to verify BLS signatures
func NewBLS() *bls {
func NewBLS() (*bls, error) {
b := &bls{}
suite := mcl.NewSuiteBLS12()
b.keyGenerator = signing.NewKeyGenerator(suite)
b.signer = singlesig.NewBlsSigner()

return b
var err error
b.multiSigner, err = multisig.NewBLSMultisig(&mclMultiSig.BlsMultiSignerKOSK{}, b.keyGenerator)

return b, err
}

// VerifyBLS verifies a BLS signatures
Expand All @@ -31,3 +38,13 @@ func (b *bls) VerifyBLS(key []byte, msg []byte, sig []byte) error {

return b.signer.Verify(publicKey, msg, sig)
}

// VerifySignatureShare verifies signature share of BLS MultiSig
func (b *bls) VerifySignatureShare(publicKey []byte, message []byte, sig []byte) error {
return b.multiSigner.VerifySignatureShare(publicKey, message, sig)
}

// VerifyAggregatedSig verifies aggregated signature of BLS MultiSig
func (b *bls) VerifyAggregatedSig(pubKeysSigners [][]byte, message []byte, aggSig []byte) error {
return b.multiSigner.VerifyAggregatedSig(pubKeysSigners, message, aggSig)
}
118 changes: 117 additions & 1 deletion crypto/signing/bls/bls_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,71 @@ package bls

import (
"encoding/hex"
"fmt"
"strings"
"testing"

crypto "github.com/multiversx/mx-chain-crypto-go"
"github.com/multiversx/mx-chain-crypto-go/signing"
"github.com/multiversx/mx-chain-crypto-go/signing/mcl"
llsig "github.com/multiversx/mx-chain-crypto-go/signing/mcl/multisig"
"github.com/multiversx/mx-chain-crypto-go/signing/multisig"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

type multiSignerSetup struct {
privKeys [][]byte
pubKeys [][]byte
partialSignatures [][][]byte
messages []string
aggSignatures [][]byte
}

const checkOK = "3e886a4c6e109a151f4105aee65a5192d150ef1fa68d3cd76964a0b086006dbe4324c989deb0e4416c6d6706db1b1910eb2732f08842fb4886067b9ed191109ac2188d76002d2e11da80a3f0ea89fee6b59c834cc478a6bd49cb8a193b1abb16@e96bd0f36b70c5ccc0c4396343bd7d8255b8a526c55fa1e218511fafe6539b8e@04725db195e37aa237cdbbda76270d4a229b6e7a3651104dc58c4349c0388e8546976fe54a04240530b99064e434c90f"
const checkNOK = "2c9a358953f61d34401d7ee4175eec105c476b18baacab371e2f47270035b539d84ad79ba587552b7e38802be00ff7148fc2a9c7a7034ff1e63ee24602ee952235ad14ca7d36e2be617fb2c99ed22a7a2729d86ae9fbb4df06f957ba07fec50e@1e46d9cbb995e30b82485525c29f80ac78aca295a6e88a11c3df8f9a445494bb@be8c460db180d6254c712ead3aa81935bc9be15b919dd45cb152b3dece04762569778c5e70e7af03fa1c66409d4f4711"

func TestBls_VerifyBLS(t *testing.T) {
t.Parallel()

b := NewBLS()
b, _ := NewBLS()
assert.Nil(t, b.VerifyBLS(splitString(t, checkOK)))
assert.NotNil(t, b.VerifyBLS(splitString(t, checkNOK)))
}

func TestBls_VerifyBLSSigShare(t *testing.T) {
t.Parallel()

b, _ := NewBLS()
assert.Nil(t, b.VerifySignatureShare(splitString(t, checkOK)))
assert.NotNil(t, b.VerifySignatureShare(splitString(t, checkNOK)))
}

func TestBls_VerifyBLSMultiSig(t *testing.T) {
t.Parallel()

b, _ := NewBLS()

numMessages := 5
setupKOSK, multiSignerKOSK := createMultiSigSetupKOSK(uint16(numMessages), numMessages)
setupKOSK.aggSignatures = aggregateSignatures(setupKOSK, multiSignerKOSK)

for i := 0; i < len(setupKOSK.pubKeys); i++ {
fmt.Println(hex.EncodeToString(setupKOSK.pubKeys[i]))
}

for i := 0; i < numMessages; i++ {
fmt.Println(setupKOSK.messages[i])
fmt.Println(hex.EncodeToString(setupKOSK.aggSignatures[i]))

assert.Nil(t, b.VerifyAggregatedSig(setupKOSK.pubKeys, []byte(setupKOSK.messages[i]), setupKOSK.aggSignatures[i]))
changedSig := make([]byte, len(setupKOSK.aggSignatures[i]))
copy(changedSig, setupKOSK.aggSignatures[i])
changedSig[0] += 1
assert.NotNil(t, b.VerifyAggregatedSig(setupKOSK.pubKeys, []byte(setupKOSK.messages[i]), changedSig))
}
}

func splitString(t testing.TB, str string) ([]byte, []byte, []byte) {
split := strings.Split(str, "@")
pkBuff, err := hex.DecodeString(split[0])
Expand All @@ -33,3 +80,72 @@ func splitString(t testing.TB, str string) ([]byte, []byte, []byte) {

return pkBuff, msgBuff, sigBuff
}

func createKeysAndMultiSignerBlsKOSK(
grSize uint16,
suite crypto.Suite,
) ([][]byte, [][]byte, crypto.MultiSigner) {

kg, privKeys, pubKeys := createMultiSignerSetup(grSize, suite)
llSigner := &llsig.BlsMultiSignerKOSK{}
multiSigner, _ := multisig.NewBLSMultisig(llSigner, kg)

return privKeys, pubKeys, multiSigner
}

func createMultiSignerSetup(grSize uint16, suite crypto.Suite) (crypto.KeyGenerator, [][]byte, [][]byte) {
kg := signing.NewKeyGenerator(suite)
privKeys := make([][]byte, grSize)
pubKeys := make([][]byte, grSize)

for i := uint16(0); i < grSize; i++ {
sk, pk := kg.GeneratePair()
privKeys[i], _ = sk.ToByteArray()
pubKeys[i], _ = pk.ToByteArray()
}
return kg, privKeys, pubKeys
}

func createSignaturesShares(privKeys [][]byte, multiSigner crypto.MultiSigner, message []byte) [][]byte {
sigShares := make([][]byte, len(privKeys))
for i := uint16(0); i < uint16(len(privKeys)); i++ {
sigShares[i], _ = multiSigner.CreateSignatureShare(privKeys[i], message)
}

return sigShares
}

func createMultiSigSetupKOSK(numSigners uint16, numMessages int) (*multiSignerSetup, crypto.MultiSigner) {
var multiSigner crypto.MultiSigner
setup := &multiSignerSetup{}
suite := mcl.NewSuiteBLS12()
setup.privKeys, setup.pubKeys, multiSigner = createKeysAndMultiSignerBlsKOSK(numSigners, suite)
setup.messages, setup.partialSignatures = createMessagesAndPartialSignatures(numMessages, setup.privKeys, multiSigner)

return setup, multiSigner
}

func createMessagesAndPartialSignatures(numMessages int, privKeys [][]byte, multiSigner crypto.MultiSigner) ([]string, [][][]byte) {
partialSignatures := make([][][]byte, numMessages)
messages := make([]string, numMessages)

for i := 0; i < numMessages; i++ {
messages[i] = fmt.Sprintf("message%d", i)
signatures := createSignaturesShares(privKeys, multiSigner, []byte(messages[i]))
partialSignatures[i] = signatures
}

return messages, partialSignatures
}

func aggregateSignatures(
setup *multiSignerSetup,
multiSigner crypto.MultiSigner,
) [][]byte {
aggSignatures := make([][]byte, len(setup.messages))
for i := 0; i < len(setup.messages); i++ {
aggSignatures[i], _ = multiSigner.AggregateSigs(setup.pubKeys, setup.partialSignatures[i])
}

return aggSignatures
}
Loading

0 comments on commit 814ac75

Please sign in to comment.