Skip to content

Instantly share code, notes, and snippets.

@zapu
Created February 2, 2017 22:08
Show Gist options
  • Save zapu/c60fe9400d79403226ffaf72c3565314 to your computer and use it in GitHub Desktop.
Save zapu/c60fe9400d79403226ffaf72c3565314 to your computer and use it in GitHub Desktop.
diff --git a/openpgp/ecdh/ecdh.go b/openpgp/ecdh/ecdh.go
index 92c366d..949c9bc 100644
--- a/openpgp/ecdh/ecdh.go
+++ b/openpgp/ecdh/ecdh.go
@@ -223,6 +223,21 @@ func (e *PrivateKey) DecryptShared(X, Y *big.Int) []byte {
return Sx.Bytes()
}
+func countBits(buffer []byte) int {
+ var headerLen int
+ switch buffer[0] {
+ case 0x4:
+ headerLen = 3
+ case 0x40:
+ headerLen = 7
+ default:
+ // Unexpected header byte.
+ headerLen = 8
+ }
+
+ return headerLen + (len(buffer) - 1) * 8
+}
+
// elliptic.Marshal and elliptic.Unmarshal only marshals uncompressed
// 0x4 MPI types. These functions will check if the curve is cv25519,
// and if so, use 0x40 compressed type to (un)marshal. Otherwise,
@@ -230,13 +245,23 @@ func (e *PrivateKey) DecryptShared(X, Y *big.Int) []byte {
// Marshal encodes point into either 0x4 uncompressed point form, or
// 0x40 compressed point for Curve 25519.
-func Marshal(curve elliptic.Curve, x, y *big.Int) []byte {
+func Marshal(curve elliptic.Curve, x, y *big.Int) (buf []byte, bitSize int) {
+ // NOTE: Read more about MPI encoding in the RFC:
+ // https://tools.ietf.org/html/rfc4880#section-3.2
+
+ // We are required to encode size in bits, counting from the most-
+ // significant non-zero bit. So assuming that the buffer never
+ // starts with 0x00, we only need to count bits in the first byte
+ // - and in current implentation it will always be 0x4 or 0x40.
+
cv, ok := curve25519.ToCurve25519(curve)
if ok {
- return cv.MarshalType40(x, y)
+ buf = cv.MarshalType40(x, y)
+ } else {
+ buf = elliptic.Marshal(curve, x, y)
}
- return elliptic.Marshal(curve, x, y)
+ return buf, countBits(buf)
}
// Unmarshal converts point, serialized by Marshal, into x, y pair.
diff --git a/openpgp/packet/ecdh.go b/openpgp/packet/ecdh.go
index 6954320..41de661 100644
--- a/openpgp/packet/ecdh.go
+++ b/openpgp/packet/ecdh.go
@@ -72,8 +72,7 @@ func serializeEncryptedKeyECDH(w io.Writer, rand io.Reader, header [10]byte, pub
return err
}
- mpis := ecdh.Marshal(ecdhpub.Curve, Vx, Vy)
- mpiBitLen := len(mpis) * 8
+ mpis, mpiBitLen := ecdh.Marshal(ecdhpub.Curve, Vx, Vy)
packetLen := len(header) /* header length in bytes */
packetLen += 2 /* mpi length in bits */ + len(mpis)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment