Skip to content

Commit

Permalink
Merge pull request #189 from Fairblock/add-keyshare-module-unit-test
Browse files Browse the repository at this point in the history
Add keyshare module unit test
  • Loading branch information
p0p3yee authored Oct 1, 2024
2 parents 20fee9c + e16dda7 commit 773a65d
Show file tree
Hide file tree
Showing 36 changed files with 2,927 additions and 21 deletions.
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ require (
github.com/cosmos/ibc-go/modules/capability v1.0.0
github.com/cosmos/ibc-go/v8 v8.2.1
github.com/cosmos/interchain-security/v3 v3.2.0-consumer-rc0.0.20231123140529-1819e73f6197
github.com/decred/dcrd/dcrec/secp256k1 v1.0.4
github.com/drand/kyber v1.2.0
github.com/drand/kyber-bls12381 v0.3.1
github.com/golang/protobuf v1.5.4
Expand Down Expand Up @@ -112,6 +113,7 @@ require (
github.com/creachadair/tomledit v0.0.25 // indirect
github.com/danieljoos/wincred v1.2.1 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/decred/dcrd/dcrec/secp256k1/v2 v2.0.0 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect
github.com/dgraph-io/badger/v2 v2.2007.4 // indirect
Expand Down
7 changes: 7 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -423,8 +423,15 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/decred/dcrd/chaincfg/chainhash v1.0.2 h1:rt5Vlq/jM3ZawwiacWjPa+smINyLRN07EO0cNBV6DGU=
github.com/decred/dcrd/chaincfg/chainhash v1.0.2/go.mod h1:BpbrGgrPTr3YJYRN3Bm+D9NuaFd+zGyNeIKgrhCXK60=
github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc=
github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y=
github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
github.com/decred/dcrd/dcrec/secp256k1 v1.0.4 h1:0XErmfJBiVbl0NvyclGn4jr+1hIylDf5beFi9W0o7Fc=
github.com/decred/dcrd/dcrec/secp256k1 v1.0.4/go.mod h1:00z7mJdugt+GBAzPN1QrDRGCXxyKUiexEHu6ukxEw3k=
github.com/decred/dcrd/dcrec/secp256k1/v2 v2.0.0 h1:3GIJYXQDAKpLEFriGFN8SbSffak10UXHGdIcFaMPykY=
github.com/decred/dcrd/dcrec/secp256k1/v2 v2.0.0/go.mod h1:3s92l0paYkZoIHuj4X93Teg/HB7eGM9x/zokGw+u4mY=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I=
Expand Down
80 changes: 71 additions & 9 deletions testutil/keeper/keyshare.go
Original file line number Diff line number Diff line change
@@ -1,48 +1,103 @@
package keeper

import (
"testing"

"cosmossdk.io/log"
"cosmossdk.io/store"
"cosmossdk.io/store/metrics"
storetypes "cosmossdk.io/store/types"
pepkeeper "github.com/Fairblock/fairyring/x/pep/keeper"
peptypes "github.com/Fairblock/fairyring/x/pep/types"
cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
dbm "github.com/cosmos/cosmos-db"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/address"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/runtime"
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
stakingtestutil "github.com/cosmos/cosmos-sdk/x/staking/testutil"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
capabilitykeeper "github.com/cosmos/ibc-go/modules/capability/keeper"
portkeeper "github.com/cosmos/ibc-go/v8/modules/core/05-port/keeper"
ibcexported "github.com/cosmos/ibc-go/v8/modules/core/exported"
ibckeeper "github.com/cosmos/ibc-go/v8/modules/core/keeper"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/require"
"testing"

"github.com/Fairblock/fairyring/x/keyshare/keeper"
"github.com/Fairblock/fairyring/x/keyshare/types"
)

func KeyshareKeeper(t testing.TB) (keeper.Keeper, sdk.Context) {
var (
bondedAcc = authtypes.NewEmptyModuleAccount(stakingtypes.BondedPoolName)
notBondedAcc = authtypes.NewEmptyModuleAccount(stakingtypes.NotBondedPoolName)
PKs = simtestutil.CreateTestPubKeys(500)
)

func KeyshareKeeper(t testing.TB) (keeper.Keeper, sdk.Context, pepkeeper.Keeper, *stakingkeeper.Keeper) {
storeKey := storetypes.NewKVStoreKey(types.StoreKey)
pepStoreKey := storetypes.NewKVStoreKey(peptypes.StoreKey)
stakingStoreKey := storetypes.NewKVStoreKey(stakingtypes.StoreKey)
memStoreKey := storetypes.NewMemoryStoreKey(types.MemStoreKey)
pepMemStoreKey := storetypes.NewMemoryStoreKey(peptypes.MemStoreKey)

db := dbm.NewMemDB()
stateStore := store.NewCommitMultiStore(db, log.NewNopLogger(), metrics.NewNoOpMetrics())
stateStore.MountStoreWithDB(storeKey, storetypes.StoreTypeIAVL, db)
stateStore.MountStoreWithDB(pepStoreKey, storetypes.StoreTypeIAVL, db)
stateStore.MountStoreWithDB(stakingStoreKey, storetypes.StoreTypeIAVL, db)
stateStore.MountStoreWithDB(memStoreKey, storetypes.StoreTypeMemory, nil)
stateStore.MountStoreWithDB(pepMemStoreKey, storetypes.StoreTypeMemory, nil)
require.NoError(t, stateStore.LoadLatestVersion())

registry := codectypes.NewInterfaceRegistry()
appCodec := codec.NewProtoCodec(registry)

capabilityKeeper := capabilitykeeper.NewKeeper(appCodec, storeKey, memStoreKey)
authority := authtypes.NewModuleAddress(govtypes.ModuleName)

scopedKeeper := capabilityKeeper.ScopeToModule(ibcexported.ModuleName)
portKeeper := portkeeper.NewKeeper(scopedKeeper)
// scopeModule := capabilityKeeper.ScopeToModule(types.ModuleName)

pepCapabilityKeeper := capabilitykeeper.NewKeeper(appCodec, pepStoreKey, pepMemStoreKey)
pepScopedKeeper := pepCapabilityKeeper.ScopeToModule(ibcexported.ModuleName)
pepPortKeeper := portkeeper.NewKeeper(pepScopedKeeper)

ctrl := gomock.NewController(t)
accountKeeper := stakingtestutil.NewMockAccountKeeper(ctrl)
accountKeeper.EXPECT().GetModuleAddress(stakingtypes.BondedPoolName).Return(bondedAcc.GetAddress())
accountKeeper.EXPECT().GetModuleAddress(stakingtypes.NotBondedPoolName).Return(notBondedAcc.GetAddress())
accountKeeper.EXPECT().AddressCodec().Return(address.NewBech32Codec("cosmos")).AnyTimes()

bankKeeper := stakingtestutil.NewMockBankKeeper(ctrl)

pepKeeper := pepkeeper.NewKeeper(
appCodec,
runtime.NewKVStoreService(pepStoreKey),
log.NewNopLogger(),
authority.String(),
func() *ibckeeper.Keeper {
return &ibckeeper.Keeper{
PortKeeper: &pepPortKeeper,
}
},
pepScopedKeeper,
accountKeeper,
nil,
)

stakingKeeper := stakingkeeper.NewKeeper(
appCodec,
runtime.NewKVStoreService(stakingStoreKey),
accountKeeper,
bankKeeper,
authority.String(),
address.NewBech32Codec("cosmosvaloper"),
address.NewBech32Codec("cosmosvalcons"),
)

k := keeper.NewKeeper(
appCodec,
Expand All @@ -58,11 +113,11 @@ func KeyshareKeeper(t testing.TB) (keeper.Keeper, sdk.Context) {
//func(string) capabilitykeeper.ScopedKeeper {
// return scopeModule
//},
accountKeeper,
nil,
pepKeeper,
nil,
nil,
nil,
nil,
stakingKeeper,
nil,
)

Expand All @@ -72,6 +127,13 @@ func KeyshareKeeper(t testing.TB) (keeper.Keeper, sdk.Context) {
if err := k.SetParams(ctx, types.DefaultParams()); err != nil {
panic(err)
}
// Initialize params
if err := pepKeeper.SetParams(ctx, peptypes.DefaultParams()); err != nil {
panic(err)
}
if err := stakingKeeper.SetParams(ctx, stakingtypes.DefaultParams()); err != nil {
panic(err)
}

return k, ctx
return k, ctx, pepKeeper, stakingKeeper
}
19 changes: 19 additions & 0 deletions testutil/random/hex.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package random

import (
"encoding/hex"
"math/rand"
"time"
)

// RandHex returns a random hexadecimal string of length n.
func RandHex(n int) string {
src := rand.New(rand.NewSource(time.Now().UnixNano()))
b := make([]byte, (n+1)/2)

if _, err := src.Read(b); err != nil {
panic(err)
}

return hex.EncodeToString(b)[:n]
}
104 changes: 104 additions & 0 deletions testutil/random/pubkey.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package random

import (
"encoding/base64"
"encoding/hex"
distIBE "github.com/FairBlock/DistributedIBE"
"github.com/Fairblock/fairyring/testutil/sample"
"github.com/Fairblock/fairyring/x/keyshare/types"
dcrdSecp256k1 "github.com/decred/dcrd/dcrec/secp256k1"
"github.com/drand/kyber"
bls "github.com/drand/kyber-bls12381"
"math"
"math/big"
)

type GeneratedShare struct {
Share string
EncShare string
Index kyber.Scalar
PrivateKey *dcrdSecp256k1.PrivateKey
PK *dcrdSecp256k1.PublicKey
ValidatorAddress string
}

type GenerateResult struct {
GeneratedShare []*GeneratedShare
KeyShareEncryptedKeyShares []*types.EncryptedKeyShare
Commitments []string
MasterPublicKey string
}

func GeneratePubKeyAndShares(totalNumberOfValidator uint32) (*GenerateResult, error) {

t := int(math.Ceil(float64(totalNumberOfValidator) * (2.0 / 3.0)))

shares, mpk, _, err := distIBE.GenerateShares(totalNumberOfValidator, uint32(t))
if err != nil {
return nil, err
}

masterPublicKeyByte, err := mpk.MarshalBinary()
if err != nil {
return nil, err
}

var result GenerateResult
result.MasterPublicKey = hex.EncodeToString(masterPublicKeyByte)

suite := bls.NewBLS12381Suite()
keyShareCommitments := make([]string, totalNumberOfValidator)
sharesList := make([]*GeneratedShare, totalNumberOfValidator)

for _, s := range shares {
indexByte, _ := hex.DecodeString(s.Index.String())
indexInt := big.NewInt(0).SetBytes(indexByte).Uint64()

commitmentPoints := suite.G1().Point().Mul(s.Value, suite.G1().Point().Base())
commitmentPointsBinary, _ := commitmentPoints.MarshalBinary()

keyShareCommitments[indexInt-1] = hex.EncodeToString(commitmentPointsBinary)

randomAddr := sample.AccAddress()
sb, _ := s.Value.MarshalBinary()
privKey, err := dcrdSecp256k1.GeneratePrivateKey()
if err != nil {
return nil, err
}

res, err := dcrdSecp256k1.Encrypt(privKey.PubKey(), sb)
if err != nil {
return nil, err
}

share := GeneratedShare{
hex.EncodeToString(sb),
base64.StdEncoding.EncodeToString(res),
s.Index,
privKey,
privKey.PubKey(),
randomAddr,
}

sharesList[indexInt-1] = &share
}

n := len(sharesList)

encShares := make([]*types.EncryptedKeyShare, n)

for _, v := range sharesList {
indexByte, _ := hex.DecodeString(v.Index.String())
indexInt := big.NewInt(0).SetBytes(indexByte).Uint64()
encShares[indexInt-1] = &types.EncryptedKeyShare{
Data: v.EncShare,
Validator: v.ValidatorAddress,
}
}

result.GeneratedShare = sharesList
result.KeyShareEncryptedKeyShares = encShares
result.Commitments = keyShareCommitments

return &result, nil
}
38 changes: 38 additions & 0 deletions testutil/shares/derive.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package shares

import (
"encoding/hex"
distIBE "github.com/FairBlock/DistributedIBE"
bls "github.com/drand/kyber-bls12381"
)

func DeriveShare(hexShare string, shareIndex uint32, id string) (string, error) {
shareByte, err := hex.DecodeString(hexShare)
if err != nil {
return "", err
}

share := bls.NewKyberScalar()
err = share.UnmarshalBinary(shareByte)
if err != nil {
return "", err
}

s := bls.NewBLS12381Suite()
extractedKey := distIBE.Extract(s, share, shareIndex, []byte(id))

extractedBinary, err := extractedKey.SK.MarshalBinary()
if err != nil {
return "", err
}
extractedKeyHex := hex.EncodeToString(extractedBinary)

// commitmentPoint := s.G1().Point().Mul(share, s.G1().Point().Base())
//commitmentBinary, err := commitmentPoint.MarshalBinary()
//if err != nil {
// return "", err
//}
// commitmentHex := hex.EncodeToString(commitmentBinary)

return extractedKeyHex, nil
}
30 changes: 30 additions & 0 deletions testutil/shares/encrypt.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package shares

import (
"encoding/base64"
"encoding/hex"
"github.com/btcsuite/btcd/btcec"
)

// EncryptWithPublicKey encrypts data using an RSA public key.
func EncryptWithPublicKey(data string, pubKeyBase64 string) (string, error) {
// Decode the base64 public key
pubKeyBytes, err := base64.StdEncoding.DecodeString(pubKeyBase64)
if err != nil {
return "", err
}

// Load the secp256k1 public key
pubKey, err := btcec.ParsePubKey(pubKeyBytes, btcec.S256())
if err != nil {
return "", err
}

ciphertext, err := btcec.Encrypt(pubKey, []byte(data))
if err != nil {
return "", err
}

// Encode ciphertext as hex for easy handling
return hex.EncodeToString(ciphertext), nil
}
Loading

0 comments on commit 773a65d

Please sign in to comment.