x/crypto/openpgp: add ElGamal support when writing GPG keys.

When writing keys that contain ElGamal subkeys, the openpgp
package would previously return an error.

Change-Id: I1c487f4a9cfb92b40e99e9be6aa4ed5928e36dbe
Reviewed-on: https://go-review.googlesource.com/18254
Reviewed-by: Adam Langley <agl@golang.org>
diff --git a/openpgp/packet/private_key.go b/openpgp/packet/private_key.go
index cddecfa..740a27d 100644
--- a/openpgp/packet/private_key.go
+++ b/openpgp/packet/private_key.go
@@ -47,6 +47,13 @@
 	return pk
 }
 
+func NewElGamalPrivateKey(currentTime time.Time, priv *elgamal.PrivateKey) *PrivateKey {
+	pk := new(PrivateKey)
+	pk.PublicKey = *NewElGamalPublicKey(currentTime, &priv.PublicKey)
+	pk.PrivateKey = priv
+	return pk
+}
+
 func (pk *PrivateKey) parse(r io.Reader) (err error) {
 	err = (&pk.PublicKey).parse(r)
 	if err != nil {
@@ -130,6 +137,8 @@
 		err = serializeRSAPrivateKey(privateKeyBuf, priv)
 	case *dsa.PrivateKey:
 		err = serializeDSAPrivateKey(privateKeyBuf, priv)
+	case *elgamal.PrivateKey:
+		err = serializeElGamalPrivateKey(privateKeyBuf, priv)
 	default:
 		err = errors.InvalidArgumentError("unknown private key type")
 	}
@@ -185,6 +194,10 @@
 	return writeBig(w, priv.X)
 }
 
+func serializeElGamalPrivateKey(w io.Writer, priv *elgamal.PrivateKey) error {
+	return writeBig(w, priv.X)
+}
+
 // Decrypt decrypts an encrypted private key using a passphrase.
 func (pk *PrivateKey) Decrypt(passphrase []byte) error {
 	if !pk.Encrypted {
diff --git a/openpgp/packet/public_key.go b/openpgp/packet/public_key.go
index c3fb188..37a6472 100644
--- a/openpgp/packet/public_key.go
+++ b/openpgp/packet/public_key.go
@@ -209,6 +209,21 @@
 	return pk
 }
 
+// NewElGamalPublicKey returns a PublicKey that wraps the given elgamal.PublicKey.
+func NewElGamalPublicKey(creationTime time.Time, pub *elgamal.PublicKey) *PublicKey {
+	pk := &PublicKey{
+		CreationTime: creationTime,
+		PubKeyAlgo:   PubKeyAlgoElGamal,
+		PublicKey:    pub,
+		p:            fromBig(pub.P),
+		g:            fromBig(pub.G),
+		y:            fromBig(pub.Y),
+	}
+
+	pk.setFingerPrintAndKeyId()
+	return pk
+}
+
 func (pk *PublicKey) parse(r io.Reader) (err error) {
 	// RFC 4880, section 5.5.2
 	var buf [6]byte