Browse Source

Remove Ledger ed25519 support, for now

pull/1782/head
Christopher Goes 7 years ago
parent
commit
63aac65590
4 changed files with 0 additions and 266 deletions
  1. +0
    -4
      amino.go
  2. +0
    -156
      ledger_ed25519.go
  3. +0
    -68
      ledger_pub_key.go
  4. +0
    -38
      ledger_test.go

+ 0
- 4
amino.go View File

@ -19,8 +19,6 @@ func RegisterAmino(cdc *amino.Codec) {
cdc.RegisterInterface((*PubKey)(nil), nil)
cdc.RegisterConcrete(PubKeyEd25519{},
"tendermint/PubKeyEd25519", nil)
cdc.RegisterConcrete(PubKeyLedgerEd25519{},
"tendermint/PubKeyLedgerEd25519", nil)
cdc.RegisterConcrete(PubKeySecp256k1{},
"tendermint/PubKeySecp256k1", nil)
@ -31,8 +29,6 @@ func RegisterAmino(cdc *amino.Codec) {
"tendermint/PrivKeySecp256k1", nil)
cdc.RegisterConcrete(PrivKeyLedgerSecp256k1{},
"tendermint/PrivKeyLedgerSecp256k1", nil)
cdc.RegisterConcrete(PrivKeyLedgerEd25519{},
"tendermint/PrivKeyLedgerEd25519", nil)
cdc.RegisterInterface((*Signature)(nil), nil)
cdc.RegisterConcrete(SignatureEd25519{},


+ 0
- 156
ledger_ed25519.go View File

@ -1,156 +0,0 @@
package crypto
import (
"fmt"
"github.com/pkg/errors"
// "github.com/tendermint/ed25519"
ledger "github.com/zondax/ledger-goclient"
)
func pubkeyLedgerEd25519(device *ledger.Ledger, path DerivationPath) (pub PubKey, err error) {
key, err := device.GetPublicKeyED25519(path)
if err != nil {
return pub, fmt.Errorf("Error fetching public key: %v", err)
}
var p PubKeyLedgerEd25519
copy(p[:], key[0:32])
return p, err
}
func signLedgerEd25519(device *ledger.Ledger, path DerivationPath, msg []byte) (sig Signature, err error) {
bsig, err := device.SignED25519(path, msg)
if err != nil {
return sig, err
}
sig = SignatureEd25519FromBytes(bsig)
return sig, nil
}
// PrivKeyLedgerEd25519 implements PrivKey, calling the ledger nano
// we cache the PubKey from the first call to use it later
type PrivKeyLedgerEd25519 struct {
// PubKey should be private, but we want to encode it via go-amino
// so we can view the address later, even without having the ledger
// attached
CachedPubKey PubKey
Path DerivationPath
}
// NewPrivKeyLedgerEd25519 will generate a new key and store the
// public key for later use.
func NewPrivKeyLedgerEd25519(path DerivationPath) (PrivKey, error) {
var pk PrivKeyLedgerEd25519
pk.Path = path
// getPubKey will cache the pubkey for later use,
// this allows us to return an error early if the ledger
// is not plugged in
_, err := pk.getPubKey()
return &pk, err
}
// ValidateKey allows us to verify the sanity of a key
// after loading it from disk
func (pk PrivKeyLedgerEd25519) ValidateKey() error {
// getPubKey will return an error if the ledger is not
// properly set up...
pub, err := pk.forceGetPubKey()
if err != nil {
return err
}
// verify this matches cached address
if !pub.Equals(pk.CachedPubKey) {
return errors.New("Cached key does not match retrieved key")
}
return nil
}
// AssertIsPrivKeyInner fulfils PrivKey Interface
func (pk *PrivKeyLedgerEd25519) AssertIsPrivKeyInner() {}
// Bytes fulfils PrivKey Interface - but it stores the cached pubkey so we can verify
// the same key when we reconnect to a ledger
func (pk PrivKeyLedgerEd25519) Bytes() []byte {
bin, err := cdc.MarshalBinaryBare(pk)
if err != nil {
panic(err)
}
return bin
}
// Sign calls the ledger and stores the PubKey for future use
//
// XXX/TODO: panics if there is an error communicating with the ledger.
//
// Communication is checked on NewPrivKeyLedger and PrivKeyFromBytes,
// returning an error, so this should only trigger if the privkey is held
// in memory for a while before use.
func (pk PrivKeyLedgerEd25519) Sign(msg []byte) Signature {
// oh, I wish there was better error handling
dev, err := getLedger()
if err != nil {
panic(err)
}
sig, err := signLedgerEd25519(dev, pk.Path, msg)
if err != nil {
panic(err)
}
pub, err := pubkeyLedgerEd25519(dev, pk.Path)
if err != nil {
panic(err)
}
// if we have no pubkey yet, store it for future queries
if pk.CachedPubKey == nil {
pk.CachedPubKey = pub
} else if !pk.CachedPubKey.Equals(pub) {
panic("Stored key does not match signing key")
}
return sig
}
// PubKey returns the stored PubKey
// TODO: query the ledger if not there, once it is not volatile
func (pk PrivKeyLedgerEd25519) PubKey() PubKey {
key, err := pk.getPubKey()
if err != nil {
panic(err)
}
return key
}
// getPubKey reads the pubkey from cache or from the ledger itself
// since this involves IO, it may return an error, which is not exposed
// in the PubKey interface, so this function allows better error handling
func (pk PrivKeyLedgerEd25519) getPubKey() (key PubKey, err error) {
// if we have no pubkey, set it
if pk.CachedPubKey == nil {
pk.CachedPubKey, err = pk.forceGetPubKey()
}
return pk.CachedPubKey, err
}
// forceGetPubKey is like getPubKey but ignores any cached key
// and ensures we get it from the ledger itself.
func (pk PrivKeyLedgerEd25519) forceGetPubKey() (key PubKey, err error) {
dev, err := getLedger()
if err != nil {
return key, errors.New(fmt.Sprintf("Cannot connect to Ledger device - error: %v", err))
}
key, err = pubkeyLedgerEd25519(dev, pk.Path)
if err != nil {
return key, errors.New(fmt.Sprintf("Please open Cosmos app on the Ledger device - error: %v", err))
}
return key, err
}
// Equals fulfils PrivKey Interface - makes sure both keys refer to the
// same
func (pk PrivKeyLedgerEd25519) Equals(other PrivKey) bool {
if ledger, ok := other.(*PrivKeyLedgerEd25519); ok {
return pk.CachedPubKey.Equals(ledger.CachedPubKey)
}
return false
}

+ 0
- 68
ledger_pub_key.go View File

@ -1,68 +0,0 @@
package crypto
import (
"bytes"
"crypto/sha512"
"fmt"
"github.com/tendermint/ed25519"
"github.com/tendermint/ed25519/extra25519"
"golang.org/x/crypto/ripemd160"
)
var _ PubKey = PubKeyLedgerEd25519{}
// Implements PubKeyInner
type PubKeyLedgerEd25519 [32]byte
func (pubKey PubKeyLedgerEd25519) Address() Address {
// append type byte
hasher := ripemd160.New()
hasher.Write(pubKey.Bytes()) // does not error
return Address(hasher.Sum(nil))
}
func (pubKey PubKeyLedgerEd25519) Bytes() []byte {
bz, err := cdc.MarshalBinaryBare(pubKey)
if err != nil {
panic(err)
}
return bz
}
func (pubKey PubKeyLedgerEd25519) VerifyBytes(msg []byte, sig_ Signature) bool {
// must verify sha512 hash of msg, no padding, for Ledger compatibility
sig, ok := sig_.(SignatureEd25519)
if !ok {
return false
}
pubKeyBytes := [32]byte(pubKey)
sigBytes := [64]byte(sig)
h := sha512.New()
h.Write(msg)
digest := h.Sum(nil)
return ed25519.Verify(&pubKeyBytes, digest, &sigBytes)
}
// For use with golang/crypto/nacl/box
// If error, returns nil.
func (pubKey PubKeyLedgerEd25519) ToCurve25519() *[32]byte {
keyCurve25519, pubKeyBytes := new([32]byte), [32]byte(pubKey)
ok := extra25519.PublicKeyToCurve25519(keyCurve25519, &pubKeyBytes)
if !ok {
return nil
}
return keyCurve25519
}
func (pubKey PubKeyLedgerEd25519) String() string {
return fmt.Sprintf("PubKeyLedgerEd25519{%X}", pubKey[:])
}
func (pubKey PubKeyLedgerEd25519) Equals(other PubKey) bool {
if otherEd, ok := other.(PubKeyLedgerEd25519); ok {
return bytes.Equal(pubKey[:], otherEd[:])
} else {
return false
}
}

+ 0
- 38
ledger_test.go View File

@ -46,44 +46,6 @@ func TestRealLedgerSecp256k1(t *testing.T) {
assert.Equal(t, pub, bpub)
}
func TestRealLedgerEd25519(t *testing.T) {
if os.Getenv("WITH_LEDGER") == "" {
t.Skip("Set WITH_LEDGER to run code on real ledger")
}
msg := []byte("kuhehfeohg")
path := DerivationPath{44, 60, 0, 0, 0}
priv, err := NewPrivKeyLedgerEd25519(path)
require.Nil(t, err, "%+v", err)
pub := priv.PubKey()
sig := priv.Sign(msg)
valid := pub.VerifyBytes(msg, sig)
assert.True(t, valid)
// now, let's serialize the key and make sure it still works
bs := priv.Bytes()
priv2, err := PrivKeyFromBytes(bs)
require.Nil(t, err, "%+v", err)
// make sure we get the same pubkey when we load from disk
pub2 := priv2.PubKey()
require.Equal(t, pub, pub2)
// signing with the loaded key should match the original pubkey
sig = priv2.Sign(msg)
valid = pub.VerifyBytes(msg, sig)
assert.True(t, valid)
// make sure pubkeys serialize properly as well
bs = pub.Bytes()
bpub, err := PubKeyFromBytes(bs)
require.NoError(t, err)
assert.Equal(t, pub, bpub)
}
// TestRealLedgerErrorHandling calls. These tests assume
// the ledger is not plugged in....
func TestRealLedgerErrorHandling(t *testing.T) {


Loading…
Cancel
Save