From ddb6d72b5ad0ae81bf1ee77b628eac1d7237536a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Thu, 23 May 2019 17:47:43 +0100 Subject: [PATCH] Consolidate abstractions and core types into go-libp2p-core (#60) --- .gitattributes | 1 - bench_test.go | 84 ------ ecdsa.go | 186 ------------ ecdsa_deprecated.go | 64 ++++ ecdsa_test.go | 96 ------ ed25519.go | 155 ---------- ed25519_deprecated.go | 28 ++ ed25519_test.go | 220 -------------- fixture_test.go | 132 --------- go.mod | 8 +- go.sum | 24 ++ key.go | 352 ---------------------- key_deprecated.go | 108 +++++++ key_test.go | 147 --------- openssl_common.go | 98 ------ pb/Makefile | 11 - pb/crypto.pb.go | 643 ---------------------------------------- pb/crypto.proto | 20 -- pb/deprecated.go | 37 +++ rsa_common.go | 10 - rsa_deprecated.go | 31 ++ rsa_go.go | 125 -------- rsa_openssl.go | 62 ---- rsa_test.go | 102 ------- secp256k1.go | 125 -------- secp256k1_deprecated.go | 28 ++ secp256k1_test.go | 96 ------ test/deprecated.go | 17 ++ test/utils.go | 17 -- test_data/0.priv | Bin 1198 -> 0 bytes test_data/0.pub | Bin 299 -> 0 bytes test_data/0.sig | Bin 256 -> 0 bytes test_data/2.priv | 1 - test_data/2.pub | 1 - test_data/2.sig | 1 - test_data/3.priv | Bin 125 -> 0 bytes test_data/3.pub | Bin 95 -> 0 bytes test_data/3.sig | Bin 72 -> 0 bytes 38 files changed, 338 insertions(+), 2692 deletions(-) delete mode 100644 .gitattributes delete mode 100644 bench_test.go delete mode 100644 ecdsa.go create mode 100644 ecdsa_deprecated.go delete mode 100644 ecdsa_test.go delete mode 100644 ed25519.go create mode 100644 ed25519_deprecated.go delete mode 100644 ed25519_test.go delete mode 100644 fixture_test.go delete mode 100644 key.go create mode 100644 key_deprecated.go delete mode 100644 key_test.go delete mode 100644 openssl_common.go delete mode 100644 pb/Makefile delete mode 100644 pb/crypto.pb.go delete mode 100644 pb/crypto.proto create mode 100644 pb/deprecated.go delete mode 100644 rsa_common.go create mode 100644 rsa_deprecated.go delete mode 100644 rsa_go.go delete mode 100644 rsa_openssl.go delete mode 100644 rsa_test.go delete mode 100644 secp256k1.go create mode 100644 secp256k1_deprecated.go delete mode 100644 secp256k1_test.go create mode 100644 test/deprecated.go delete mode 100644 test/utils.go delete mode 100644 test_data/0.priv delete mode 100644 test_data/0.pub delete mode 100644 test_data/0.sig delete mode 100644 test_data/2.priv delete mode 100644 test_data/2.pub delete mode 100644 test_data/2.sig delete mode 100644 test_data/3.priv delete mode 100644 test_data/3.pub delete mode 100644 test_data/3.sig diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index 9c827fb..0000000 --- a/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -test_data/** binary diff --git a/bench_test.go b/bench_test.go deleted file mode 100644 index fffc3bb..0000000 --- a/bench_test.go +++ /dev/null @@ -1,84 +0,0 @@ -package crypto - -import "testing" - -func BenchmarkSignRSA1B(b *testing.B) { RunBenchmarkSignRSA(b, 1) } -func BenchmarkSignRSA10B(b *testing.B) { RunBenchmarkSignRSA(b, 10) } -func BenchmarkSignRSA100B(b *testing.B) { RunBenchmarkSignRSA(b, 100) } -func BenchmarkSignRSA1000B(b *testing.B) { RunBenchmarkSignRSA(b, 1000) } -func BenchmarkSignRSA10000B(b *testing.B) { RunBenchmarkSignRSA(b, 10000) } -func BenchmarkSignRSA100000B(b *testing.B) { RunBenchmarkSignRSA(b, 100000) } - -func BenchmarkVerifyRSA1B(b *testing.B) { RunBenchmarkVerifyRSA(b, 1) } -func BenchmarkVerifyRSA10B(b *testing.B) { RunBenchmarkVerifyRSA(b, 10) } -func BenchmarkVerifyRSA100B(b *testing.B) { RunBenchmarkVerifyRSA(b, 100) } -func BenchmarkVerifyRSA1000B(b *testing.B) { RunBenchmarkVerifyRSA(b, 1000) } -func BenchmarkVerifyRSA10000B(b *testing.B) { RunBenchmarkVerifyRSA(b, 10000) } -func BenchmarkVerifyRSA100000B(b *testing.B) { RunBenchmarkVerifyRSA(b, 100000) } - -func BenchmarkSignEd255191B(b *testing.B) { RunBenchmarkSignEd25519(b, 1) } -func BenchmarkSignEd2551910B(b *testing.B) { RunBenchmarkSignEd25519(b, 10) } -func BenchmarkSignEd25519100B(b *testing.B) { RunBenchmarkSignEd25519(b, 100) } -func BenchmarkSignEd255191000B(b *testing.B) { RunBenchmarkSignEd25519(b, 1000) } -func BenchmarkSignEd2551910000B(b *testing.B) { RunBenchmarkSignEd25519(b, 10000) } -func BenchmarkSignEd25519100000B(b *testing.B) { RunBenchmarkSignEd25519(b, 100000) } - -func BenchmarkVerifyEd255191B(b *testing.B) { RunBenchmarkVerifyEd25519(b, 1) } -func BenchmarkVerifyEd2551910B(b *testing.B) { RunBenchmarkVerifyEd25519(b, 10) } -func BenchmarkVerifyEd25519100B(b *testing.B) { RunBenchmarkVerifyEd25519(b, 100) } -func BenchmarkVerifyEd255191000B(b *testing.B) { RunBenchmarkVerifyEd25519(b, 1000) } -func BenchmarkVerifyEd2551910000B(b *testing.B) { RunBenchmarkVerifyEd25519(b, 10000) } -func BenchmarkVerifyEd25519100000B(b *testing.B) { RunBenchmarkVerifyEd25519(b, 100000) } - -func RunBenchmarkSignRSA(b *testing.B, numBytes int) { - runBenchmarkSign(b, numBytes, RSA) -} - -func RunBenchmarkSignEd25519(b *testing.B, numBytes int) { - runBenchmarkSign(b, numBytes, Ed25519) -} - -func runBenchmarkSign(b *testing.B, numBytes int, t int) { - secret, _, err := GenerateKeyPair(t, 1024) - if err != nil { - b.Fatal(err) - } - someData := make([]byte, numBytes) - b.ResetTimer() - for i := 0; i < b.N; i++ { - _, err := secret.Sign(someData) - if err != nil { - b.Fatal(err) - } - } -} - -func RunBenchmarkVerifyRSA(b *testing.B, numBytes int) { - runBenchmarkSign(b, numBytes, RSA) -} - -func RunBenchmarkVerifyEd25519(b *testing.B, numBytes int) { - runBenchmarkSign(b, numBytes, Ed25519) -} - -func runBenchmarkVerify(b *testing.B, numBytes int, t int) { - secret, public, err := GenerateKeyPair(t, 1024) - if err != nil { - b.Fatal(err) - } - someData := make([]byte, numBytes) - signature, err := secret.Sign(someData) - if err != nil { - b.Fatal(err) - } - b.ResetTimer() - for i := 0; i < b.N; i++ { - valid, err := public.Verify(someData, signature) - if err != nil { - b.Fatal(err) - } - if !valid { - b.Fatal("signature should be valid") - } - } -} diff --git a/ecdsa.go b/ecdsa.go deleted file mode 100644 index 80229a4..0000000 --- a/ecdsa.go +++ /dev/null @@ -1,186 +0,0 @@ -package crypto - -import ( - "crypto/ecdsa" - "crypto/elliptic" - "crypto/rand" - "crypto/x509" - "encoding/asn1" - "errors" - "io" - "math/big" - - pb "github.com/libp2p/go-libp2p-crypto/pb" - - sha256 "github.com/minio/sha256-simd" -) - -// ECDSAPrivateKey is an implementation of an ECDSA private key -type ECDSAPrivateKey struct { - priv *ecdsa.PrivateKey -} - -// ECDSAPublicKey is an implementation of an ECDSA public key -type ECDSAPublicKey struct { - pub *ecdsa.PublicKey -} - -// ECDSASig holds the r and s values of an ECDSA signature -type ECDSASig struct { - R, S *big.Int -} - -var ( - // ErrNotECDSAPubKey is returned when the public key passed is not an ecdsa public key - ErrNotECDSAPubKey = errors.New("not an ecdsa public key") - // ErrNilSig is returned when the signature is nil - ErrNilSig = errors.New("sig is nil") - // ErrNilPrivateKey is returned when a nil private key is provided - ErrNilPrivateKey = errors.New("private key is nil") - // ECDSACurve is the default ecdsa curve used - ECDSACurve = elliptic.P256() -) - -// GenerateECDSAKeyPair generates a new ecdsa private and public key -func GenerateECDSAKeyPair(src io.Reader) (PrivKey, PubKey, error) { - return GenerateECDSAKeyPairWithCurve(ECDSACurve, src) -} - -// GenerateECDSAKeyPairWithCurve generates a new ecdsa private and public key with a speicified curve -func GenerateECDSAKeyPairWithCurve(curve elliptic.Curve, src io.Reader) (PrivKey, PubKey, error) { - priv, err := ecdsa.GenerateKey(curve, src) - if err != nil { - return nil, nil, err - } - - return &ECDSAPrivateKey{priv}, &ECDSAPublicKey{&priv.PublicKey}, nil -} - -// ECDSAKeyPairFromKey generates a new ecdsa private and public key from an input private key -func ECDSAKeyPairFromKey(priv *ecdsa.PrivateKey) (PrivKey, PubKey, error) { - if priv == nil { - return nil, nil, ErrNilPrivateKey - } - - return &ECDSAPrivateKey{priv}, &ECDSAPublicKey{&priv.PublicKey}, nil -} - -// MarshalECDSAPrivateKey returns x509 bytes from a private key -func MarshalECDSAPrivateKey(ePriv ECDSAPrivateKey) ([]byte, error) { - return x509.MarshalECPrivateKey(ePriv.priv) -} - -// MarshalECDSAPublicKey returns x509 bytes from a public key -func MarshalECDSAPublicKey(ePub ECDSAPublicKey) ([]byte, error) { - return x509.MarshalPKIXPublicKey(ePub.pub) -} - -// UnmarshalECDSAPrivateKey returns a private key from x509 bytes -func UnmarshalECDSAPrivateKey(data []byte) (PrivKey, error) { - priv, err := x509.ParseECPrivateKey(data) - if err != nil { - return nil, err - } - - return &ECDSAPrivateKey{priv}, nil -} - -// UnmarshalECDSAPublicKey returns the public key from x509 bytes -func UnmarshalECDSAPublicKey(data []byte) (PubKey, error) { - pubIfc, err := x509.ParsePKIXPublicKey(data) - if err != nil { - return nil, err - } - - pub, ok := pubIfc.(*ecdsa.PublicKey) - if !ok { - return nil, ErrNotECDSAPubKey - } - - return &ECDSAPublicKey{pub}, nil -} - -// Bytes returns the private key as protobuf bytes -func (ePriv *ECDSAPrivateKey) Bytes() ([]byte, error) { - return MarshalPrivateKey(ePriv) -} - -// Type returns the key type -func (ePriv *ECDSAPrivateKey) Type() pb.KeyType { - return pb.KeyType_ECDSA -} - -// Raw returns x509 bytes from a private key -func (ePriv *ECDSAPrivateKey) Raw() ([]byte, error) { - return x509.MarshalECPrivateKey(ePriv.priv) -} - -// Equals compares to private keys -func (ePriv *ECDSAPrivateKey) Equals(o Key) bool { - oPriv, ok := o.(*ECDSAPrivateKey) - if !ok { - return false - } - - return ePriv.priv.D.Cmp(oPriv.priv.D) == 0 -} - -// Sign returns the signature of the input data -func (ePriv *ECDSAPrivateKey) Sign(data []byte) ([]byte, error) { - hash := sha256.Sum256(data) - r, s, err := ecdsa.Sign(rand.Reader, ePriv.priv, hash[:]) - if err != nil { - return nil, err - } - - return asn1.Marshal(ECDSASig{ - R: r, - S: s, - }) -} - -// GetPublic returns a public key -func (ePriv *ECDSAPrivateKey) GetPublic() PubKey { - return &ECDSAPublicKey{&ePriv.priv.PublicKey} -} - -// Bytes returns the public key as protobuf bytes -func (ePub *ECDSAPublicKey) Bytes() ([]byte, error) { - return MarshalPublicKey(ePub) -} - -// Type returns the key type -func (ePub *ECDSAPublicKey) Type() pb.KeyType { - return pb.KeyType_ECDSA -} - -// Raw returns x509 bytes from a public key -func (ePub ECDSAPublicKey) Raw() ([]byte, error) { - return x509.MarshalPKIXPublicKey(ePub.pub) -} - -// Equals compares to public keys -func (ePub *ECDSAPublicKey) Equals(o Key) bool { - oPub, ok := o.(*ECDSAPublicKey) - if !ok { - return false - } - - return ePub.pub.X != nil && ePub.pub.Y != nil && oPub.pub.X != nil && oPub.pub.Y != nil && - 0 == ePub.pub.X.Cmp(oPub.pub.X) && 0 == ePub.pub.Y.Cmp(oPub.pub.Y) -} - -// Verify compares data to a signature -func (ePub *ECDSAPublicKey) Verify(data, sigBytes []byte) (bool, error) { - sig := new(ECDSASig) - if _, err := asn1.Unmarshal(sigBytes, sig); err != nil { - return false, err - } - if sig == nil { - return false, ErrNilSig - } - - hash := sha256.Sum256(data) - - return ecdsa.Verify(ePub.pub, hash[:], sig.R, sig.S), nil -} diff --git a/ecdsa_deprecated.go b/ecdsa_deprecated.go new file mode 100644 index 0000000..f37d661 --- /dev/null +++ b/ecdsa_deprecated.go @@ -0,0 +1,64 @@ +package crypto + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "io" + + core "github.com/libp2p/go-libp2p-core/crypto" +) + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.ECDSAPrivateKey instead. +type ECDSAPrivateKey = core.ECDSAPrivateKey + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.ECDSAPublicKey instead. +type ECDSAPublicKey = core.ECDSAPublicKey + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.ECDSASig instead. +type ECDSASig = core.ECDSASig + +var ( + // Deprecated: use github.com/libp2p/go-libp2p-core/crypto.ErrNotECDSAPubKey instead. + ErrNotECDSAPubKey = core.ErrNotECDSAPubKey + // Deprecated: use github.com/libp2p/go-libp2p-core/crypto.ErrNilSig instead. + ErrNilSig = core.ErrNilSig + // Deprecated: use github.com/libp2p/go-libp2p-core/crypto.ErrNilPrivateKey instead. + ErrNilPrivateKey = core.ErrNilPrivateKey + // Deprecated: use github.com/libp2p/go-libp2p-core/crypto.ECDSACurve instead. + ECDSACurve = core.ECDSACurve +) + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.GenerateECDSAKeyPair instead. +func GenerateECDSAKeyPair(src io.Reader) (PrivKey, PubKey, error) { + return core.GenerateECDSAKeyPair(src) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.GenerateECDSAKeyPairWithCurve instead. +func GenerateECDSAKeyPairWithCurve(curve elliptic.Curve, src io.Reader) (PrivKey, PubKey, error) { + return core.GenerateECDSAKeyPairWithCurve(curve, src) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.ECDSAKeyPairFromKey instead. +func ECDSAKeyPairFromKey(priv *ecdsa.PrivateKey) (PrivKey, PubKey, error) { + return core.ECDSAKeyPairFromKey(priv) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.MarshalECDSAPrivateKey instead. +func MarshalECDSAPrivateKey(ePriv ECDSAPrivateKey) ([]byte, error) { + return core.MarshalECDSAPrivateKey(ePriv) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.MarshalECDSAPublicKey instead. +func MarshalECDSAPublicKey(ePub ECDSAPublicKey) ([]byte, error) { + return core.MarshalECDSAPublicKey(ePub) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.UnmarshalECDSAPrivateKey instead. +func UnmarshalECDSAPrivateKey(data []byte) (PrivKey, error) { + return core.UnmarshalECDSAPrivateKey(data) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.UnmarshalECDSAPublicKey instead. +func UnmarshalECDSAPublicKey(data []byte) (PubKey, error) { + return core.UnmarshalECDSAPublicKey(data) +} diff --git a/ecdsa_test.go b/ecdsa_test.go deleted file mode 100644 index 328b9a7..0000000 --- a/ecdsa_test.go +++ /dev/null @@ -1,96 +0,0 @@ -package crypto - -import ( - "crypto/rand" - "testing" -) - -func TestECDSABasicSignAndVerify(t *testing.T) { - priv, pub, err := GenerateECDSAKeyPair(rand.Reader) - if err != nil { - t.Fatal(err) - } - - data := []byte("hello! and welcome to some awesome crypto primitives") - - sig, err := priv.Sign(data) - if err != nil { - t.Fatal(err) - } - - ok, err := pub.Verify(data, sig) - if err != nil { - t.Fatal(err) - } - - if !ok { - t.Fatal("signature didnt match") - } - - // change data - data[0] = ^data[0] - ok, err = pub.Verify(data, sig) - if err != nil { - t.Fatal(err) - } - - if ok { - t.Fatal("signature matched and shouldn't") - } -} - -func TestECDSASignZero(t *testing.T) { - priv, pub, err := GenerateECDSAKeyPair(rand.Reader) - if err != nil { - t.Fatal(err) - } - - data := make([]byte, 0) - sig, err := priv.Sign(data) - if err != nil { - t.Fatal(err) - } - - ok, err := pub.Verify(data, sig) - if err != nil { - t.Fatal(err) - } - if !ok { - t.Fatal("signature didn't match") - } -} - -func TestECDSAMarshalLoop(t *testing.T) { - priv, pub, err := GenerateECDSAKeyPair(rand.Reader) - if err != nil { - t.Fatal(err) - } - - privB, err := priv.Bytes() - if err != nil { - t.Fatal(err) - } - - privNew, err := UnmarshalPrivateKey(privB) - if err != nil { - t.Fatal(err) - } - - if !priv.Equals(privNew) || !privNew.Equals(priv) { - t.Fatal("keys are not equal") - } - - pubB, err := pub.Bytes() - if err != nil { - t.Fatal(err) - } - pubNew, err := UnmarshalPublicKey(pubB) - if err != nil { - t.Fatal(err) - } - - if !pub.Equals(pubNew) || !pubNew.Equals(pub) { - t.Fatal("keys are not equal") - } - -} diff --git a/ed25519.go b/ed25519.go deleted file mode 100644 index 960ad31..0000000 --- a/ed25519.go +++ /dev/null @@ -1,155 +0,0 @@ -package crypto - -import ( - "bytes" - "errors" - "fmt" - "io" - - pb "github.com/libp2p/go-libp2p-crypto/pb" - - "golang.org/x/crypto/ed25519" -) - -// Ed25519PrivateKey is an ed25519 private key. -type Ed25519PrivateKey struct { - k ed25519.PrivateKey -} - -// Ed25519PublicKey is an ed25519 public key. -type Ed25519PublicKey struct { - k ed25519.PublicKey -} - -// GenerateEd25519Key generate a new ed25519 private and public key pair. -func GenerateEd25519Key(src io.Reader) (PrivKey, PubKey, error) { - pub, priv, err := ed25519.GenerateKey(src) - if err != nil { - return nil, nil, err - } - - return &Ed25519PrivateKey{ - k: priv, - }, - &Ed25519PublicKey{ - k: pub, - }, - nil -} - -// Type of the private key (Ed25519). -func (k *Ed25519PrivateKey) Type() pb.KeyType { - return pb.KeyType_Ed25519 -} - -// Bytes marshals an ed25519 private key to protobuf bytes. -func (k *Ed25519PrivateKey) Bytes() ([]byte, error) { - return MarshalPrivateKey(k) -} - -// Raw private key bytes. -func (k *Ed25519PrivateKey) Raw() ([]byte, error) { - // The Ed25519 private key contains two 32-bytes curve points, the private - // key and the public key. - // It makes it more efficient to get the public key without re-computing an - // elliptic curve multiplication. - buf := make([]byte, len(k.k)) - copy(buf, k.k) - - return buf, nil -} - -func (k *Ed25519PrivateKey) pubKeyBytes() []byte { - return k.k[ed25519.PrivateKeySize-ed25519.PublicKeySize:] -} - -// Equals compares two ed25519 private keys. -func (k *Ed25519PrivateKey) Equals(o Key) bool { - edk, ok := o.(*Ed25519PrivateKey) - if !ok { - return false - } - - return bytes.Equal(k.k, edk.k) -} - -// GetPublic returns an ed25519 public key from a private key. -func (k *Ed25519PrivateKey) GetPublic() PubKey { - return &Ed25519PublicKey{k: k.pubKeyBytes()} -} - -// Sign returns a signature from an input message. -func (k *Ed25519PrivateKey) Sign(msg []byte) ([]byte, error) { - return ed25519.Sign(k.k, msg), nil -} - -// Type of the public key (Ed25519). -func (k *Ed25519PublicKey) Type() pb.KeyType { - return pb.KeyType_Ed25519 -} - -// Bytes returns a ed25519 public key as protobuf bytes. -func (k *Ed25519PublicKey) Bytes() ([]byte, error) { - return MarshalPublicKey(k) -} - -// Raw public key bytes. -func (k *Ed25519PublicKey) Raw() ([]byte, error) { - return k.k, nil -} - -// Equals compares two ed25519 public keys. -func (k *Ed25519PublicKey) Equals(o Key) bool { - edk, ok := o.(*Ed25519PublicKey) - if !ok { - return false - } - - return bytes.Equal(k.k, edk.k) -} - -// Verify checks a signature agains the input data. -func (k *Ed25519PublicKey) Verify(data []byte, sig []byte) (bool, error) { - return ed25519.Verify(k.k, data, sig), nil -} - -// UnmarshalEd25519PublicKey returns a public key from input bytes. -func UnmarshalEd25519PublicKey(data []byte) (PubKey, error) { - if len(data) != 32 { - return nil, errors.New("expect ed25519 public key data size to be 32") - } - - return &Ed25519PublicKey{ - k: ed25519.PublicKey(data), - }, nil -} - -// UnmarshalEd25519PrivateKey returns a private key from input bytes. -func UnmarshalEd25519PrivateKey(data []byte) (PrivKey, error) { - switch len(data) { - case ed25519.PrivateKeySize + ed25519.PublicKeySize: - // Remove the redundant public key. See issue #36. - redundantPk := data[ed25519.PrivateKeySize:] - pk := data[ed25519.PrivateKeySize-ed25519.PublicKeySize : ed25519.PrivateKeySize] - if !bytes.Equal(pk, redundantPk) { - return nil, errors.New("expected redundant ed25519 public key to be redundant") - } - - // No point in storing the extra data. - newKey := make([]byte, ed25519.PrivateKeySize) - copy(newKey, data[:ed25519.PrivateKeySize]) - data = newKey - case ed25519.PrivateKeySize: - default: - return nil, fmt.Errorf( - "expected ed25519 data size to be %d or %d, got %d", - ed25519.PrivateKeySize, - ed25519.PrivateKeySize+ed25519.PublicKeySize, - len(data), - ) - } - - return &Ed25519PrivateKey{ - k: ed25519.PrivateKey(data), - }, nil -} diff --git a/ed25519_deprecated.go b/ed25519_deprecated.go new file mode 100644 index 0000000..3d9a4b4 --- /dev/null +++ b/ed25519_deprecated.go @@ -0,0 +1,28 @@ +package crypto + +import ( + "io" + + core "github.com/libp2p/go-libp2p-core/crypto" +) + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.Ed25519PrivateKey instead. +type Ed25519PrivateKey = core.Ed25519PrivateKey + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.Ed25519PublicKey instead. +type Ed25519PublicKey = core.Ed25519PublicKey + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.GenerateEd25519Key instead. +func GenerateEd25519Key(src io.Reader) (PrivKey, PubKey, error) { + return core.GenerateEd25519Key(src) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.UnmarshalEd25519PublicKey instead. +func UnmarshalEd25519PublicKey(data []byte) (PubKey, error) { + return core.UnmarshalEd25519PublicKey(data) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.UnmarshalEd25519PrivateKey instead. +func UnmarshalEd25519PrivateKey(data []byte) (PrivKey, error) { + return core.UnmarshalEd25519PrivateKey(data) +} diff --git a/ed25519_test.go b/ed25519_test.go deleted file mode 100644 index b57de9b..0000000 --- a/ed25519_test.go +++ /dev/null @@ -1,220 +0,0 @@ -package crypto - -import ( - "crypto/rand" - "testing" - - pb "github.com/libp2p/go-libp2p-crypto/pb" - - "golang.org/x/crypto/ed25519" -) - -func TestBasicSignAndVerify(t *testing.T) { - priv, pub, err := GenerateEd25519Key(rand.Reader) - if err != nil { - t.Fatal(err) - } - - data := []byte("hello! and welcome to some awesome crypto primitives") - - sig, err := priv.Sign(data) - if err != nil { - t.Fatal(err) - } - - ok, err := pub.Verify(data, sig) - if err != nil { - t.Fatal(err) - } - - if !ok { - t.Fatal("signature didn't match") - } - - // change data - data[0] = ^data[0] - ok, err = pub.Verify(data, sig) - if err != nil { - t.Fatal(err) - } - - if ok { - t.Fatal("signature matched and shouldn't") - } -} - -func TestSignZero(t *testing.T) { - priv, pub, err := GenerateEd25519Key(rand.Reader) - if err != nil { - t.Fatal(err) - } - - data := make([]byte, 0) - sig, err := priv.Sign(data) - if err != nil { - t.Fatal(err) - } - - ok, err := pub.Verify(data, sig) - if err != nil { - t.Fatal(err) - } - if !ok { - t.Fatal("signature didn't match") - } -} - -func TestMarshalLoop(t *testing.T) { - priv, pub, err := GenerateEd25519Key(rand.Reader) - if err != nil { - t.Fatal(err) - } - - t.Run("PrivateKey", func(t *testing.T) { - for name, f := range map[string]func() ([]byte, error){ - "Bytes": priv.Bytes, - "Marshal": func() ([]byte, error) { - return MarshalPrivateKey(priv) - }, - "Redundant": func() ([]byte, error) { - // See issue #36. - // Ed25519 private keys used to contain the public key twice. - // For backwards-compatibility, we need to continue supporting - // that scenario. - pbmes := new(pb.PrivateKey) - pbmes.Type = priv.Type() - data, err := priv.Raw() - if err != nil { - t.Fatal(err) - } - - pbmes.Data = append(data, data[len(data)-ed25519.PublicKeySize:]...) - return pbmes.Marshal() - }, - } { - t.Run(name, func(t *testing.T) { - bts, err := f() - if err != nil { - t.Fatal(err) - } - - privNew, err := UnmarshalPrivateKey(bts) - if err != nil { - t.Fatal(err) - } - - if !priv.Equals(privNew) || !privNew.Equals(priv) { - t.Fatal("keys are not equal") - } - - msg := []byte("My child, my sister,\nThink of the rapture\nOf living together there!") - signed, err := privNew.Sign(msg) - if err != nil { - t.Fatal(err) - } - - ok, err := privNew.GetPublic().Verify(msg, signed) - if err != nil { - t.Fatal(err) - } - - if !ok { - t.Fatal("signature didn't match") - } - }) - } - }) - - t.Run("PublicKey", func(t *testing.T) { - for name, f := range map[string]func() ([]byte, error){ - "Bytes": pub.Bytes, - "Marshal": func() ([]byte, error) { - return MarshalPublicKey(pub) - }, - } { - t.Run(name, func(t *testing.T) { - bts, err := f() - if err != nil { - t.Fatal(err) - } - pubNew, err := UnmarshalPublicKey(bts) - if err != nil { - t.Fatal(err) - } - - if !pub.Equals(pubNew) || !pubNew.Equals(pub) { - t.Fatal("keys are not equal") - } - }) - } - }) -} - -func TestUnmarshalErrors(t *testing.T) { - t.Run("PublicKey", func(t *testing.T) { - t.Run("Invalid data length", func(t *testing.T) { - pbmes := &pb.PublicKey{ - Type: pb.KeyType_Ed25519, - Data: []byte{42}, - } - - data, err := pbmes.Marshal() - if err != nil { - t.Fatal(err) - } - - _, err = UnmarshalPublicKey(data) - if err == nil { - t.Fatal("expected an error") - } - }) - }) - - t.Run("PrivateKey", func(t *testing.T) { - t.Run("Redundant public key mismatch", func(t *testing.T) { - priv, _, err := GenerateEd25519Key(rand.Reader) - if err != nil { - t.Fatal(err) - } - - pbmes := new(pb.PrivateKey) - pbmes.Type = priv.Type() - data, err := priv.Raw() - if err != nil { - t.Fatal(err) - } - - // Append the private key instead of the public key. - pbmes.Data = append(data, data[:ed25519.PublicKeySize]...) - b, err := pbmes.Marshal() - if err != nil { - t.Fatal(err) - } - - _, err = UnmarshalPrivateKey(b) - if err == nil { - t.Fatal("expected an error") - } - if err.Error() != "expected redundant ed25519 public key to be redundant" { - t.Fatalf("invalid error received: %s", err.Error()) - } - }) - - t.Run("Invalid data length", func(t *testing.T) { - pbmes := &pb.PrivateKey{ - Type: pb.KeyType_Ed25519, - Data: []byte{42}, - } - - data, err := pbmes.Marshal() - if err != nil { - t.Fatal(err) - } - - _, err = UnmarshalPrivateKey(data) - if err == nil { - t.Fatal("expected an error") - } - }) - }) -} diff --git a/fixture_test.go b/fixture_test.go deleted file mode 100644 index a291194..0000000 --- a/fixture_test.go +++ /dev/null @@ -1,132 +0,0 @@ -package crypto_test - -import ( - "bytes" - "crypto/rand" - "fmt" - "io" - "io/ioutil" - "testing" - - crypto "github.com/libp2p/go-libp2p-crypto" - crypto_pb "github.com/libp2p/go-libp2p-crypto/pb" -) - -var message = []byte("Libp2p is the _best_!") - -type testCase struct { - keyType crypto_pb.KeyType - gen func(i io.Reader) (crypto.PrivKey, crypto.PubKey, error) - sigDeterministic bool -} - -var keyTypes = []testCase{ - { - keyType: crypto_pb.KeyType_ECDSA, - gen: crypto.GenerateECDSAKeyPair, - }, - { - keyType: crypto_pb.KeyType_Secp256k1, - sigDeterministic: true, - gen: crypto.GenerateSecp256k1Key, - }, - { - keyType: crypto_pb.KeyType_RSA, - sigDeterministic: true, - gen: func(i io.Reader) (crypto.PrivKey, crypto.PubKey, error) { - return crypto.GenerateRSAKeyPair(2048, i) - }, - }, -} - -func fname(kt crypto_pb.KeyType, ext string) string { - return fmt.Sprintf("test_data/%d.%s", kt, ext) -} - -func TestFixtures(t *testing.T) { - for _, tc := range keyTypes { - t.Run(tc.keyType.String(), func(t *testing.T) { - pubBytes, err := ioutil.ReadFile(fname(tc.keyType, "pub")) - if err != nil { - t.Fatal(err) - } - privBytes, err := ioutil.ReadFile(fname(tc.keyType, "priv")) - if err != nil { - t.Fatal(err) - } - sigBytes, err := ioutil.ReadFile(fname(tc.keyType, "sig")) - if err != nil { - t.Fatal(err) - } - pub, err := crypto.UnmarshalPublicKey(pubBytes) - if err != nil { - t.Fatal(err) - } - pubBytes2, err := pub.Bytes() - if err != nil { - t.Fatal(err) - } - if !bytes.Equal(pubBytes2, pubBytes) { - t.Fatal("encoding round-trip failed") - } - priv, err := crypto.UnmarshalPrivateKey(privBytes) - if err != nil { - t.Fatal(err) - } - privBytes2, err := priv.Bytes() - if err != nil { - t.Fatal(err) - } - if !bytes.Equal(privBytes2, privBytes) { - t.Fatal("encoding round-trip failed") - } - ok, err := pub.Verify(message, sigBytes) - if !ok || err != nil { - t.Fatal("failed to validate signature with public key") - } - - if tc.sigDeterministic { - sigBytes2, err := priv.Sign(message) - if err != nil { - t.Fatal(err) - } - if !bytes.Equal(sigBytes2, sigBytes) { - t.Fatal("signature not deterministic") - } - } - }) - } -} - -func init() { - // set to true to re-generate test data - if false { - generate() - panic("generated") - } -} - -// generate re-generates test data -func generate() { - for _, tc := range keyTypes { - priv, pub, err := tc.gen(rand.Reader) - if err != nil { - panic(err) - } - pubb, err := pub.Bytes() - if err != nil { - panic(err) - } - privb, err := priv.Bytes() - if err != nil { - panic(err) - } - sig, err := priv.Sign(message) - if err != nil { - panic(err) - } - ioutil.WriteFile(fname(tc.keyType, "pub"), pubb, 0666) - ioutil.WriteFile(fname(tc.keyType, "priv"), privb, 0666) - ioutil.WriteFile(fname(tc.keyType, "sig"), sig, 0666) - } -} diff --git a/go.mod b/go.mod index 11176ce..38a007a 100644 --- a/go.mod +++ b/go.mod @@ -1,9 +1,3 @@ module github.com/libp2p/go-libp2p-crypto -require ( - github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32 - github.com/gogo/protobuf v1.2.1 - github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 - github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a - golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b -) +require github.com/libp2p/go-libp2p-core v0.0.1 diff --git a/go.sum b/go.sum index 8b8d0ce..669c035 100644 --- a/go.sum +++ b/go.sum @@ -8,20 +8,41 @@ github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVa github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495 h1:6IyqGr3fnd0tM3YxipK27TUskaOVUjU2nG45yzwcQKY= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-libp2p-core v0.0.1 h1:HSTZtFIq/W5Ue43Zw+uWZyy2Vl5WtF0zDjKN8/DT/1I= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ= github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1 h1:OJIdWOWYe2l5PQNgimGtuwHY8nDskvJ5vvs//YnzRLs= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-multiaddr v0.0.2 h1:RBysRCv5rv3FWlhKWKoXv8tnsCUpEpIZpCmqAGZos2s= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= @@ -30,11 +51,14 @@ github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7A github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b h1:+/WWzjwW6gidDJnMKWLKLX1gxn7irUTF1fLpQovfQ5M= golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d h1:Z0Ahzd7HltpJtjAHHxX8QFP3j1yYgiuvjbjRzDj/KH0= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/key.go b/key.go deleted file mode 100644 index 9900772..0000000 --- a/key.go +++ /dev/null @@ -1,352 +0,0 @@ -// Package crypto implements various cryptographic utilities used by ipfs. -// This includes a Public and Private key interface and an RSA key implementation -// that satisfies it. -package crypto - -import ( - "bytes" - "crypto/elliptic" - "crypto/hmac" - "crypto/rand" - "crypto/sha1" - "crypto/sha512" - "encoding/base64" - "errors" - "fmt" - "hash" - "io" - - pb "github.com/libp2p/go-libp2p-crypto/pb" - - "github.com/gogo/protobuf/proto" - sha256 "github.com/minio/sha256-simd" -) - -const ( - // RSA is an enum for the supported RSA key type - RSA = iota - // Ed25519 is an enum for the supported Ed25519 key type - Ed25519 - // Secp256k1 is an enum for the supported Secp256k1 key type - Secp256k1 - // ECDSA is an enum for the supported ECDSA key type - ECDSA -) - -var ( - // ErrBadKeyType is returned when a key is not supported - ErrBadKeyType = errors.New("invalid or unsupported key type") - // KeyTypes is a list of supported keys - KeyTypes = []int{ - RSA, - Ed25519, - Secp256k1, - ECDSA, - } -) - -// PubKeyUnmarshaller is a func that creates a PubKey from a given slice of bytes -type PubKeyUnmarshaller func(data []byte) (PubKey, error) - -// PrivKeyUnmarshaller is a func that creates a PrivKey from a given slice of bytes -type PrivKeyUnmarshaller func(data []byte) (PrivKey, error) - -// PubKeyUnmarshallers is a map of unmarshallers by key type -var PubKeyUnmarshallers = map[pb.KeyType]PubKeyUnmarshaller{ - pb.KeyType_RSA: UnmarshalRsaPublicKey, - pb.KeyType_Ed25519: UnmarshalEd25519PublicKey, - pb.KeyType_Secp256k1: UnmarshalSecp256k1PublicKey, - pb.KeyType_ECDSA: UnmarshalECDSAPublicKey, -} - -// PrivKeyUnmarshallers is a map of unmarshallers by key type -var PrivKeyUnmarshallers = map[pb.KeyType]PrivKeyUnmarshaller{ - pb.KeyType_RSA: UnmarshalRsaPrivateKey, - pb.KeyType_Ed25519: UnmarshalEd25519PrivateKey, - pb.KeyType_Secp256k1: UnmarshalSecp256k1PrivateKey, - pb.KeyType_ECDSA: UnmarshalECDSAPrivateKey, -} - -// Key represents a crypto key that can be compared to another key -type Key interface { - // Bytes returns a serialized, storeable representation of this key - // DEPRECATED in favor of Marshal / Unmarshal - Bytes() ([]byte, error) - - // Equals checks whether two PubKeys are the same - Equals(Key) bool - - // Raw returns the raw bytes of the key (not wrapped in the - // libp2p-crypto protobuf). - // - // This function is the inverse of {Priv,Pub}KeyUnmarshaler. - Raw() ([]byte, error) - - // Type returns the protobof key type. - Type() pb.KeyType -} - -// PrivKey represents a private key that can be used to generate a public key, -// sign data, and decrypt data that was encrypted with a public key -type PrivKey interface { - Key - - // Cryptographically sign the given bytes - Sign([]byte) ([]byte, error) - - // Return a public key paired with this private key - GetPublic() PubKey -} - -// PubKey is a public key -type PubKey interface { - Key - - // Verify that 'sig' is the signed hash of 'data' - Verify(data []byte, sig []byte) (bool, error) -} - -// GenSharedKey generates the shared key from a given private key -type GenSharedKey func([]byte) ([]byte, error) - -// GenerateKeyPair generates a private and public key -func GenerateKeyPair(typ, bits int) (PrivKey, PubKey, error) { - return GenerateKeyPairWithReader(typ, bits, rand.Reader) -} - -// GenerateKeyPairWithReader returns a keypair of the given type and bitsize -func GenerateKeyPairWithReader(typ, bits int, src io.Reader) (PrivKey, PubKey, error) { - switch typ { - case RSA: - return GenerateRSAKeyPair(bits, src) - case Ed25519: - return GenerateEd25519Key(src) - case Secp256k1: - return GenerateSecp256k1Key(src) - case ECDSA: - return GenerateECDSAKeyPair(src) - default: - return nil, nil, ErrBadKeyType - } -} - -// GenerateEKeyPair returns an ephemeral public key and returns a function that will compute -// the shared secret key. Used in the identify module. -// -// Focuses only on ECDH now, but can be made more general in the future. -func GenerateEKeyPair(curveName string) ([]byte, GenSharedKey, error) { - var curve elliptic.Curve - - switch curveName { - case "P-256": - curve = elliptic.P256() - case "P-384": - curve = elliptic.P384() - case "P-521": - curve = elliptic.P521() - } - - priv, x, y, err := elliptic.GenerateKey(curve, rand.Reader) - if err != nil { - return nil, nil, err - } - - pubKey := elliptic.Marshal(curve, x, y) - - done := func(theirPub []byte) ([]byte, error) { - // Verify and unpack node's public key. - x, y := elliptic.Unmarshal(curve, theirPub) - if x == nil { - return nil, fmt.Errorf("malformed public key: %d %v", len(theirPub), theirPub) - } - - if !curve.IsOnCurve(x, y) { - return nil, errors.New("invalid public key") - } - - // Generate shared secret. - secret, _ := curve.ScalarMult(x, y, priv) - - return secret.Bytes(), nil - } - - return pubKey, done, nil -} - -// StretchedKeys ... -type StretchedKeys struct { - IV []byte - MacKey []byte - CipherKey []byte -} - -// KeyStretcher returns a set of keys for each party by stretching the shared key. -// (myIV, theirIV, myCipherKey, theirCipherKey, myMACKey, theirMACKey) -func KeyStretcher(cipherType string, hashType string, secret []byte) (StretchedKeys, StretchedKeys) { - var cipherKeySize int - var ivSize int - switch cipherType { - case "AES-128": - ivSize = 16 - cipherKeySize = 16 - case "AES-256": - ivSize = 16 - cipherKeySize = 32 - case "Blowfish": - ivSize = 8 - // Note: 24 arbitrarily selected, needs more thought - cipherKeySize = 32 - } - - hmacKeySize := 20 - - seed := []byte("key expansion") - - result := make([]byte, 2*(ivSize+cipherKeySize+hmacKeySize)) - - var h func() hash.Hash - - switch hashType { - case "SHA1": - h = sha1.New - case "SHA256": - h = sha256.New - case "SHA512": - h = sha512.New - default: - panic("Unrecognized hash function, programmer error?") - } - - m := hmac.New(h, secret) - // note: guaranteed to never return an error - m.Write(seed) - - a := m.Sum(nil) - - j := 0 - for j < len(result) { - m.Reset() - - // note: guaranteed to never return an error. - m.Write(a) - m.Write(seed) - - b := m.Sum(nil) - - todo := len(b) - - if j+todo > len(result) { - todo = len(result) - j - } - - copy(result[j:j+todo], b) - - j += todo - - m.Reset() - - // note: guaranteed to never return an error. - m.Write(a) - - a = m.Sum(nil) - } - - half := len(result) / 2 - r1 := result[:half] - r2 := result[half:] - - var k1 StretchedKeys - var k2 StretchedKeys - - k1.IV = r1[0:ivSize] - k1.CipherKey = r1[ivSize : ivSize+cipherKeySize] - k1.MacKey = r1[ivSize+cipherKeySize:] - - k2.IV = r2[0:ivSize] - k2.CipherKey = r2[ivSize : ivSize+cipherKeySize] - k2.MacKey = r2[ivSize+cipherKeySize:] - - return k1, k2 -} - -// UnmarshalPublicKey converts a protobuf serialized public key into its -// representative object -func UnmarshalPublicKey(data []byte) (PubKey, error) { - pmes := new(pb.PublicKey) - err := proto.Unmarshal(data, pmes) - if err != nil { - return nil, err - } - - um, ok := PubKeyUnmarshallers[pmes.GetType()] - if !ok { - return nil, ErrBadKeyType - } - - return um(pmes.GetData()) -} - -// MarshalPublicKey converts a public key object into a protobuf serialized -// public key -func MarshalPublicKey(k PubKey) ([]byte, error) { - pbmes := new(pb.PublicKey) - pbmes.Type = k.Type() - data, err := k.Raw() - if err != nil { - return nil, err - } - pbmes.Data = data - - return proto.Marshal(pbmes) -} - -// UnmarshalPrivateKey converts a protobuf serialized private key into its -// representative object -func UnmarshalPrivateKey(data []byte) (PrivKey, error) { - pmes := new(pb.PrivateKey) - err := proto.Unmarshal(data, pmes) - if err != nil { - return nil, err - } - - um, ok := PrivKeyUnmarshallers[pmes.GetType()] - if !ok { - return nil, ErrBadKeyType - } - - return um(pmes.GetData()) -} - -// MarshalPrivateKey converts a key object into its protobuf serialized form. -func MarshalPrivateKey(k PrivKey) ([]byte, error) { - pbmes := new(pb.PrivateKey) - pbmes.Type = k.Type() - data, err := k.Raw() - if err != nil { - return nil, err - } - - pbmes.Data = data - return proto.Marshal(pbmes) -} - -// ConfigDecodeKey decodes from b64 (for config file), and unmarshals. -func ConfigDecodeKey(b string) ([]byte, error) { - return base64.StdEncoding.DecodeString(b) -} - -// ConfigEncodeKey encodes to b64 (for config file), and marshals. -func ConfigEncodeKey(b []byte) string { - return base64.StdEncoding.EncodeToString(b) -} - -// KeyEqual checks whether two -func KeyEqual(k1, k2 Key) bool { - if k1 == k2 { - return true - } - - b1, err1 := k1.Bytes() - b2, err2 := k2.Bytes() - return bytes.Equal(b1, b2) && err1 == err2 -} diff --git a/key_deprecated.go b/key_deprecated.go new file mode 100644 index 0000000..5734269 --- /dev/null +++ b/key_deprecated.go @@ -0,0 +1,108 @@ +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto instead. +package crypto + +import ( + "io" + + core "github.com/libp2p/go-libp2p-core/crypto" +) + +const ( + // Deprecated: use github.com/libp2p/go-libp2p-core/crypto.RSA instead. + RSA = core.RSA + // Deprecated: use github.com/libp2p/go-libp2p-core/crypto.Ed25519 instead. + Ed25519 = core.Ed25519 + // Deprecated: use github.com/libp2p/go-libp2p-core/crypto.Secp256k1 instead. + Secp256k1 = core.Secp256k1 + // Deprecated: use github.com/libp2p/go-libp2p-core/crypto.ECDSA instead. + ECDSA = core.ECDSA +) + +var ( + // Deprecated: use github.com/libp2p/go-libp2p-core/crypto.ErrBadKeyType instead. + ErrBadKeyType = core.ErrBadKeyType + // Deprecated: use github.com/libp2p/go-libp2p-core/crypto.KeyTypes instead. + KeyTypes = core.KeyTypes +) + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.PubKeyUnmarshaller instead. +type PubKeyUnmarshaller = core.PubKeyUnmarshaller + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.PrivKeyUnmarshaller instead. +type PrivKeyUnmarshaller = core.PrivKeyUnmarshaller + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.PubKeyUnmarshallers instead. +var PubKeyUnmarshallers = core.PubKeyUnmarshallers + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.PrivKeyUnmarshallers instead. +var PrivKeyUnmarshallers = core.PrivKeyUnmarshallers + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.Key instead. +type Key = core.Key + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.PrivKey instead. +type PrivKey = core.PrivKey + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.PubKey instead. +type PubKey = core.PubKey + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.GenSharedKey instead. +type GenSharedKey = core.GenSharedKey + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.GenerateKeyPair instead. +func GenerateKeyPair(typ, bits int) (PrivKey, PubKey, error) { + return core.GenerateKeyPair(typ, bits) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.GenerateKeyPairWithReader instead. +func GenerateKeyPairWithReader(typ, bits int, src io.Reader) (PrivKey, PubKey, error) { + return core.GenerateKeyPairWithReader(typ, bits, src) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.GenerateEKeyPair instead. +func GenerateEKeyPair(curveName string) ([]byte, GenSharedKey, error) { + return core.GenerateEKeyPair(curveName) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.GenSharedKey instead. +type StretchedKeys = core.StretchedKeys + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.KeyStretcher instead. +func KeyStretcher(cipherType string, hashType string, secret []byte) (StretchedKeys, StretchedKeys) { + return core.KeyStretcher(cipherType, hashType, secret) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.UnmarshalPublicKey instead. +func UnmarshalPublicKey(data []byte) (PubKey, error) { + return core.UnmarshalPublicKey(data) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.MarshalPublicKey instead. +func MarshalPublicKey(k PubKey) ([]byte, error) { + return core.MarshalPublicKey(k) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.UnmarshalPrivateKey instead. +func UnmarshalPrivateKey(data []byte) (PrivKey, error) { + return core.UnmarshalPrivateKey(data) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.MarshalPrivateKey instead. +func MarshalPrivateKey(k PrivKey) ([]byte, error) { + return core.MarshalPrivateKey(k) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.ConfigDecodeKey instead. +func ConfigDecodeKey(b string) ([]byte, error) { + return core.ConfigDecodeKey(b) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.ConfigEncodeKey instead. +func ConfigEncodeKey(b []byte) string { + return core.ConfigEncodeKey(b) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.KeyEqual instead. +func KeyEqual(k1, k2 Key) bool { + return core.KeyEqual(k1, k2) +} diff --git a/key_test.go b/key_test.go deleted file mode 100644 index 1d2d8d8..0000000 --- a/key_test.go +++ /dev/null @@ -1,147 +0,0 @@ -package crypto_test - -import ( - "bytes" - "crypto/rand" - "testing" - - . "github.com/libp2p/go-libp2p-crypto" - pb "github.com/libp2p/go-libp2p-crypto/pb" - tu "github.com/libp2p/go-libp2p-crypto/test" -) - -func TestKeys(t *testing.T) { - for _, typ := range KeyTypes { - testKeyType(typ, t) - } -} - -func testKeyType(typ int, t *testing.T) { - sk, pk, err := tu.RandTestKeyPair(typ, 512) - if err != nil { - t.Fatal(err) - } - - testKeySignature(t, sk) - testKeyEncoding(t, sk) - testKeyEquals(t, sk) - testKeyEquals(t, pk) -} - -func testKeySignature(t *testing.T, sk PrivKey) { - pk := sk.GetPublic() - - text := make([]byte, 16) - if _, err := rand.Read(text); err != nil { - t.Fatal(err) - } - - sig, err := sk.Sign(text) - if err != nil { - t.Fatal(err) - } - - valid, err := pk.Verify(text, sig) - if err != nil { - t.Fatal(err) - } - - if !valid { - t.Fatal("Invalid signature.") - } -} - -func testKeyEncoding(t *testing.T, sk PrivKey) { - skbm, err := MarshalPrivateKey(sk) - if err != nil { - t.Fatal(err) - } - - sk2, err := UnmarshalPrivateKey(skbm) - if err != nil { - t.Fatal(err) - } - - if !sk.Equals(sk2) { - t.Error("Unmarshaled private key didn't match original.\n") - } - - skbm2, err := MarshalPrivateKey(sk2) - if err != nil { - t.Fatal(err) - } - - if !bytes.Equal(skbm, skbm2) { - t.Error("skb -> marshal -> unmarshal -> skb failed.\n", skbm, "\n", skbm2) - } - - pk := sk.GetPublic() - pkbm, err := MarshalPublicKey(pk) - if err != nil { - t.Fatal(err) - } - - pk2, err := UnmarshalPublicKey(pkbm) - if err != nil { - t.Fatal(err) - } - - if !pk.Equals(pk2) { - t.Error("Unmarshaled public key didn't match original.\n") - } - - pkbm2, err := MarshalPublicKey(pk) - if err != nil { - t.Fatal(err) - } - - if !bytes.Equal(pkbm, pkbm2) { - t.Error("skb -> marshal -> unmarshal -> skb failed.\n", pkbm, "\n", pkbm2) - } -} - -func testKeyEquals(t *testing.T, k Key) { - kb, err := k.Bytes() - 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.") - } - - sk, pk, err := tu.RandTestKeyPair(RSA, 512) - if err != nil { - t.Fatal(err) - } - - if KeyEqual(k, sk) { - t.Fatal("Keys should not equal.") - } - - if KeyEqual(k, pk) { - t.Fatal("Keys should not equal.") - } -} - -type testkey []byte - -func (pk testkey) Bytes() ([]byte, error) { - return pk, nil -} - -func (pk testkey) Type() pb.KeyType { - return pb.KeyType_RSA -} - -func (pk testkey) Raw() ([]byte, error) { - return pk, nil -} - -func (pk testkey) Equals(k Key) bool { - return KeyEqual(pk, k) -} diff --git a/openssl_common.go b/openssl_common.go deleted file mode 100644 index 776936d..0000000 --- a/openssl_common.go +++ /dev/null @@ -1,98 +0,0 @@ -// +build openssl - -package crypto - -import ( - pb "github.com/libp2p/go-libp2p-crypto/pb" - - openssl "github.com/spacemonkeygo/openssl" -) - -// define these as separate types so we can add more key types later and reuse -// code. - -type opensslPublicKey struct { - key openssl.PublicKey -} - -type opensslPrivateKey struct { - key openssl.PrivateKey -} - -func unmarshalOpensslPrivateKey(b []byte) (opensslPrivateKey, error) { - sk, err := openssl.LoadPrivateKeyFromDER(b) - if err != nil { - return opensslPrivateKey{}, err - } - return opensslPrivateKey{sk}, nil -} - -func unmarshalOpensslPublicKey(b []byte) (opensslPublicKey, error) { - sk, err := openssl.LoadPublicKeyFromDER(b) - if err != nil { - return opensslPublicKey{}, err - } - return opensslPublicKey{sk}, nil -} - -// Verify compares a signature against input data -func (pk *opensslPublicKey) Verify(data, sig []byte) (bool, error) { - err := pk.key.VerifyPKCS1v15(openssl.SHA256_Method, data, sig) - return err == nil, err -} - -func (pk *opensslPublicKey) Type() pb.KeyType { - switch pk.key.KeyType() { - case openssl.KeyTypeRSA: - return pb.KeyType_RSA - default: - return -1 - } -} - -// Bytes returns protobuf bytes of a public key -func (pk *opensslPublicKey) Bytes() ([]byte, error) { - return MarshalPublicKey(pk) -} - -func (pk *opensslPublicKey) Raw() ([]byte, error) { - return pk.key.MarshalPKIXPublicKeyDER() -} - -// Equals checks whether this key is equal to another -func (pk *opensslPublicKey) Equals(k Key) bool { - return KeyEqual(pk, k) -} - -// Sign returns a signature of the input data -func (sk *opensslPrivateKey) Sign(message []byte) ([]byte, error) { - return sk.key.SignPKCS1v15(openssl.SHA256_Method, message) -} - -// GetPublic returns a public key -func (sk *opensslPrivateKey) GetPublic() PubKey { - return &opensslPublicKey{sk.key} -} - -func (sk *opensslPrivateKey) Type() pb.KeyType { - switch sk.key.KeyType() { - case openssl.KeyTypeRSA: - return pb.KeyType_RSA - default: - return -1 - } -} - -// Bytes returns protobuf bytes from a private key -func (sk *opensslPrivateKey) Bytes() ([]byte, error) { - return MarshalPrivateKey(sk) -} - -func (sk *opensslPrivateKey) Raw() ([]byte, error) { - return sk.key.MarshalPKCS1PrivateKeyDER() -} - -// Equals checks whether this key is equal to another -func (sk *opensslPrivateKey) Equals(k Key) bool { - return KeyEqual(sk, k) -} diff --git a/pb/Makefile b/pb/Makefile deleted file mode 100644 index df34e54..0000000 --- a/pb/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -PB = $(wildcard *.proto) -GO = $(PB:.proto=.pb.go) - -all: $(GO) - -%.pb.go: %.proto - protoc --proto_path=$(GOPATH)/src:. --gogofaster_out=. $< - -clean: - rm -f *.pb.go - rm -f *.go diff --git a/pb/crypto.pb.go b/pb/crypto.pb.go deleted file mode 100644 index 5fa7aec..0000000 --- a/pb/crypto.pb.go +++ /dev/null @@ -1,643 +0,0 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: crypto.proto - -package crypto_pb - -import ( - fmt "fmt" - github_com_gogo_protobuf_proto "github.com/gogo/protobuf/proto" - proto "github.com/gogo/protobuf/proto" - io "io" - math "math" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package - -type KeyType int32 - -const ( - KeyType_RSA KeyType = 0 - KeyType_Ed25519 KeyType = 1 - KeyType_Secp256k1 KeyType = 2 - KeyType_ECDSA KeyType = 3 -) - -var KeyType_name = map[int32]string{ - 0: "RSA", - 1: "Ed25519", - 2: "Secp256k1", - 3: "ECDSA", -} - -var KeyType_value = map[string]int32{ - "RSA": 0, - "Ed25519": 1, - "Secp256k1": 2, - "ECDSA": 3, -} - -func (x KeyType) Enum() *KeyType { - p := new(KeyType) - *p = x - return p -} - -func (x KeyType) String() string { - return proto.EnumName(KeyType_name, int32(x)) -} - -func (x *KeyType) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(KeyType_value, data, "KeyType") - if err != nil { - return err - } - *x = KeyType(value) - return nil -} - -func (KeyType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_527278fb02d03321, []int{0} -} - -type PublicKey struct { - Type KeyType `protobuf:"varint,1,req,name=Type,enum=crypto.pb.KeyType" json:"Type"` - Data []byte `protobuf:"bytes,2,req,name=Data" json:"Data"` -} - -func (m *PublicKey) Reset() { *m = PublicKey{} } -func (m *PublicKey) String() string { return proto.CompactTextString(m) } -func (*PublicKey) ProtoMessage() {} -func (*PublicKey) Descriptor() ([]byte, []int) { - return fileDescriptor_527278fb02d03321, []int{0} -} -func (m *PublicKey) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *PublicKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_PublicKey.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *PublicKey) XXX_Merge(src proto.Message) { - xxx_messageInfo_PublicKey.Merge(m, src) -} -func (m *PublicKey) XXX_Size() int { - return m.Size() -} -func (m *PublicKey) XXX_DiscardUnknown() { - xxx_messageInfo_PublicKey.DiscardUnknown(m) -} - -var xxx_messageInfo_PublicKey proto.InternalMessageInfo - -func (m *PublicKey) GetType() KeyType { - if m != nil { - return m.Type - } - return KeyType_RSA -} - -func (m *PublicKey) GetData() []byte { - if m != nil { - return m.Data - } - return nil -} - -type PrivateKey struct { - Type KeyType `protobuf:"varint,1,req,name=Type,enum=crypto.pb.KeyType" json:"Type"` - Data []byte `protobuf:"bytes,2,req,name=Data" json:"Data"` -} - -func (m *PrivateKey) Reset() { *m = PrivateKey{} } -func (m *PrivateKey) String() string { return proto.CompactTextString(m) } -func (*PrivateKey) ProtoMessage() {} -func (*PrivateKey) Descriptor() ([]byte, []int) { - return fileDescriptor_527278fb02d03321, []int{1} -} -func (m *PrivateKey) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *PrivateKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_PrivateKey.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalTo(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *PrivateKey) XXX_Merge(src proto.Message) { - xxx_messageInfo_PrivateKey.Merge(m, src) -} -func (m *PrivateKey) XXX_Size() int { - return m.Size() -} -func (m *PrivateKey) XXX_DiscardUnknown() { - xxx_messageInfo_PrivateKey.DiscardUnknown(m) -} - -var xxx_messageInfo_PrivateKey proto.InternalMessageInfo - -func (m *PrivateKey) GetType() KeyType { - if m != nil { - return m.Type - } - return KeyType_RSA -} - -func (m *PrivateKey) GetData() []byte { - if m != nil { - return m.Data - } - return nil -} - -func init() { - proto.RegisterEnum("crypto.pb.KeyType", KeyType_name, KeyType_value) - proto.RegisterType((*PublicKey)(nil), "crypto.pb.PublicKey") - proto.RegisterType((*PrivateKey)(nil), "crypto.pb.PrivateKey") -} - -func init() { proto.RegisterFile("crypto.proto", fileDescriptor_527278fb02d03321) } - -var fileDescriptor_527278fb02d03321 = []byte{ - // 203 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x49, 0x2e, 0xaa, 0x2c, - 0x28, 0xc9, 0xd7, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x84, 0xf1, 0x92, 0x94, 0x82, 0xb9, - 0x38, 0x03, 0x4a, 0x93, 0x72, 0x32, 0x93, 0xbd, 0x53, 0x2b, 0x85, 0x74, 0xb8, 0x58, 0x42, 0x2a, - 0x0b, 0x52, 0x25, 0x18, 0x15, 0x98, 0x34, 0xf8, 0x8c, 0x84, 0xf4, 0xe0, 0xca, 0xf4, 0xbc, 0x53, - 0x2b, 0x41, 0x32, 0x4e, 0x2c, 0x27, 0xee, 0xc9, 0x33, 0x04, 0x81, 0x55, 0x09, 0x49, 0x70, 0xb1, - 0xb8, 0x24, 0x96, 0x24, 0x4a, 0x30, 0x29, 0x30, 0x69, 0xf0, 0xc0, 0x64, 0x40, 0x22, 0x4a, 0x21, - 0x5c, 0x5c, 0x01, 0x45, 0x99, 0x65, 0x89, 0x25, 0xa9, 0x54, 0x34, 0x55, 0xcb, 0x92, 0x8b, 0x1d, - 0xaa, 0x41, 0x88, 0x9d, 0x8b, 0x39, 0x28, 0xd8, 0x51, 0x80, 0x41, 0x88, 0x9b, 0x8b, 0xdd, 0x35, - 0xc5, 0xc8, 0xd4, 0xd4, 0xd0, 0x52, 0x80, 0x51, 0x88, 0x97, 0x8b, 0x33, 0x38, 0x35, 0xb9, 0xc0, - 0xc8, 0xd4, 0x2c, 0xdb, 0x50, 0x80, 0x49, 0x88, 0x93, 0x8b, 0xd5, 0xd5, 0xd9, 0x25, 0xd8, 0x51, - 0x80, 0xd9, 0x49, 0xe2, 0xc4, 0x23, 0x39, 0xc6, 0x0b, 0x8f, 0xe4, 0x18, 0x1f, 0x3c, 0x92, 0x63, - 0x9c, 0xf0, 0x58, 0x8e, 0xe1, 0xc2, 0x63, 0x39, 0x86, 0x1b, 0x8f, 0xe5, 0x18, 0x00, 0x01, 0x00, - 0x00, 0xff, 0xff, 0x13, 0xbe, 0xd4, 0xff, 0x19, 0x01, 0x00, 0x00, -} - -func (m *PublicKey) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *PublicKey) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0x8 - i++ - i = encodeVarintCrypto(dAtA, i, uint64(m.Type)) - if m.Data != nil { - dAtA[i] = 0x12 - i++ - i = encodeVarintCrypto(dAtA, i, uint64(len(m.Data))) - i += copy(dAtA[i:], m.Data) - } - return i, nil -} - -func (m *PrivateKey) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *PrivateKey) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - dAtA[i] = 0x8 - i++ - i = encodeVarintCrypto(dAtA, i, uint64(m.Type)) - if m.Data != nil { - dAtA[i] = 0x12 - i++ - i = encodeVarintCrypto(dAtA, i, uint64(len(m.Data))) - i += copy(dAtA[i:], m.Data) - } - return i, nil -} - -func encodeVarintCrypto(dAtA []byte, offset int, v uint64) int { - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return offset + 1 -} -func (m *PublicKey) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - n += 1 + sovCrypto(uint64(m.Type)) - if m.Data != nil { - l = len(m.Data) - n += 1 + l + sovCrypto(uint64(l)) - } - return n -} - -func (m *PrivateKey) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - n += 1 + sovCrypto(uint64(m.Type)) - if m.Data != nil { - l = len(m.Data) - n += 1 + l + sovCrypto(uint64(l)) - } - return n -} - -func sovCrypto(x uint64) (n int) { - for { - n++ - x >>= 7 - if x == 0 { - break - } - } - return n -} -func sozCrypto(x uint64) (n int) { - return sovCrypto(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (m *PublicKey) Unmarshal(dAtA []byte) error { - var hasFields [1]uint64 - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCrypto - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: PublicKey: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: PublicKey: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) - } - m.Type = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCrypto - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Type |= KeyType(b&0x7F) << shift - if b < 0x80 { - break - } - } - hasFields[0] |= uint64(0x00000001) - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCrypto - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthCrypto - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthCrypto - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) - if m.Data == nil { - m.Data = []byte{} - } - iNdEx = postIndex - hasFields[0] |= uint64(0x00000002) - default: - iNdEx = preIndex - skippy, err := skipCrypto(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthCrypto - } - if (iNdEx + skippy) < 0 { - return ErrInvalidLengthCrypto - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - if hasFields[0]&uint64(0x00000001) == 0 { - return github_com_gogo_protobuf_proto.NewRequiredNotSetError("Type") - } - if hasFields[0]&uint64(0x00000002) == 0 { - return github_com_gogo_protobuf_proto.NewRequiredNotSetError("Data") - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *PrivateKey) Unmarshal(dAtA []byte) error { - var hasFields [1]uint64 - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCrypto - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: PrivateKey: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: PrivateKey: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) - } - m.Type = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCrypto - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Type |= KeyType(b&0x7F) << shift - if b < 0x80 { - break - } - } - hasFields[0] |= uint64(0x00000001) - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCrypto - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthCrypto - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthCrypto - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) - if m.Data == nil { - m.Data = []byte{} - } - iNdEx = postIndex - hasFields[0] |= uint64(0x00000002) - default: - iNdEx = preIndex - skippy, err := skipCrypto(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthCrypto - } - if (iNdEx + skippy) < 0 { - return ErrInvalidLengthCrypto - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - if hasFields[0]&uint64(0x00000001) == 0 { - return github_com_gogo_protobuf_proto.NewRequiredNotSetError("Type") - } - if hasFields[0]&uint64(0x00000002) == 0 { - return github_com_gogo_protobuf_proto.NewRequiredNotSetError("Data") - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipCrypto(dAtA []byte) (n int, err error) { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowCrypto - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowCrypto - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - iNdEx++ - if dAtA[iNdEx-1] < 0x80 { - break - } - } - return iNdEx, nil - case 1: - iNdEx += 8 - return iNdEx, nil - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowCrypto - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if length < 0 { - return 0, ErrInvalidLengthCrypto - } - iNdEx += length - if iNdEx < 0 { - return 0, ErrInvalidLengthCrypto - } - return iNdEx, nil - case 3: - for { - var innerWire uint64 - var start int = iNdEx - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowCrypto - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - innerWire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - innerWireType := int(innerWire & 0x7) - if innerWireType == 4 { - break - } - next, err := skipCrypto(dAtA[start:]) - if err != nil { - return 0, err - } - iNdEx = start + next - if iNdEx < 0 { - return 0, ErrInvalidLengthCrypto - } - } - return iNdEx, nil - case 4: - return iNdEx, nil - case 5: - iNdEx += 4 - return iNdEx, nil - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - } - panic("unreachable") -} - -var ( - ErrInvalidLengthCrypto = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowCrypto = fmt.Errorf("proto: integer overflow") -) diff --git a/pb/crypto.proto b/pb/crypto.proto deleted file mode 100644 index cb5cee8..0000000 --- a/pb/crypto.proto +++ /dev/null @@ -1,20 +0,0 @@ -syntax = "proto2"; - -package crypto.pb; - -enum KeyType { - RSA = 0; - Ed25519 = 1; - Secp256k1 = 2; - ECDSA = 3; -} - -message PublicKey { - required KeyType Type = 1; - required bytes Data = 2; -} - -message PrivateKey { - required KeyType Type = 1; - required bytes Data = 2; -} diff --git a/pb/deprecated.go b/pb/deprecated.go new file mode 100644 index 0000000..6b2f14b --- /dev/null +++ b/pb/deprecated.go @@ -0,0 +1,37 @@ +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto/pb instead. +package crypto_pb + +import core "github.com/libp2p/go-libp2p-core/crypto/pb" + +const ( + // Deprecated: use github.com/libp2p/go-libp2p-core/crypto/pb.KeyType_RSA instead. + KeyType_RSA = core.KeyType_RSA + // Deprecated: use github.com/libp2p/go-libp2p-core/crypto/pb.KeyType_Ed25519 instead. + KeyType_Ed25519 = core.KeyType_Ed25519 + // Deprecated: use github.com/libp2p/go-libp2p-core/crypto/pb.KeyType_Secp256k1 instead. + KeyType_Secp256k1 = core.KeyType_Secp256k1 + // Deprecated: use github.com/libp2p/go-libp2p-core/crypto/pb.KeyType_ECDSA instead. + KeyType_ECDSA = core.KeyType_ECDSA +) + +var ( + // Deprecated: use github.com/libp2p/go-libp2p-core/crypto/pb.ErrInvalidLengthCrypto instead. + ErrInvalidLengthCrypto = core.ErrInvalidLengthCrypto + // Deprecated: use github.com/libp2p/go-libp2p-core/crypto/pb.ErrIntOverflowCrypto instead. + ErrIntOverflowCrypto = core.ErrIntOverflowCrypto +) + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto/pb.KeyType_name instead. +var KeyType_name = core.KeyType_name + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto/pb.KeyType_value instead. +var KeyType_value = core.KeyType_value + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto/pb.KeyType instead. +type KeyType = core.KeyType + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto/pb.PublicKey instead. +type PublicKey = core.PublicKey + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto/pb.PrivateKey instead. +type PrivateKey = core.PrivateKey diff --git a/rsa_common.go b/rsa_common.go deleted file mode 100644 index d50651f..0000000 --- a/rsa_common.go +++ /dev/null @@ -1,10 +0,0 @@ -package crypto - -import ( - "errors" -) - -// ErrRsaKeyTooSmall is returned when trying to generate or parse an RSA key -// that's smaller than 512 bits. Keys need to be larger enough to sign a 256bit -// hash so this is a reasonable absolute minimum. -var ErrRsaKeyTooSmall = errors.New("rsa keys must be >= 512 bits to be useful") diff --git a/rsa_deprecated.go b/rsa_deprecated.go new file mode 100644 index 0000000..8c3e4c4 --- /dev/null +++ b/rsa_deprecated.go @@ -0,0 +1,31 @@ +package crypto + +import ( + "io" + + core "github.com/libp2p/go-libp2p-core/crypto" +) + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.ErrRsaKeyTooSmall instead. +var ErrRsaKeyTooSmall = core.ErrRsaKeyTooSmall + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.RsaPrivateKey instead. +type RsaPrivateKey = core.RsaPrivateKey + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.RsaPublicKey instead. +type RsaPublicKey = core.RsaPublicKey + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.GenerateRSAKeyPair instead. +func GenerateRSAKeyPair(bits int, src io.Reader) (PrivKey, PubKey, error) { + return core.GenerateRSAKeyPair(bits, src) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.UnmarshalRsaPrivateKey instead. +func UnmarshalRsaPrivateKey(b []byte) (PrivKey, error) { + return core.UnmarshalRsaPrivateKey(b) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.UnmarshalRsaPublicKey instead. +func UnmarshalRsaPublicKey(b []byte) (PubKey, error) { + return core.UnmarshalRsaPublicKey(b) +} diff --git a/rsa_go.go b/rsa_go.go deleted file mode 100644 index 07905e4..0000000 --- a/rsa_go.go +++ /dev/null @@ -1,125 +0,0 @@ -// +build !openssl - -package crypto - -import ( - "crypto" - "crypto/rand" - "crypto/rsa" - "crypto/x509" - "errors" - "io" - - pb "github.com/libp2p/go-libp2p-crypto/pb" - - sha256 "github.com/minio/sha256-simd" -) - -// RsaPrivateKey is an rsa private key -type RsaPrivateKey struct { - sk rsa.PrivateKey -} - -// RsaPublicKey is an rsa public key -type RsaPublicKey struct { - k rsa.PublicKey -} - -// GenerateRSAKeyPair generates a new rsa private and public key -func GenerateRSAKeyPair(bits int, src io.Reader) (PrivKey, PubKey, error) { - if bits < 512 { - return nil, nil, ErrRsaKeyTooSmall - } - priv, err := rsa.GenerateKey(src, bits) - if err != nil { - return nil, nil, err - } - pk := priv.PublicKey - return &RsaPrivateKey{sk: *priv}, &RsaPublicKey{pk}, nil -} - -// Verify compares a signature against input data -func (pk *RsaPublicKey) Verify(data, sig []byte) (bool, error) { - hashed := sha256.Sum256(data) - err := rsa.VerifyPKCS1v15(&pk.k, crypto.SHA256, hashed[:], sig) - if err != nil { - return false, err - } - return true, nil -} - -func (pk *RsaPublicKey) Type() pb.KeyType { - return pb.KeyType_RSA -} - -// Bytes returns protobuf bytes of a public key -func (pk *RsaPublicKey) Bytes() ([]byte, error) { - return MarshalPublicKey(pk) -} - -func (pk *RsaPublicKey) Raw() ([]byte, error) { - return x509.MarshalPKIXPublicKey(&pk.k) -} - -// Equals checks whether this key is equal to another -func (pk *RsaPublicKey) Equals(k Key) bool { - return KeyEqual(pk, k) -} - -// Sign returns a signature of the input data -func (sk *RsaPrivateKey) Sign(message []byte) ([]byte, error) { - hashed := sha256.Sum256(message) - return rsa.SignPKCS1v15(rand.Reader, &sk.sk, crypto.SHA256, hashed[:]) -} - -// GetPublic returns a public key -func (sk *RsaPrivateKey) GetPublic() PubKey { - return &RsaPublicKey{sk.sk.PublicKey} -} - -func (sk *RsaPrivateKey) Type() pb.KeyType { - return pb.KeyType_RSA -} - -// Bytes returns protobuf bytes from a private key -func (sk *RsaPrivateKey) Bytes() ([]byte, error) { - return MarshalPrivateKey(sk) -} - -func (sk *RsaPrivateKey) Raw() ([]byte, error) { - b := x509.MarshalPKCS1PrivateKey(&sk.sk) - return b, nil -} - -// Equals checks whether this key is equal to another -func (sk *RsaPrivateKey) Equals(k Key) bool { - return KeyEqual(sk, k) -} - -// UnmarshalRsaPrivateKey returns a private key from the input x509 bytes -func UnmarshalRsaPrivateKey(b []byte) (PrivKey, error) { - sk, err := x509.ParsePKCS1PrivateKey(b) - if err != nil { - return nil, err - } - if sk.N.BitLen() < 512 { - return nil, ErrRsaKeyTooSmall - } - return &RsaPrivateKey{sk: *sk}, nil -} - -// UnmarshalRsaPublicKey returns a public key from the input x509 bytes -func UnmarshalRsaPublicKey(b []byte) (PubKey, error) { - pub, err := x509.ParsePKIXPublicKey(b) - if err != nil { - return nil, err - } - pk, ok := pub.(*rsa.PublicKey) - if !ok { - return nil, errors.New("not actually an rsa public key") - } - if pk.N.BitLen() < 512 { - return nil, ErrRsaKeyTooSmall - } - return &RsaPublicKey{*pk}, nil -} diff --git a/rsa_openssl.go b/rsa_openssl.go deleted file mode 100644 index 96c5588..0000000 --- a/rsa_openssl.go +++ /dev/null @@ -1,62 +0,0 @@ -// +build openssl - -package crypto - -import ( - "errors" - "io" - - openssl "github.com/spacemonkeygo/openssl" -) - -// RsaPrivateKey is an rsa private key -type RsaPrivateKey struct { - opensslPrivateKey -} - -// RsaPublicKey is an rsa public key -type RsaPublicKey struct { - opensslPublicKey -} - -// GenerateRSAKeyPair generates a new rsa private and public key -func GenerateRSAKeyPair(bits int, _ io.Reader) (PrivKey, PubKey, error) { - if bits < 512 { - return nil, nil, ErrRsaKeyTooSmall - } - - key, err := openssl.GenerateRSAKey(bits) - if err != nil { - return nil, nil, err - } - return &RsaPrivateKey{opensslPrivateKey{key}}, &RsaPublicKey{opensslPublicKey{key}}, nil -} - -// GetPublic returns a public key -func (sk *RsaPrivateKey) GetPublic() PubKey { - return &RsaPublicKey{opensslPublicKey{sk.opensslPrivateKey.key}} -} - -// UnmarshalRsaPrivateKey returns a private key from the input x509 bytes -func UnmarshalRsaPrivateKey(b []byte) (PrivKey, error) { - key, err := unmarshalOpensslPrivateKey(b) - if err != nil { - return nil, err - } - if key.Type() != RSA { - return nil, errors.New("not actually an rsa public key") - } - return &RsaPrivateKey{key}, nil -} - -// UnmarshalRsaPublicKey returns a public key from the input x509 bytes -func UnmarshalRsaPublicKey(b []byte) (PubKey, error) { - key, err := unmarshalOpensslPublicKey(b) - if err != nil { - return nil, err - } - if key.Type() != RSA { - return nil, errors.New("not actually an rsa public key") - } - return &RsaPublicKey{key}, nil -} diff --git a/rsa_test.go b/rsa_test.go deleted file mode 100644 index 7ee520a..0000000 --- a/rsa_test.go +++ /dev/null @@ -1,102 +0,0 @@ -package crypto - -import ( - "crypto/rand" - "testing" -) - -func TestRSABasicSignAndVerify(t *testing.T) { - priv, pub, err := GenerateRSAKeyPair(512, rand.Reader) - if err != nil { - t.Fatal(err) - } - - data := []byte("hello! and welcome to some awesome crypto primitives") - - sig, err := priv.Sign(data) - if err != nil { - t.Fatal(err) - } - - ok, err := pub.Verify(data, sig) - if err != nil { - t.Fatal(err) - } - - if !ok { - t.Fatal("signature didnt match") - } - - // change data - data[0] = ^data[0] - ok, err = pub.Verify(data, sig) - if err == nil { - t.Fatal("should have produced a verification error") - } - - if ok { - t.Fatal("signature matched and shouldn't") - } -} - -func TestRSASmallKey(t *testing.T) { - _, _, err := GenerateRSAKeyPair(384, rand.Reader) - if err != ErrRsaKeyTooSmall { - t.Fatal("should have refused to create small RSA key") - } -} - -func TestRSASignZero(t *testing.T) { - priv, pub, err := GenerateRSAKeyPair(512, rand.Reader) - if err != nil { - t.Fatal(err) - } - - data := make([]byte, 0) - sig, err := priv.Sign(data) - if err != nil { - t.Fatal(err) - } - - ok, err := pub.Verify(data, sig) - if err != nil { - t.Fatal(err) - } - if !ok { - t.Fatal("signature didn't match") - } -} - -func TestRSAMarshalLoop(t *testing.T) { - priv, pub, err := GenerateRSAKeyPair(512, rand.Reader) - if err != nil { - t.Fatal(err) - } - - privB, err := priv.Bytes() - if err != nil { - t.Fatal(err) - } - - privNew, err := UnmarshalPrivateKey(privB) - if err != nil { - t.Fatal(err) - } - - if !priv.Equals(privNew) || !privNew.Equals(priv) { - t.Fatal("keys are not equal") - } - - pubB, err := pub.Bytes() - if err != nil { - t.Fatal(err) - } - pubNew, err := UnmarshalPublicKey(pubB) - if err != nil { - t.Fatal(err) - } - - if !pub.Equals(pubNew) || !pubNew.Equals(pub) { - t.Fatal("keys are not equal") - } -} diff --git a/secp256k1.go b/secp256k1.go deleted file mode 100644 index 8bca33e..0000000 --- a/secp256k1.go +++ /dev/null @@ -1,125 +0,0 @@ -package crypto - -import ( - "fmt" - "io" - - pb "github.com/libp2p/go-libp2p-crypto/pb" - - btcec "github.com/btcsuite/btcd/btcec" - sha256 "github.com/minio/sha256-simd" -) - -// Secp256k1PrivateKey is an Secp256k1 private key -type Secp256k1PrivateKey btcec.PrivateKey - -// Secp256k1PublicKey is an Secp256k1 public key -type Secp256k1PublicKey btcec.PublicKey - -// GenerateSecp256k1Key generates a new Secp256k1 private and public key pair -func GenerateSecp256k1Key(src io.Reader) (PrivKey, PubKey, error) { - privk, err := btcec.NewPrivateKey(btcec.S256()) - if err != nil { - return nil, nil, err - } - - k := (*Secp256k1PrivateKey)(privk) - return k, k.GetPublic(), nil -} - -// UnmarshalSecp256k1PrivateKey returns a private key from bytes -func UnmarshalSecp256k1PrivateKey(data []byte) (PrivKey, error) { - if len(data) != btcec.PrivKeyBytesLen { - return nil, fmt.Errorf("expected secp256k1 data size to be %d", btcec.PrivKeyBytesLen) - } - - privk, _ := btcec.PrivKeyFromBytes(btcec.S256(), data) - return (*Secp256k1PrivateKey)(privk), nil -} - -// UnmarshalSecp256k1PublicKey returns a public key from bytes -func UnmarshalSecp256k1PublicKey(data []byte) (PubKey, error) { - k, err := btcec.ParsePubKey(data, btcec.S256()) - if err != nil { - return nil, err - } - - return (*Secp256k1PublicKey)(k), nil -} - -// Bytes returns protobuf bytes from a private key -func (k *Secp256k1PrivateKey) Bytes() ([]byte, error) { - return MarshalPrivateKey(k) -} - -// Type returns the private key type -func (k *Secp256k1PrivateKey) Type() pb.KeyType { - return pb.KeyType_Secp256k1 -} - -// Raw returns the bytes of the key -func (k *Secp256k1PrivateKey) Raw() ([]byte, error) { - return (*btcec.PrivateKey)(k).Serialize(), nil -} - -// Equals compares two private keys -func (k *Secp256k1PrivateKey) Equals(o Key) bool { - sk, ok := o.(*Secp256k1PrivateKey) - if !ok { - return false - } - - return k.D.Cmp(sk.D) == 0 -} - -// Sign returns a signature from input data -func (k *Secp256k1PrivateKey) Sign(data []byte) ([]byte, error) { - hash := sha256.Sum256(data) - sig, err := (*btcec.PrivateKey)(k).Sign(hash[:]) - if err != nil { - return nil, err - } - - return sig.Serialize(), nil -} - -// GetPublic returns a public key -func (k *Secp256k1PrivateKey) GetPublic() PubKey { - return (*Secp256k1PublicKey)((*btcec.PrivateKey)(k).PubKey()) -} - -// Bytes returns protobuf bytes from a public key -func (k *Secp256k1PublicKey) Bytes() ([]byte, error) { - return MarshalPublicKey(k) -} - -// Type returns the public key type -func (k *Secp256k1PublicKey) Type() pb.KeyType { - return pb.KeyType_Secp256k1 -} - -// Raw returns the bytes of the key -func (k *Secp256k1PublicKey) Raw() ([]byte, error) { - return (*btcec.PublicKey)(k).SerializeCompressed(), nil -} - -// Equals compares two public keys -func (k *Secp256k1PublicKey) Equals(o Key) bool { - sk, ok := o.(*Secp256k1PublicKey) - if !ok { - return false - } - - return (*btcec.PublicKey)(k).IsEqual((*btcec.PublicKey)(sk)) -} - -// Verify compares a signature against the input data -func (k *Secp256k1PublicKey) Verify(data []byte, sigStr []byte) (bool, error) { - sig, err := btcec.ParseDERSignature(sigStr, btcec.S256()) - if err != nil { - return false, err - } - - hash := sha256.Sum256(data) - return sig.Verify(hash[:], (*btcec.PublicKey)(k)), nil -} diff --git a/secp256k1_deprecated.go b/secp256k1_deprecated.go new file mode 100644 index 0000000..741321c --- /dev/null +++ b/secp256k1_deprecated.go @@ -0,0 +1,28 @@ +package crypto + +import ( + "io" + + core "github.com/libp2p/go-libp2p-core/crypto" +) + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.Secp256k1PrivateKey instead. +type Secp256k1PrivateKey = core.Secp256k1PrivateKey + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.Secp256k1PublicKey instead. +type Secp256k1PublicKey = core.Secp256k1PublicKey + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.GenerateSecp256k1Key instead. +func GenerateSecp256k1Key(src io.Reader) (PrivKey, PubKey, error) { + return core.GenerateSecp256k1Key(src) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.UnmarshalSecp256k1PrivateKey instead. +func UnmarshalSecp256k1PrivateKey(data []byte) (PrivKey, error) { + return core.UnmarshalSecp256k1PrivateKey(data) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/crypto.UnmarshalSecp256k1PublicKey instead. +func UnmarshalSecp256k1PublicKey(data []byte) (PubKey, error) { + return core.UnmarshalSecp256k1PublicKey(data) +} diff --git a/secp256k1_test.go b/secp256k1_test.go deleted file mode 100644 index aff2bd9..0000000 --- a/secp256k1_test.go +++ /dev/null @@ -1,96 +0,0 @@ -package crypto - -import ( - "crypto/rand" - "testing" -) - -func TestSecp256k1BasicSignAndVerify(t *testing.T) { - priv, pub, err := GenerateSecp256k1Key(rand.Reader) - if err != nil { - t.Fatal(err) - } - - data := []byte("hello! and welcome to some awesome crypto primitives") - - sig, err := priv.Sign(data) - if err != nil { - t.Fatal(err) - } - - ok, err := pub.Verify(data, sig) - if err != nil { - t.Fatal(err) - } - - if !ok { - t.Fatal("signature didnt match") - } - - // change data - data[0] = ^data[0] - ok, err = pub.Verify(data, sig) - if err != nil { - t.Fatal(err) - } - - if ok { - t.Fatal("signature matched and shouldn't") - } -} - -func TestSecp256k1SignZero(t *testing.T) { - priv, pub, err := GenerateSecp256k1Key(rand.Reader) - if err != nil { - t.Fatal(err) - } - - data := make([]byte, 0) - sig, err := priv.Sign(data) - if err != nil { - t.Fatal(err) - } - - ok, err := pub.Verify(data, sig) - if err != nil { - t.Fatal(err) - } - if !ok { - t.Fatal("signature didn't match") - } -} - -func TestSecp256k1MarshalLoop(t *testing.T) { - priv, pub, err := GenerateSecp256k1Key(rand.Reader) - if err != nil { - t.Fatal(err) - } - - privB, err := priv.Bytes() - if err != nil { - t.Fatal(err) - } - - privNew, err := UnmarshalPrivateKey(privB) - if err != nil { - t.Fatal(err) - } - - if !priv.Equals(privNew) || !privNew.Equals(priv) { - t.Fatal("keys are not equal") - } - - pubB, err := pub.Bytes() - if err != nil { - t.Fatal(err) - } - pubNew, err := UnmarshalPublicKey(pubB) - if err != nil { - t.Fatal(err) - } - - if !pub.Equals(pubNew) || !pubNew.Equals(pub) { - t.Fatal("keys are not equal") - } - -} diff --git a/test/deprecated.go b/test/deprecated.go new file mode 100644 index 0000000..9951d90 --- /dev/null +++ b/test/deprecated.go @@ -0,0 +1,17 @@ +// Deprecated: use github.com/libp2p/go-libp2p-core/test instead. +package testutil + +import ( + "github.com/libp2p/go-libp2p-core/test" + ci "github.com/libp2p/go-libp2p-crypto" +) + +// Deprecated: use github.com/libp2p/go-libp2p-core/test.RandTestKeyPair instead. +func RandTestKeyPair(typ, bits int) (ci.PrivKey, ci.PubKey, error) { + return test.RandTestKeyPair(typ, bits) +} + +// Deprecated: use github.com/libp2p/go-libp2p-core/test.SeededTestKeyPair instead. +func SeededTestKeyPair(typ, bits int, seed int64) (ci.PrivKey, ci.PubKey, error) { + return test.SeededTestKeyPair(typ, bits, seed) +} diff --git a/test/utils.go b/test/utils.go deleted file mode 100644 index f1c1f98..0000000 --- a/test/utils.go +++ /dev/null @@ -1,17 +0,0 @@ -package testutil - -import ( - "math/rand" - "time" - - ci "github.com/libp2p/go-libp2p-crypto" -) - -func RandTestKeyPair(typ, bits int) (ci.PrivKey, ci.PubKey, error) { - return SeededTestKeyPair(typ, bits, time.Now().UnixNano()) -} - -func SeededTestKeyPair(typ, bits int, seed int64) (ci.PrivKey, ci.PubKey, error) { - r := rand.New(rand.NewSource(seed)) - return ci.GenerateKeyPairWithReader(typ, bits, r) -} diff --git a/test_data/0.priv b/test_data/0.priv deleted file mode 100644 index 9047d5d95da8d54887fe5983a9e9e4d9017db511..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1198 zcmV;f1X24401~MQFoFc70s#O5f&l>l^0!+-j417TtNs`14f~V9KQ6{N9S1LlFSl3- zxoskT?;wNIA4+%zpM|YzjB|-@qlKe}Lk%3jnvkL}@Cgx7Tva&4wk?T&#%13TP(^C& zblGnC8FJR5NY;c!Jmu5l>)EGR6zp4aTeyfT1bw@%01DWOQZ`v?*Z{=L`s2qRA`{(D+=J7bt9;Dl zpJn3S=f`Z9vc=bs>`u1XRH|+irBq{Op5F>36Tqt3 zxHO+7nwwx-J#pT|J8AA~=uxLr0s{d60Rn;n08<2nA{Sn$Tb&qt^(x~r)|XY-R=F1p z8cCPjbf0&`q{aow5gk&?TKJVPi;*6)lQcUqgKEpcS>J>>^`sNb1S!5D=t6zl+7Rjk( zYND*U&2#Orgq!XHhDWt_;Vy)`iN%bETqDILV3#64n=yFRX69Il((zQS%1r(3 z)4oWbyKgSs{ei4Z!~Ts4+wm2T4T+xXbdCOFmlHiz62dqzSNXWIX=IxZZo9&52Y=nS z=;brvC%D1OT7a&--qVUd3I7ICl5l!y~fO`9SQvI zg0!T(6}2&dnA<`tw3f#7Xv^Z)CuNy-gBhV2EM8c8(H8t9u>GvwtXD2&atS%P*mt)6rro&N1R{dFHK#nb=*x z{{n%50Q|R!9!0VLp_YTv$s^t&jkINb*awC$09>!A_9$@`(foFoJ`iQ~xu^|I#UJ`3 zGvM(GL}#tQ@$6^i#37j}X?vvC`xdB(J_etSi2q0V>|$+4v23lY8z3)%C4dUMiX2c9 z>_jsMG{PR^#%&IMJ&beVhD4@r$Fv=p4uX!wtpb680OZB?3gY~S@sW&OrCjG)vcjw6 zA9WA74nA+0;>h|6qA)?-(B}%Um|{Ka+-R8Q!40$QY;a8b+FAl;W<+Y^#=1Ff0xq1w zl80+cuNpj!0_8lJtH8a%dd(P2z@IXPOdS50Z>T-7g$x1os%GPZ;M>mc?Q~TzUX$(6>} zBM$@ESv#mV9%E*+CMQQ1RsuSdGWk(THG!nd?0@KmdrcNaICJ;pFslnqP`uf?`rITK z$k`a24#2p(+~*Y&bS0si0dhd@uO;#2D)eIn_jca(xdMTK0Ib$_%b!(+j$2`MrZO8* zK0VVe#NRZ66g;0%>I1jW4sv-NuP46&Xiyr|N*J&>_rbgur@oH$9`#uJs%zkUQ%aHfT;!I2{KshA+2R2)S({e(xZI(;rHB2A_qkYK(JY;z?zVv zFz^WxQCw9x#I`Mof5v6s5l}^H>~+nuF${?E2b_ZSYI!$YdF1#&@aq*JKN)h?qDa<+ zMLgxxdIw-?GKm xknB#j*;J}-6s1&SWuD&(B@@7^*|;>HC7PRHTRm~!#5-y3Yv@s@Qvw4400F=}h;aY_ diff --git a/test_data/0.sig b/test_data/0.sig deleted file mode 100644 index 2f16825274520604c4d67c5dc4a1efd11c4cb5a0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 256 zcmV+b0ssDP5fdf%5Un{zGtbk0Mt&H@6Mwcn7%ZEPqeF&re1kDy+yM>l5^mzU^EDO! zS%)zD!_$Fo#oNXv__1;bLna{ikzc+WZd%SDZ9ln;Ka<+9=)s>16_V{NiZx5j)4 zz$b0Y=dnKD diff --git a/test_data/2.priv b/test_data/2.priv deleted file mode 100644 index 1004ab9..0000000 --- a/test_data/2.priv +++ /dev/null @@ -1 +0,0 @@ - 1A`jPLD4N[-XFX \ No newline at end of file diff --git a/test_data/2.pub b/test_data/2.pub deleted file mode 100644 index dd984bd..0000000 --- a/test_data/2.pub +++ /dev/null @@ -1 +0,0 @@ -!5@*5QMU&PkS֢ \ No newline at end of file diff --git a/test_data/2.sig b/test_data/2.sig deleted file mode 100644 index b96001b..0000000 --- a/test_data/2.sig +++ /dev/null @@ -1 +0,0 @@ -0D 13ZCuܛ@L I!EGuCꏲpCG5I<@;Y \ No newline at end of file diff --git a/test_data/3.priv b/test_data/3.priv deleted file mode 100644 index 7a05f359f803dfd03a776c8648e43dd501f55fe0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 125 zcmV-@0D}Jr0}^>KcLD(c1Rx*4R7vBbLOZy%lt-jIJ|nF_m8?&nyLCl+&htxXl%Jpq z1_&yKNX|V20SBQ(13~}<;+lqZ^I=X5%W^<#{vkK%_{I0uEfaqVF5M$OH8)3h{U4g` fO)UCzamug8?*iL{xF2`V;k?+#6|C^NqIZs|4V^dR diff --git a/test_data/3.pub b/test_data/3.pub deleted file mode 100644 index f4551f8811180cad4e160e2db6dfd675c774cb69..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 95 zcmd;J7K%2AG!SNE*J|@PXUoLM#sOw9GqN)~F|a(E)mHL3(U0eJkwf-BMe~-_MYi>^A7p)^AGpjI4-*8!_GzJeJcS7%qWZi diff --git a/test_data/3.sig b/test_data/3.sig deleted file mode 100644 index 253c09f6d7b2bd30be7d49abbda27ea1bfd01043..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 72 zcmV-O0Jr}zMgk!KglcAmx#ufZ46^)6b@|J~ijb=6r}Oe&=NW@7x4AlH0wDm+nJc%w eE6gaz+XR?>5Us?J{xpJcl}~n-%MJhk4g5X!9waUR