Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

keys: define proto type #5997

Closed
wants to merge 52 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
caa7560
crypto/keys: move keybase and keyring to crypto/keyring/ dir
fedekunze Mar 24, 2020
0668da6
Update client/keys/root.go
fedekunze Mar 24, 2020
7b42d88
Update crypto/keyring/errors.go
fedekunze Mar 24, 2020
018b256
Update crypto/keyring/keybase.go
fedekunze Mar 24, 2020
3f4609e
Update crypto/keyring/options.go
fedekunze Mar 24, 2020
9e23f88
format
fedekunze Mar 24, 2020
30e0a38
Merge branch 'fedekunze/5819-move-keys' of https://github.com/cosmos/…
fedekunze Mar 24, 2020
49b6fd4
changelog
fedekunze Mar 24, 2020
715cd36
fix build
fedekunze Mar 24, 2020
c36c9f1
format
fedekunze Mar 24, 2020
2e10608
crypto/keys: move tendermint key types to the SDK
fedekunze Mar 24, 2020
1e96870
crypto/keys: flatten pkgs
fedekunze Mar 25, 2020
49034e9
crypto/keys: cleanup types
fedekunze Mar 25, 2020
5e4724d
revert dep change
fedekunze Mar 25, 2020
7849944
cleanup
fedekunze Mar 25, 2020
e040f03
update proto message for multisig
fedekunze Mar 25, 2020
47032f9
genprivkey functions
fedekunze Mar 25, 2020
411ae36
build errors
fedekunze Mar 25, 2020
0455a2f
add missing methods for secp256k1
fedekunze Mar 25, 2020
239abd5
more fixes
fedekunze Mar 25, 2020
4e7cad3
rebase to master
fedekunze Mar 25, 2020
2ce648f
Merge branch 'master' of https://github.com/cosmos/cosmos-sdk into fe…
fedekunze Mar 26, 2020
c7c9ab8
crypto/keys: add ByteArray util function for each key type
fedekunze Mar 26, 2020
371241f
crypto/keys: fixes from tests
fedekunze Mar 26, 2020
b7c6fcd
tests
fedekunze Mar 26, 2020
dd94902
cast types
tac0turtle Apr 15, 2020
9135567
merge master
fedekunze Apr 15, 2020
6ae127e
Merge branch 'fedekunze/5819-tm-keys' of github.com:cosmos/cosmos-sdk…
fedekunze Apr 15, 2020
92dc996
fix build
tac0turtle Apr 15, 2020
3586202
Merge branch 'marko/pubkeys' of https://github.com/cosmos/cosmos-sdk …
tac0turtle Apr 15, 2020
1960b0f
move PubKey and PrivKey to codec/std/
fedekunze Apr 15, 2020
980ae75
add to/from proto keys
tac0turtle Apr 16, 2020
9a3f012
remove bit array
tac0turtle Apr 16, 2020
fe64a81
bring back multisig
tac0turtle Apr 16, 2020
625ef37
Merge branch 'master' into marko/pubkeys
tac0turtle Apr 16, 2020
9f5b23d
add pubkey threshold to from to pubkeys
tac0turtle Apr 16, 2020
ddcbae3
add marshlers to compactbitarray
tac0turtle Apr 16, 2020
7015bdf
appease linter
tac0turtle Apr 16, 2020
e49b200
format according to guidelines
tac0turtle Apr 16, 2020
c5dd830
Apply suggestions from code review
tac0turtle Apr 16, 2020
3769492
Merge branch 'master' into marko/pubkeys
fedekunze Apr 16, 2020
c75f2b2
Merge branch 'master' into marko/pubkeys
fedekunze Apr 18, 2020
c47a74c
Merge branch 'master' into marko/pubkeys
tac0turtle Apr 20, 2020
34f5af2
migrate multisig to sdk
tac0turtle Apr 20, 2020
c2b3dc0
move bitarray to types
tac0turtle Apr 20, 2020
ea2afd8
move it up on dir
tac0turtle Apr 20, 2020
1f1d07d
Merge branch 'master' into marko/pubkeys
fedekunze Apr 20, 2020
e0b1ce1
fix pubkey tests
tac0turtle Apr 21, 2020
a15dfd7
Merge branch 'master' into marko/pubkeys
fedekunze Apr 21, 2020
855e976
Merge branch 'master' into marko/pubkeys
fedekunze Apr 21, 2020
94efb32
Merge branch 'master' into marko/pubkeys
Apr 21, 2020
6e1bdd6
Merge branch 'master' into marko/pubkeys
tac0turtle Apr 22, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
add missing methods for secp256k1
  • Loading branch information
fedekunze committed Mar 25, 2020
commit 0455a2faa937d54d2e4e10adba11ae565a6c9127
14 changes: 10 additions & 4 deletions crypto/keys/multisig.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,19 +71,25 @@ var _ crypto.PubKey = PubKeyMultisigThreshold{}

// NewPubKeyMultisigThreshold returns a new PubKeyMultisigThreshold.
// Panics if len(pubkeys) < k or 0 >= k.
func NewPubKeyMultisigThreshold(k int32, pubkeys []*crypto.PubKey) crypto.PubKey {
func NewPubKeyMultisigThreshold(k int32, pubkeys []crypto.PubKey) crypto.PubKey {
if k <= 0 {
panic("threshold k of n multisignature: k <= 0")
}
if len(pubkeys) < int(k) {
panic("threshold k of n multisignature: len(pubkeys) < k")
}
for _, pubkey := range pubkeys {

pks := make([]*PubKey, len(pubkeys))
for i, pubkey := range pubkeys {
if pubkey == nil {
panic("nil pubkey")
panic(fmt.Errorf("pubkey at index %d cannot be nil", i))
}
if err := pks[i].SetPubKey(pubkey); err != nil {
panic(fmt.Errorf("couldn't set pubkey at index %d: %w", i, err))
}
}
return PubKeyMultisigThreshold{K: uint32(k), PubKeys: pubkeys}

return PubKeyMultisigThreshold{K: uint32(k), PubKeys: pks}
}

// VerifyBytes expects sig to be an amino encoded version of a MultiSignature.
Expand Down
97 changes: 89 additions & 8 deletions crypto/keys/secp256k1.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ import (
"crypto/sha256"
"crypto/subtle"
"fmt"
"math/big"

secp256k1 "github.com/btcsuite/btcd/btcec"
"github.com/btcsuite/btcd/btcec"
"github.com/ethereum/go-ethereum/crypto/secp256k1"
"golang.org/x/crypto/ripemd160" // nolint: staticcheck // necessary for Bitcoin address format

"github.com/tendermint/tendermint/crypto"
Expand All @@ -30,6 +32,12 @@ const (
PrivKeySecp256k1Size = 32
)

// used to reject malleable signatures
// see:
// - https://github.com/ethereum/go-ethereum/blob/f9401ae011ddf7f8d2d95020b7446c17f8d98dc1/crypto/signature_nocgo.go#L90-L93
// - https://github.com/ethereum/go-ethereum/blob/f9401ae011ddf7f8d2d95020b7446c17f8d98dc1/crypto/crypto.go#L39
var secp256k1halfN = new(big.Int).Rsh(btcec.S256().N, 1)

// Address returns a Bitcoin style addresses: RIPEMD160(SHA256(pubkey))
func (pubKey PubKeySecp256K1) Address() crypto.Address {
hasherSHA256 := sha256.New()
Expand Down Expand Up @@ -61,10 +69,43 @@ func (pubKey PubKeySecp256K1) String() string {
}

func (pubKey PubKeySecp256K1) Equals(other crypto.PubKey) bool {
if otherSecp, ok := other.(PubKeySecp256K1); ok {
return bytes.Equal(pubKey.bytes, otherSecp.bytes)
otherSecp, ok := other.(PubKeySecp256K1)
if !ok {
return false
}
return bytes.Equal(pubKey.bytes, otherSecp.bytes)
}

// Sign creates an ECDSA signature on curve Secp256k1, using SHA256 on the msg.
// The returned signature will be of the form R || S (in lower-S form).
func (privKey PubKeySecp256K1) Sign(msg []byte) ([]byte, error) {
priv, _ := btcec.PrivKeyFromBytes(btcec.S256(), privKey.Bytes())
sig, err := priv.Sign(crypto.Sha256(msg))
if err != nil {
return nil, err
}
sigBytes := serializeSig(sig)
return sigBytes, nil
}

// VerifyBytes verifies a signature of the form R || S.
// It rejects signatures which are not in lower-S form.
func (pubKey PubKeySecp256K1) VerifyBytes(msg []byte, sigStr []byte) bool {
if len(sigStr) != 64 {
return false
}
pub, err := btcec.ParsePubKey(pubKey.Bytes(), btcec.S256())
if err != nil {
return false
}
// parse the signature:
signature := signatureFromBytes(sigStr)
// Reject malleable signatures. libsecp256k1 does this check but btcec doesn't.
// see: https://github.com/ethereum/go-ethereum/blob/f9401ae011ddf7f8d2d95020b7446c17f8d98dc1/crypto/signature_nocgo.go#L90-L93
if signature.S.Cmp(secp256k1halfN) > 0 {
return false
}
return false
return signature.Verify(crypto.Sha256(msg), pub)
}

//-------------------------------------
Expand All @@ -80,7 +121,7 @@ func (privKey PrivKeySecp256K1) Bytes() []byte {
// PubKey performs the point-scalar multiplication from the privKey on the
// generator point to get the pubkey.
func (privKey PrivKeySecp256K1) PubKey() crypto.PubKey {
_, pubkeyObject := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKey.Bytes()[:])
_, pubkeyObject := btcec.PrivKeyFromBytes(secp256k1.S256(), privKey.Bytes()[:])
var pubkeyBytes []byte
copy(pubkeyBytes, pubkeyObject.SerializeCompressed())
return PubKeySecp256K1{bytes: pubkeyBytes}
Expand All @@ -89,8 +130,48 @@ func (privKey PrivKeySecp256K1) PubKey() crypto.PubKey {
// Equals - you probably don't need to use this.
// Runs in constant time based on length of the keys.
func (privKey PrivKeySecp256K1) Equals(other crypto.PrivKey) bool {
if otherSecp, ok := other.(PrivKeySecp256K1); ok {
return subtle.ConstantTimeCompare(privKey.bytes, otherSecp.bytes) == 1
otherSecp, ok := other.(PrivKeySecp256K1)
if !ok {
return false
}
return false
return subtle.ConstantTimeCompare(privKey.bytes, otherSecp.bytes) == 1
}

// Sign creates an ECDSA signature on curve Secp256k1, using SHA256 on the msg.
func (privKey PrivKeySecp256K1) Sign(msg []byte) ([]byte, error) {
rsv, err := secp256k1.Sign(crypto.Sha256(msg), privKey.Bytes())
if err != nil {
return nil, err
}
// we do not need v in r||s||v:
rs := rsv[:len(rsv)-1]
return rs, nil
}

func (pubKey PrivKeySecp256K1) VerifyBytes(msg []byte, sig []byte) bool {
return secp256k1.VerifySignature(pubKey.Bytes(), crypto.Sha256(msg), sig)
}

//-------------------------------------
// utils

// Read signature struct from R || S.
// CONTRACT: Caller needs to ensure that len(sigStr) == 64.
func signatureFromBytes(sigStr []byte) *btcec.Signature {
return &btcec.Signature{
R: new(big.Int).SetBytes(sigStr[:32]),
S: new(big.Int).SetBytes(sigStr[32:64]),
}
}

// Serialize signature to R || S.
// R, S are padded to 32 bytes respectively.
func serializeSig(sig *btcec.Signature) []byte {
rBytes := sig.R.Bytes()
sBytes := sig.S.Bytes()
sigBytes := make([]byte, 64)
// 0 pad the byte arrays from the left if they aren't big enough.
copy(sigBytes[32-len(rBytes):32], rBytes)
copy(sigBytes[64-len(sBytes):64], sBytes)
return sigBytes
}
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ require (
github.com/btcsuite/btcutil v0.0.0-20180706230648-ab6388e0c60a
github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d
github.com/cosmos/ledger-cosmos-go v0.11.1
github.com/ethereum/go-ethereum v1.9.12
github.com/gibson042/canonicaljson-go v1.0.3
github.com/gogo/protobuf v1.3.1
github.com/golang/mock v1.4.3
Expand All @@ -33,7 +34,7 @@ require (
github.com/tendermint/iavl v0.13.2
github.com/tendermint/tendermint v0.33.2
github.com/tendermint/tm-db v0.5.0
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413
golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4
google.golang.org/protobuf v1.20.1 // indirect
gopkg.in/yaml.v2 v2.2.8
)
Expand Down
Loading