Add extended public key as IssuerPlanetmint (#62)

* Fix package and domain name

Signed-off-by: Julian Strobl <jmastr@mailbox.org>

* Add extended public key as `IssuerPlanetmint`

This patch introduces parts of the `chaincfg` for Planetmint and
especially the magic bytes that produces extended keys with the prefix
`pmpr` for a Planetmint extended private key and `pmpb` for a Planetmint
extended public key.

// Closes https://github.com/rddl-network/issues/issues/30

Signed-off-by: Julian Strobl <jmastr@mailbox.org>

* Validate Planetmint extended public key during machine attestation

Signed-off-by: Julian Strobl <jmastr@mailbox.org>

* [lint] Fix error return value is not checked

Signed-off-by: Julian Strobl <jmastr@mailbox.org>

---------

Signed-off-by: Julian Strobl <jmastr@mailbox.org>
This commit is contained in:
Julian Strobl 2023-08-11 09:14:52 +02:00 committed by GitHub
parent 01ef2dbfd0
commit 1383d0aaa6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 60 additions and 18 deletions

View File

@ -1,4 +1,4 @@
package app package config
import ( import (
"encoding/json" "encoding/json"

25
config/params.go Normal file
View File

@ -0,0 +1,25 @@
package config
import (
"github.com/btcsuite/btcd/chaincfg"
)
// PlmntNetParams defines the network parameters for the Planetmint network.
var PlmntNetParams = chaincfg.Params{
Name: "planetmint",
// BIP32 hierarchical deterministic extended key magics
HDPrivateKeyID: [4]byte{0x03, 0xe1, 0x42, 0xb0}, // starts with pmpr
HDPublicKeyID: [4]byte{0x03, 0xe1, 0x42, 0x47}, // starts with pmpb
// BIP44 coin type used in the hierarchical deterministic path for
// address generation.
HDCoinType: 8680,
}
func init() {
err := chaincfg.Register(&PlmntNetParams)
if err != nil {
panic(err)
}
}

View File

@ -3,12 +3,14 @@ package keeper
import ( import (
"testing" "testing"
"planetmint-go/config"
"planetmint-go/testutil/sample" "planetmint-go/testutil/sample"
"planetmint-go/x/asset/keeper" "planetmint-go/x/asset/keeper"
"planetmint-go/x/asset/types" "planetmint-go/x/asset/types"
assettestutils "planetmint-go/x/asset/testutil" assettestutils "planetmint-go/x/asset/testutil"
"github.com/btcsuite/btcd/chaincfg"
tmdb "github.com/cometbft/cometbft-db" tmdb "github.com/cometbft/cometbft-db"
"github.com/cometbft/cometbft/libs/log" "github.com/cometbft/cometbft/libs/log"
tmproto "github.com/cometbft/cometbft/proto/tendermint/types" tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
@ -48,8 +50,9 @@ func AssetKeeper(t testing.TB) (*keeper.Keeper, sdk.Context) {
ctrl := gomock.NewController(t) ctrl := gomock.NewController(t)
mk := assettestutils.NewMockMachineKeeper(ctrl) mk := assettestutils.NewMockMachineKeeper(ctrl)
sk, pk := sample.KeyPair() sk, pk := sample.KeyPair()
_, lpk := sample.LiquidKeyPair() _, ppk := sample.ExtendedKeyPair(config.PlmntNetParams)
id := sample.MachineIndex(pk, lpk) _, lpk := sample.ExtendedKeyPair(chaincfg.MainNetParams)
id := sample.MachineIndex(pk, ppk, lpk)
mk.EXPECT().GetMachineIndex(ctx, pk).Return(id, true).AnyTimes() mk.EXPECT().GetMachineIndex(ctx, pk).Return(id, true).AnyTimes()
mk.EXPECT().GetMachineIndex(ctx, sk).Return(id, false).AnyTimes() mk.EXPECT().GetMachineIndex(ctx, sk).Return(id, false).AnyTimes()
mk.EXPECT().GetMachine(ctx, id).Return(sample.Machine(pk, pk), true).AnyTimes() mk.EXPECT().GetMachine(ctx, id).Return(sample.Machine(pk, pk), true).AnyTimes()

View File

@ -3,6 +3,7 @@ package sample
import ( import (
"encoding/hex" "encoding/hex"
"planetmint-go/config"
machinetypes "planetmint-go/x/machine/types" machinetypes "planetmint-go/x/machine/types"
"github.com/btcsuite/btcd/btcutil/hdkeychain" "github.com/btcsuite/btcd/btcutil/hdkeychain"
@ -49,15 +50,16 @@ func AccAddress() string {
func Machine(name, pubKey string) machinetypes.Machine { func Machine(name, pubKey string) machinetypes.Machine {
metadata := Metadata() metadata := Metadata()
_, liquidPubKey := LiquidKeyPair() _, liquidPubKey := ExtendedKeyPair(chaincfg.MainNetParams)
_, planetmintPubKey := ExtendedKeyPair(config.PlmntNetParams)
m := machinetypes.Machine{ m := machinetypes.Machine{
Name: name, Name: name,
Ticker: name + "_ticker", Ticker: name + "_ticker",
Domain: "lab.r3c.net", Domain: "lab.r3c.network",
Reissue: true, Reissue: true,
Amount: 1000, Amount: 1000,
Precision: 8, Precision: 8,
IssuerPlanetmint: pubKey, IssuerPlanetmint: planetmintPubKey,
IssuerLiquid: liquidPubKey, IssuerLiquid: liquidPubKey,
MachineId: pubKey, MachineId: pubKey,
Metadata: &metadata, Metadata: &metadata,
@ -65,10 +67,10 @@ func Machine(name, pubKey string) machinetypes.Machine {
return m return m
} }
func MachineIndex(pubKey string, liquidPubKey string) machinetypes.MachineIndex { func MachineIndex(pubKey string, planetmintPubKey string, liquidPubKey string) machinetypes.MachineIndex {
return machinetypes.MachineIndex{ return machinetypes.MachineIndex{
MachineId: pubKey, MachineId: pubKey,
IssuerPlanetmint: pubKey, IssuerPlanetmint: planetmintPubKey,
IssuerLiquid: liquidPubKey, IssuerLiquid: liquidPubKey,
} }
} }
@ -96,10 +98,18 @@ func Asset(sk string) (string, string) {
return cid, signatureHex return cid, signatureHex
} }
func LiquidKeyPair() (string, string) { func ExtendedKeyPair(cfg chaincfg.Params) (string, string) {
// Ignore errors as keypair was tested beforehand seed, err := bip39.NewSeedWithErrorChecking(Mnemonic, keyring.DefaultBIP39Passphrase)
seed, _ := bip39.NewSeedWithErrorChecking(Mnemonic, keyring.DefaultBIP39Passphrase) if err != nil {
xprivKey, _ := hdkeychain.NewMaster(seed, &chaincfg.MainNetParams) panic(err)
xpubKey, _ := xprivKey.Neuter() }
xprivKey, err := hdkeychain.NewMaster(seed, &cfg)
if err != nil {
panic(err)
}
xpubKey, err := xprivKey.Neuter()
if err != nil {
panic(err)
}
return xprivKey.String(), xpubKey.String() return xprivKey.String(), xpubKey.String()
} }

View File

@ -24,7 +24,11 @@ func (k msgServer) isNFTCreationRequest(machine *types.Machine) bool {
func (k msgServer) AttestMachine(goCtx context.Context, msg *types.MsgAttestMachine) (*types.MsgAttestMachineResponse, error) { func (k msgServer) AttestMachine(goCtx context.Context, msg *types.MsgAttestMachine) (*types.MsgAttestMachineResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx) ctx := sdk.UnwrapSDKContext(goCtx)
isValidIssuerLiquid := validateIssuerLiquid(msg.Machine.IssuerLiquid) isValidIssuerPlanetmint := validateExtendedPublicKey(msg.Machine.IssuerPlanetmint, config.PlmntNetParams)
if !isValidIssuerPlanetmint {
return nil, errors.New("invalid planetmint key")
}
isValidIssuerLiquid := validateExtendedPublicKey(msg.Machine.IssuerLiquid, chaincfg.MainNetParams)
if !isValidIssuerLiquid { if !isValidIssuerLiquid {
return nil, errors.New("invalid liquid key") return nil, errors.New("invalid liquid key")
} }
@ -41,13 +45,13 @@ func (k msgServer) AttestMachine(goCtx context.Context, msg *types.MsgAttestMach
return &types.MsgAttestMachineResponse{}, nil return &types.MsgAttestMachineResponse{}, nil
} }
func validateIssuerLiquid(issuerLiquid string) bool { func validateExtendedPublicKey(issuer string, cfg chaincfg.Params) bool {
xpubKeyLiquid, err := hdkeychain.NewKeyFromString(issuerLiquid) xpubKey, err := hdkeychain.NewKeyFromString(issuer)
if err != nil { if err != nil {
return false return false
} }
isValidLiquidKey := xpubKeyLiquid.IsForNet(&chaincfg.MainNetParams) isValidExtendedPublicKey := xpubKey.IsForNet(&cfg)
return isValidLiquidKey return isValidExtendedPublicKey
} }
func (k msgServer) issueMachineNFT(machine *types.Machine) error { func (k msgServer) issueMachineNFT(machine *types.Machine) error {