Created
February 2, 2017 22:08
-
-
Save zapu/c60fe9400d79403226ffaf72c3565314 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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