Skip to content

Commit

Permalink
Merge pull request #46 from libp2p/feat/cherry-pick-stabalize
Browse files Browse the repository at this point in the history
cherry-pick key optimizations from stabilize
  • Loading branch information
Stebalien authored Aug 2, 2019
2 parents 8dda665 + 9e14101 commit b7e4f2f
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 22 deletions.
4 changes: 2 additions & 2 deletions core/crypto/ecdsa.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ func (ePriv *ECDSAPrivateKey) Raw() ([]byte, error) {
func (ePriv *ECDSAPrivateKey) Equals(o Key) bool {
oPriv, ok := o.(*ECDSAPrivateKey)
if !ok {
return false
return basicEquals(ePriv, o)
}

return ePriv.priv.D.Cmp(oPriv.priv.D) == 0
Expand Down Expand Up @@ -163,7 +163,7 @@ func (ePub ECDSAPublicKey) Raw() ([]byte, error) {
func (ePub *ECDSAPublicKey) Equals(o Key) bool {
oPub, ok := o.(*ECDSAPublicKey)
if !ok {
return false
return basicEquals(ePub, o)
}

return ePub.pub.X != nil && ePub.pub.Y != nil && oPub.pub.X != nil && oPub.pub.Y != nil &&
Expand Down
20 changes: 17 additions & 3 deletions core/crypto/key.go
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,21 @@ func KeyEqual(k1, k2 Key) bool {
return true
}

b1, err1 := k1.Bytes()
b2, err2 := k2.Bytes()
return subtle.ConstantTimeCompare(b1, b2) == 1 && err1 == err2
return k1.Equals(k2)
}

func basicEquals(k1, k2 Key) bool {
if k1.Type() != k2.Type() {
return false
}

a, err := k1.Raw()
if err != nil {
return false
}
b, err := k2.Raw()
if err != nil {
return false
}
return subtle.ConstantTimeCompare(a, b) == 1
}
30 changes: 22 additions & 8 deletions core/crypto/key_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,18 +101,19 @@ func testKeyEncoding(t *testing.T, sk PrivKey) {
}

func testKeyEquals(t *testing.T, k Key) {
kb, err := k.Bytes()
if err != nil {
t.Fatal(err)
}
// kb, err := k.Raw()
// if err != nil {
// t.Fatal(err)
// }

if !KeyEqual(k, k) {
t.Fatal("Key not equal to itself.")
}

if !KeyEqual(k, testkey(kb)) {
t.Fatal("Key not equal to key with same bytes.")
}
// bad test, relies on deep internals..
// if !KeyEqual(k, testkey(kb)) {
// t.Fatal("Key not equal to key with same bytes.")
// }

sk, pk, err := test.RandTestKeyPair(RSA, 512)
if err != nil {
Expand Down Expand Up @@ -143,7 +144,20 @@ func (pk testkey) Raw() ([]byte, error) {
}

func (pk testkey) Equals(k Key) bool {
return KeyEqual(pk, k)
if pk.Type() != k.Type() {
return false
}
a, err := pk.Raw()
if err != nil {
return false
}

b, err := k.Raw()
if err != nil {
return false
}

return bytes.Equal(a, b)
}

func TestUnknownCurveErrors(t *testing.T) {
Expand Down
16 changes: 13 additions & 3 deletions core/crypto/openssl_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ package crypto
import (
pb "github.com/libp2p/go-libp2p-core/crypto/pb"

openssl "github.com/spacemonkeygo/openssl"
openssl "github.com/libp2p/go-openssl"
)

// define these as separate types so we can add more key types later and reuse
Expand Down Expand Up @@ -61,7 +61,12 @@ func (pk *opensslPublicKey) Raw() ([]byte, error) {

// Equals checks whether this key is equal to another
func (pk *opensslPublicKey) Equals(k Key) bool {
return KeyEqual(pk, k)
k0, ok := k.(*RsaPublicKey)
if !ok {
return basicEquals(pk, k)
}

return pk.key.Equal(k0.opensslPublicKey.key)
}

// Sign returns a signature of the input data
Expand Down Expand Up @@ -94,5 +99,10 @@ func (sk *opensslPrivateKey) Raw() ([]byte, error) {

// Equals checks whether this key is equal to another
func (sk *opensslPrivateKey) Equals(k Key) bool {
return KeyEqual(sk, k)
k0, ok := k.(*RsaPrivateKey)
if !ok {
return basicEquals(sk, k)
}

return sk.key.Equal(k0.opensslPrivateKey.key)
}
20 changes: 18 additions & 2 deletions core/crypto/rsa_go.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,13 @@ func (pk *RsaPublicKey) Raw() ([]byte, error) {

// Equals checks whether this key is equal to another
func (pk *RsaPublicKey) Equals(k Key) bool {
return KeyEqual(pk, k)
// make sure this is an rsa public key
other, ok := (k).(*RsaPublicKey)
if !ok {
return basicEquals(pk, k)
}

return pk.k.N.Cmp(other.k.N) == 0 && pk.k.E == other.k.E
}

// Sign returns a signature of the input data
Expand Down Expand Up @@ -93,7 +99,17 @@ func (sk *RsaPrivateKey) Raw() ([]byte, error) {

// Equals checks whether this key is equal to another
func (sk *RsaPrivateKey) Equals(k Key) bool {
return KeyEqual(sk, k)
// make sure this is an rsa public key
other, ok := (k).(*RsaPrivateKey)
if !ok {
return basicEquals(sk, k)
}

a := sk.sk
b := other.sk

// Don't care about constant time. We're only comparing the public half.
return a.PublicKey.N.Cmp(b.PublicKey.N) == 0 && a.PublicKey.E == b.PublicKey.E
}

// UnmarshalRsaPrivateKey returns a private key from the input x509 bytes
Expand Down
2 changes: 1 addition & 1 deletion core/crypto/rsa_openssl.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"errors"
"io"

openssl "github.com/spacemonkeygo/openssl"
openssl "github.com/libp2p/go-openssl"
)

// RsaPrivateKey is an rsa private key
Expand Down
6 changes: 3 additions & 3 deletions core/crypto/secp256k1.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ func (k *Secp256k1PrivateKey) Raw() ([]byte, error) {
func (k *Secp256k1PrivateKey) Equals(o Key) bool {
sk, ok := o.(*Secp256k1PrivateKey)
if !ok {
return false
return basicEquals(k, o)
}

return k.D.Cmp(sk.D) == 0
return k.GetPublic().Equals(sk.GetPublic())
}

// Sign returns a signature from input data
Expand Down Expand Up @@ -107,7 +107,7 @@ func (k *Secp256k1PublicKey) Raw() ([]byte, error) {
func (k *Secp256k1PublicKey) Equals(o Key) bool {
sk, ok := o.(*Secp256k1PublicKey)
if !ok {
return false
return basicEquals(k, o)
}

return (*btcec.PublicKey)(k).IsEqual((*btcec.PublicKey)(sk))
Expand Down

0 comments on commit b7e4f2f

Please sign in to comment.