Skip to content

Commit

Permalink
feat: add key dedicated to vrf
Browse files Browse the repository at this point in the history
  • Loading branch information
hacheigriega committed Dec 14, 2023
1 parent 95aaf29 commit dcc8235
Show file tree
Hide file tree
Showing 5 changed files with 216 additions and 91 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ scripts/testnet/artifacts
# Ignore the env file one may actually fill out
seda.env
.env
.netrc

# coverage files
coverage.txt
7 changes: 7 additions & 0 deletions DEVELOPING.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,13 @@ machine github.com
password <YOUR_GITHUB_TOKEN>
```

The e2e testing can now be run with the following command:
```bash
machine github.com
login <YOUR_USERNAME>
password <YOUR_GITHUB_TOKEN>
```

Change the permissions of `.netrc` and run e2e with the following commands:
```bash
chmod 600 .netrc
Expand Down
11 changes: 9 additions & 2 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ import (
ibckeeper "github.com/cosmos/ibc-go/v8/modules/core/keeper"

appparams "github.com/sedaprotocol/seda-chain/app/params"
"github.com/sedaprotocol/seda-chain/cmd/seda-chaind/utils"
"github.com/sedaprotocol/seda-chain/docs"
randomness "github.com/sedaprotocol/seda-chain/x/randomness"
"github.com/sedaprotocol/seda-chain/x/randomness/keeper"
Expand Down Expand Up @@ -866,11 +867,17 @@ func NewApp(
app.SetEndBlocker(app.EndBlocker)

// Pseudorandomness beacon
// homePath,
// cast.ToString(appOpts.Get("priv_validator_key_file")),
vrfKey, err := utils.LoadOrGenVRFKey("~/.seda-chain/config/vrf_key.json")
if err != nil {
panic(fmt.Errorf("failed to load of generate VRF key: %w", err))
}

app.SetPrepareProposal(
randomnesskeeper.PrepareProposalHandler(
txConfig,
homePath,
cast.ToString(appOpts.Get("priv_validator_key_file")),
vrfKey,
app.RandomnessKeeper,
app.AccountKeeper,
app.StakingKeeper,
Expand Down
172 changes: 172 additions & 0 deletions cmd/seda-chaind/utils/keys.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
package utils

import (
"context"
"fmt"
"os"

"github.com/cometbft/cometbft/crypto"
"github.com/cometbft/cometbft/crypto/secp256k1"
cmtjson "github.com/cometbft/cometbft/libs/json"
cmtos "github.com/cometbft/cometbft/libs/os"
"github.com/cometbft/cometbft/types"

"github.com/cosmos/cosmos-sdk/client"
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
sdkcrypto "github.com/cosmos/cosmos-sdk/crypto/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/tx/signing"
txsigning "github.com/cosmos/cosmos-sdk/types/tx/signing"
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"

vrf "github.com/sedaprotocol/vrf-go"
)

var _ VRFSigner = &VRFKey{}

type VRFSigner interface {
VRFProve(alpha []byte) (pi, beta []byte, err error)
SignTransaction(ctx sdk.Context,
signMode signing.SignMode,
txBuilder client.TxBuilder, txConfig client.TxConfig, account sdk.AccountI) (signing.SignatureV2, error)
}

type VRFKey struct {
Address types.Address `json:"address"`
PubKey sdkcrypto.PubKey `json:"pub_key"`
PrivKey crypto.PrivKey `json:"priv_key"` // TO-DO can we not export it?

filePath string
vrf *vrf.VRFStruct
}

// Save persists the VRFKey to its filePath.
func (key VRFKey) Save() error {
outFile := key.filePath
if outFile == "" {
return fmt.Errorf("key's file path is empty")
}

jsonBytes, err := cmtjson.MarshalIndent(key, "", " ")
if err != nil {
return fmt.Errorf("failed to marshal key: %v", err)
}

err = os.WriteFile(outFile, jsonBytes, 0o600)
if err != nil {
return fmt.Errorf("failed to write key file: %v", err)
}
return nil
}

func (v *VRFKey) VRFProve(alpha []byte) (pi, beta []byte, err error) {
pi, err = v.vrf.Prove(v.PrivKey.Bytes(), alpha)
if err != nil {
return nil, nil, err
}
beta, err = v.vrf.ProofToHash(pi)
if err != nil {
return nil, nil, err
}
return pi, beta, nil
}

func (v *VRFKey) SignTransaction(
ctx sdk.Context,
signMode signing.SignMode,
txBuilder client.TxBuilder, txConfig client.TxConfig, account sdk.AccountI,
) (signing.SignatureV2, error) {
var sigV2 signing.SignatureV2

signerData := authsigning.SignerData{
ChainID: ctx.ChainID(),
AccountNumber: account.GetAccountNumber(),
Sequence: account.GetSequence(),
PubKey: v.PubKey,
Address: account.GetAddress().String(),
}

bytesToSign, err := authsigning.GetSignBytesAdapter(
context.Background(),
txConfig.SignModeHandler(),
signMode,
signerData,
txBuilder.GetTx(),
)
if err != nil {
return sigV2, err
}

sigBytes, err := v.PrivKey.Sign(bytesToSign)
if err != nil {
return sigV2, err
}

sigV2 = signing.SignatureV2{
PubKey: v.PubKey,
Data: &txsigning.SingleSignatureData{
SignMode: signMode,
Signature: sigBytes,
},
Sequence: account.GetSequence(),
}

return sigV2, nil
}

// NewVRFKey generates a new VRFKey from the given key and key file path.
func NewVRFKey(privKey crypto.PrivKey, keyFilePath string) (*VRFKey, error) {
vrfStruct := vrf.NewK256VRF(0xFE)

Check failure on line 119 in cmd/seda-chaind/utils/keys.go

View workflow job for this annotation

GitHub Actions / sedad darwin-amd64

too many arguments in call to vrf.NewK256VRF

Check failure on line 119 in cmd/seda-chaind/utils/keys.go

View workflow job for this annotation

GitHub Actions / tests

too many arguments in call to vrf.NewK256VRF

Check failure on line 119 in cmd/seda-chaind/utils/keys.go

View workflow job for this annotation

GitHub Actions / sedad linux-amd64

too many arguments in call to vrf.NewK256VRF
pubKey, err := cryptocodec.FromCmtPubKeyInterface(privKey.PubKey())
if err != nil {
return nil, err
}
return &VRFKey{
Address: privKey.PubKey().Address(),
PubKey: pubKey,
PrivKey: privKey,
filePath: keyFilePath,
vrf: &vrfStruct,
}, nil
}

// GenVRFKey generates a new VRFKey with a randomly generated private key.
func GenVRFKey(keyFilePath string) (*VRFKey, error) {
return NewVRFKey(secp256k1.GenPrivKey(), keyFilePath)
}

func LoadVRFKey(keyFilePath string) (*VRFKey, error) {
keyJSONBytes, err := os.ReadFile(keyFilePath)
if err != nil {
return nil, fmt.Errorf("error reading VRF key from %v: %v", keyFilePath, err)
}
vrfKey := new(VRFKey)
err = cmtjson.Unmarshal(keyJSONBytes, vrfKey)
if err != nil {
return nil, fmt.Errorf("error unmarshalling VRF key from %v: %v", keyFilePath, err)
}
return vrfKey, nil
}

// LoadOrGenVRFKey loads a VRFKey from the given file path
// or else generates a new one and saves it to the file path.
func LoadOrGenVRFKey(keyFilePath string) (*VRFKey, error) {
var vrfKey *VRFKey
var err error
if cmtos.FileExists(keyFilePath) {
vrfKey, err = LoadVRFKey(keyFilePath)
if err != nil {
return nil, err
}
} else {
vrfKey, err = GenVRFKey(keyFilePath)
if err != nil {
return nil, err
}
err = vrfKey.Save()
if err != nil {
return nil, err
}
}
return vrfKey, nil
}
Loading

0 comments on commit dcc8235

Please sign in to comment.