X, Y *big.Int
}
+// Any methods implemented on PublicKey might need to also be implemented on
+// PrivateKey, as the latter embeds the former and will expose its methods.
+
// Equal reports whether pub and x have the same value.
//
// Two keys are only considered to have the same value if they have the same Curve value.
return &priv.PublicKey
}
+// Equal reports whether priv and x have the same value.
+//
+// See PublicKey.Equal for details on how Curve is compared.
+func (priv *PrivateKey) Equal(x crypto.PrivateKey) bool {
+ xx, ok := x.(*PrivateKey)
+ if !ok {
+ return false
+ }
+ return priv.PublicKey.Equal(&xx.PublicKey) && priv.D.Cmp(xx.D) == 0
+}
+
// Sign signs digest with priv, reading randomness from rand. The opts argument
// is not currently used but, in keeping with the crypto.Signer interface,
// should be the hash function used to digest the message.
if !public.Equal(crypto.Signer(private).Public().(*ecdsa.PublicKey)) {
t.Errorf("private.Public() is not Equal to public: %q", public)
}
+ if !private.Equal(private) {
+ t.Errorf("private key is not equal to itself: %v", private)
+ }
- enc, err := x509.MarshalPKIXPublicKey(public)
+ enc, err := x509.MarshalPKCS8PrivateKey(private)
if err != nil {
t.Fatal(err)
}
- decoded, err := x509.ParsePKIXPublicKey(enc)
+ decoded, err := x509.ParsePKCS8PrivateKey(enc)
if err != nil {
t.Fatal(err)
}
- if !public.Equal(decoded) {
+ if !public.Equal(decoded.(crypto.Signer).Public()) {
t.Errorf("public key is not equal to itself after decoding: %v", public)
}
+ if !private.Equal(decoded) {
+ t.Errorf("private key is not equal to itself after decoding: %v", private)
+ }
other, _ := ecdsa.GenerateKey(c, rand.Reader)
- if public.Equal(other) {
+ if public.Equal(other.Public()) {
t.Errorf("different public keys are Equal")
}
+ if private.Equal(other) {
+ t.Errorf("different private keys are Equal")
+ }
// Ensure that keys with the same coordinates but on different curves
// aren't considered Equal.
// PublicKey is the type of Ed25519 public keys.
type PublicKey []byte
+// Any methods implemented on PublicKey might need to also be implemented on
+// PrivateKey, as the latter embeds the former and will expose its methods.
+
// Equal reports whether pub and x have the same value.
func (pub PublicKey) Equal(x crypto.PublicKey) bool {
xx, ok := x.(PublicKey)
return PublicKey(publicKey)
}
+// Equal reports whether priv and x have the same value.
+func (priv PrivateKey) Equal(x crypto.PrivateKey) bool {
+ xx, ok := x.(PrivateKey)
+ if !ok {
+ return false
+ }
+ return bytes.Equal(priv, xx)
+}
+
// Seed returns the private key seed corresponding to priv. It is provided for
// interoperability with RFC 8032. RFC 8032's private keys correspond to seeds
// in this package.
if !public.Equal(public) {
t.Errorf("public key is not equal to itself: %q", public)
}
- if !public.Equal(crypto.Signer(private).Public().(PublicKey)) {
+ if !public.Equal(crypto.Signer(private).Public()) {
t.Errorf("private.Public() is not Equal to public: %q", public)
}
+ if !private.Equal(private) {
+ t.Errorf("private key is not equal to itself: %q", private)
+ }
- other, _, _ := GenerateKey(rand.Reader)
- if public.Equal(other) {
+ otherPub, otherPriv, _ := GenerateKey(rand.Reader)
+ if public.Equal(otherPub) {
t.Errorf("different public keys are Equal")
}
+ if private.Equal(otherPriv) {
+ t.Errorf("different private keys are Equal")
+ }
}
func TestGolden(t *testing.T) {
if !public.Equal(crypto.Signer(private).Public().(*rsa.PublicKey)) {
t.Errorf("private.Public() is not Equal to public: %q", public)
}
+ if !private.Equal(private) {
+ t.Errorf("private key is not equal to itself: %v", private)
+ }
- enc, err := x509.MarshalPKIXPublicKey(public)
+ enc, err := x509.MarshalPKCS8PrivateKey(private)
if err != nil {
t.Fatal(err)
}
- decoded, err := x509.ParsePKIXPublicKey(enc)
+ decoded, err := x509.ParsePKCS8PrivateKey(enc)
if err != nil {
t.Fatal(err)
}
- if !public.Equal(decoded) {
+ if !public.Equal(decoded.(crypto.Signer).Public()) {
t.Errorf("public key is not equal to itself after decoding: %v", public)
}
+ if !private.Equal(decoded) {
+ t.Errorf("private key is not equal to itself after decoding: %v", private)
+ }
other, _ := rsa.GenerateKey(rand.Reader, 512)
- if public.Equal(other) {
+ if public.Equal(other.Public()) {
t.Errorf("different public keys are Equal")
}
+ if private.Equal(other) {
+ t.Errorf("different private keys are Equal")
+ }
}
E int // public exponent
}
+// Any methods implemented on PublicKey might need to also be implemented on
+// PrivateKey, as the latter embeds the former and will expose its methods.
+
// Size returns the modulus size in bytes. Raw signatures and ciphertexts
// for or by this public key will have the same size.
func (pub *PublicKey) Size() int {
return &priv.PublicKey
}
+// Equal reports whether priv and x have equivalent values. It ignores
+// Precomputed values.
+func (priv *PrivateKey) Equal(x crypto.PrivateKey) bool {
+ xx, ok := x.(*PrivateKey)
+ if !ok {
+ return false
+ }
+ if !priv.PublicKey.Equal(&xx.PublicKey) || priv.D.Cmp(xx.D) != 0 {
+ return false
+ }
+ if len(priv.Primes) != len(xx.Primes) {
+ return false
+ }
+ for i := range priv.Primes {
+ if priv.Primes[i].Cmp(xx.Primes[i]) != 0 {
+ return false
+ }
+ }
+ return true
+}
+
// Sign signs digest with priv, reading randomness from rand. If opts is a
// *PSSOptions then the PSS algorithm will be used, otherwise PKCS#1 v1.5 will
// be used. digest must be the result of hashing the input message using