Skip to content

Commit 0a5b1d9

Browse files
authored
Merge pull request cosmos#37 from tendermint/nano
Nano Support
2 parents a6e6b58 + 0219ba2 commit 0a5b1d9

23 files changed

+1064
-591
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ REPO:=github.com/tendermint/go-crypto
1010
all: get_vendor_deps metalinter_test test
1111

1212
test:
13-
go test `glide novendor`
13+
go test -p 1 `glide novendor`
1414

1515
get_vendor_deps: ensure_tools
1616
@rm -rf vendor/

glide.lock

Lines changed: 14 additions & 16 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

glide.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import:
3030
- package: github.com/spf13/viper
3131
- package: gopkg.in/go-playground/validator.v9
3232
- package: github.com/howeyc/crc16
33+
- package: github.com/ethanfrey/ledger
3334
testImport:
3435
- package: github.com/mndrix/btcutil
3536
- package: github.com/stretchr/testify

keys/cryptostore/encoder.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ func (e secretbox) Decrypt(saltBytes []byte, encBytes []byte, passphrase string)
4343
privKeyBytes := encBytes
4444
// NOTE: Some keys weren't encrypted with a passphrase and hence we have the conditional
4545
if passphrase != "" {
46-
key, err := bcrypt.GenerateFromPassword(saltBytes, []byte(passphrase), 14) // TODO parameterize. 14 is good today (2016)
46+
var key []byte
47+
key, err = bcrypt.GenerateFromPassword(saltBytes, []byte(passphrase), 14) // TODO parameterize. 14 is good today (2016)
4748
if err != nil {
4849
return crypto.PrivKey{}, errors.Wrap(err, "Invalid Passphrase")
4950
}
@@ -55,7 +56,7 @@ func (e secretbox) Decrypt(saltBytes []byte, encBytes []byte, passphrase string)
5556
}
5657
privKey, err = crypto.PrivKeyFromBytes(privKeyBytes)
5758
if err != nil {
58-
return crypto.PrivKey{}, errors.Wrap(err, "Couldn't get privKey from bytes")
59+
return crypto.PrivKey{}, errors.Wrap(err, "Private Key")
5960
}
6061
return privKey, nil
6162
}

keys/cryptostore/encoder_test.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@ func TestNoopEncoder(t *testing.T) {
1515
assert, require := assert.New(t), require.New(t)
1616
noop := cryptostore.Noop
1717

18-
key := cryptostore.GenEd25519.Generate(cmn.RandBytes(16))
19-
key2 := cryptostore.GenSecp256k1.Generate(cmn.RandBytes(16))
18+
key, err := cryptostore.GenEd25519.Generate(cmn.RandBytes(16))
19+
require.NoError(err)
20+
key2, err := cryptostore.GenSecp256k1.Generate(cmn.RandBytes(16))
21+
require.NoError(err)
2022

2123
_, b, err := noop.Encrypt(key, "encode")
2224
require.Nil(err)
@@ -43,7 +45,8 @@ func TestSecretBox(t *testing.T) {
4345
assert, require := assert.New(t), require.New(t)
4446
enc := cryptostore.SecretBox
4547

46-
key := cryptostore.GenEd25519.Generate(cmn.RandBytes(16))
48+
key, err := cryptostore.GenEd25519.Generate(cmn.RandBytes(16))
49+
require.NoError(err)
4750
pass := "some-special-secret"
4851

4952
s, b, err := enc.Encrypt(key, pass)
@@ -65,7 +68,8 @@ func TestSecretBoxNoPass(t *testing.T) {
6568
assert, require := assert.New(t), require.New(t)
6669
enc := cryptostore.SecretBox
6770

68-
key := cryptostore.GenEd25519.Generate(cmn.RandBytes(16))
71+
key, rerr := cryptostore.GenEd25519.Generate(cmn.RandBytes(16))
72+
require.NoError(rerr)
6973

7074
cases := []struct {
7175
encode string
@@ -95,7 +99,7 @@ func TestSecretBoxNoPass(t *testing.T) {
9599

96100
// now let's make sure raw bytes also work...
97101
b := key.Bytes()
98-
pk, err := enc.Decrypt(nil, b, "")
99-
require.Nil(err, "%+v", err)
102+
pk, rerr := enc.Decrypt(nil, b, "")
103+
require.NoError(rerr)
100104
assert.Equal(key, pk)
101105
}

keys/cryptostore/generator.go

Lines changed: 48 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,53 +4,86 @@ import (
44
"github.com/pkg/errors"
55

66
crypto "github.com/tendermint/go-crypto"
7+
"github.com/tendermint/go-crypto/nano"
78
)
89

910
var (
1011
// GenEd25519 produces Ed25519 private keys
1112
GenEd25519 Generator = GenFunc(genEd25519)
1213
// GenSecp256k1 produces Secp256k1 private keys
1314
GenSecp256k1 Generator = GenFunc(genSecp256)
15+
// GenLedgerEd25519 used Ed25519 keys stored on nano ledger s with cosmos app
16+
GenLedgerEd25519 Generator = GenFunc(genLedgerEd25519)
1417
)
1518

1619
// Generator determines the type of private key the keystore creates
1720
type Generator interface {
18-
Generate(secret []byte) crypto.PrivKey
21+
Generate(secret []byte) (crypto.PrivKey, error)
1922
}
2023

2124
// GenFunc is a helper to transform a function into a Generator
22-
type GenFunc func(secret []byte) crypto.PrivKey
25+
type GenFunc func(secret []byte) (crypto.PrivKey, error)
2326

24-
func (f GenFunc) Generate(secret []byte) crypto.PrivKey {
27+
func (f GenFunc) Generate(secret []byte) (crypto.PrivKey, error) {
2528
return f(secret)
2629
}
2730

28-
func genEd25519(secret []byte) crypto.PrivKey {
29-
return crypto.GenPrivKeyEd25519FromSecret(secret).Wrap()
31+
func genEd25519(secret []byte) (crypto.PrivKey, error) {
32+
key := crypto.GenPrivKeyEd25519FromSecret(secret).Wrap()
33+
return key, nil
3034
}
3135

32-
func genSecp256(secret []byte) crypto.PrivKey {
33-
return crypto.GenPrivKeySecp256k1FromSecret(secret).Wrap()
36+
func genSecp256(secret []byte) (crypto.PrivKey, error) {
37+
key := crypto.GenPrivKeySecp256k1FromSecret(secret).Wrap()
38+
return key, nil
3439
}
3540

36-
func getGenerator(algo string) (Generator, error) {
41+
// secret is completely ignored for the ledger...
42+
// just for interface compatibility
43+
func genLedgerEd25519(secret []byte) (crypto.PrivKey, error) {
44+
return nano.NewPrivKeyLedgerEd25519Ed25519()
45+
}
46+
47+
type genInvalidByte struct {
48+
typ byte
49+
}
50+
51+
func (g genInvalidByte) Generate(secret []byte) (crypto.PrivKey, error) {
52+
err := errors.Errorf("Cannot generate keys for algorithm: %X", g.typ)
53+
return crypto.PrivKey{}, err
54+
}
55+
56+
type genInvalidAlgo struct {
57+
algo string
58+
}
59+
60+
func (g genInvalidAlgo) Generate(secret []byte) (crypto.PrivKey, error) {
61+
err := errors.Errorf("Cannot generate keys for algorithm: %s", g.algo)
62+
return crypto.PrivKey{}, err
63+
}
64+
65+
func getGenerator(algo string) Generator {
3766
switch algo {
3867
case crypto.NameEd25519:
39-
return GenEd25519, nil
68+
return GenEd25519
4069
case crypto.NameSecp256k1:
41-
return GenSecp256k1, nil
70+
return GenSecp256k1
71+
case nano.NameLedgerEd25519:
72+
return GenLedgerEd25519
4273
default:
43-
return nil, errors.Errorf("Cannot generate keys for algorithm: %s", algo)
74+
return genInvalidAlgo{algo}
4475
}
4576
}
4677

47-
func getGeneratorByType(typ byte) (Generator, error) {
78+
func getGeneratorByType(typ byte) Generator {
4879
switch typ {
4980
case crypto.TypeEd25519:
50-
return GenEd25519, nil
81+
return GenEd25519
5182
case crypto.TypeSecp256k1:
52-
return GenSecp256k1, nil
83+
return GenSecp256k1
84+
case nano.TypeLedgerEd25519:
85+
return GenLedgerEd25519
5386
default:
54-
return nil, errors.Errorf("Cannot generate keys for algorithm: %X", typ)
87+
return genInvalidByte{typ}
5588
}
5689
}

keys/cryptostore/holder.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,15 @@ var _ keys.Manager = Manager{}
3333
//
3434
// algo must be a supported go-crypto algorithm: ed25519, secp256k1
3535
func (s Manager) Create(name, passphrase, algo string) (keys.Info, string, error) {
36-
gen, err := getGenerator(algo)
36+
// 128-bits are the all the randomness we can make use of
37+
secret := crypto.CRandBytes(16)
38+
gen := getGenerator(algo)
39+
40+
key, err := gen.Generate(secret)
3741
if err != nil {
3842
return keys.Info{}, "", err
3943
}
4044

41-
// 128-bits are the all the randomness we can make use of
42-
secret := crypto.CRandBytes(16)
43-
key := gen.Generate(secret)
4445
err = s.es.Put(name, passphrase, key)
4546
if err != nil {
4647
return keys.Info{}, "", err
@@ -74,11 +75,11 @@ func (s Manager) Recover(name, passphrase, seedphrase string) (keys.Info, error)
7475
l := len(secret)
7576
secret, typ := secret[:l-1], secret[l-1]
7677

77-
gen, err := getGeneratorByType(typ)
78+
gen := getGeneratorByType(typ)
79+
key, err := gen.Generate(secret)
7880
if err != nil {
7981
return keys.Info{}, err
8082
}
81-
key := gen.Generate(secret)
8283

8384
// d00d, it worked! create the bugger....
8485
err = s.es.Put(name, passphrase, key)

0 commit comments

Comments
 (0)