crypto/tls: support X25519.

X25519 (RFC 7748) is now commonly used for key agreement in TLS
connections, as specified in
https://tools.ietf.org/html/draft-ietf-tls-curve25519-01.

This change adds support for that in crypto/tls, but does not enabled it
by default so that there's less test noise. A future change will enable
it by default and will update all the test data at the same time.

Change-Id: I91802ecd776d73aae5c65bcb653d12e23c413ed4
Reviewed-on: https://go-review.googlesource.com/30824
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
diff --git a/src/crypto/tls/common.go b/src/crypto/tls/common.go
index f2989b6..a14712b 100644
--- a/src/crypto/tls/common.go
+++ b/src/crypto/tls/common.go
@@ -95,6 +95,7 @@
 	CurveP256 CurveID = 23
 	CurveP384 CurveID = 24
 	CurveP521 CurveID = 25
+	X25519    CurveID = 29
 )
 
 // TLS Elliptic Curve Point Formats
diff --git a/src/crypto/tls/handshake_client_test.go b/src/crypto/tls/handshake_client_test.go
index 165ed4b..b062365 100644
--- a/src/crypto/tls/handshake_client_test.go
+++ b/src/crypto/tls/handshake_client_test.go
@@ -537,6 +537,19 @@
 	runClientTestTLS12(t, test)
 }
 
+func TestHandshakeClientX25519(t *testing.T) {
+	config := testConfig.Clone()
+	config.CurvePreferences = []CurveID{X25519}
+
+	test := &clientTest{
+		name:    "X25519-ECDHE-RSA-AES-GCM",
+		command: []string{"openssl", "s_server", "-cipher", "ECDHE-RSA-AES128-GCM-SHA256"},
+		config:  config,
+	}
+
+	runClientTestTLS12(t, test)
+}
+
 func TestHandshakeClientCertRSA(t *testing.T) {
 	config := testConfig.Clone()
 	cert, _ := X509KeyPair([]byte(clientCertificatePEM), []byte(clientKeyPEM))
diff --git a/src/crypto/tls/handshake_server_test.go b/src/crypto/tls/handshake_server_test.go
index 9c39d21..fdf5244 100644
--- a/src/crypto/tls/handshake_server_test.go
+++ b/src/crypto/tls/handshake_server_test.go
@@ -749,6 +749,18 @@
 	runServerTestTLS12(t, test)
 }
 
+func TestHandshakeServerX25519(t *testing.T) {
+	config := testConfig.Clone()
+	config.CurvePreferences = []CurveID{X25519}
+
+	test := &serverTest{
+		name:    "X25519-ECDHE-RSA-AES-GCM",
+		command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "ECDHE-RSA-AES128-GCM-SHA256"},
+		config:  config,
+	}
+	runServerTestTLS12(t, test)
+}
+
 func TestHandshakeServerALPN(t *testing.T) {
 	config := testConfig.Clone()
 	config.NextProtos = []string{"proto1", "proto2"}
diff --git a/src/crypto/tls/key_agreement.go b/src/crypto/tls/key_agreement.go
index 467efb2..1b27c04 100644
--- a/src/crypto/tls/key_agreement.go
+++ b/src/crypto/tls/key_agreement.go
@@ -16,6 +16,8 @@
 	"errors"
 	"io"
 	"math/big"
+
+	"golang_org/x/crypto/curve25519"
 )
 
 var errClientKeyExchange = errors.New("tls: invalid ClientKeyExchange message")
@@ -177,52 +179,71 @@
 	version    uint16
 	sigType    uint8
 	privateKey []byte
-	curve      elliptic.Curve
-	x, y       *big.Int
+	curveid    CurveID
+
+	// publicKey is used to store the peer's public value when X25519 is
+	// being used.
+	publicKey []byte
+	// x and y are used to store the peer's public value when one of the
+	// NIST curves is being used.
+	x, y *big.Int
 }
 
 func (ka *ecdheKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
-	var curveid CurveID
 	preferredCurves := config.curvePreferences()
 
 NextCandidate:
 	for _, candidate := range preferredCurves {
 		for _, c := range clientHello.supportedCurves {
 			if candidate == c {
-				curveid = c
+				ka.curveid = c
 				break NextCandidate
 			}
 		}
 	}
 
-	if curveid == 0 {
+	if ka.curveid == 0 {
 		return nil, errors.New("tls: no supported elliptic curves offered")
 	}
 
-	var ok bool
-	if ka.curve, ok = curveForCurveID(curveid); !ok {
-		return nil, errors.New("tls: preferredCurves includes unsupported curve")
-	}
+	var ecdhePublic []byte
 
-	var x, y *big.Int
-	var err error
-	ka.privateKey, x, y, err = elliptic.GenerateKey(ka.curve, config.rand())
-	if err != nil {
-		return nil, err
+	if ka.curveid == X25519 {
+		var scalar, public [32]byte
+		if _, err := io.ReadFull(config.rand(), scalar[:]); err != nil {
+			return nil, err
+		}
+
+		curve25519.ScalarBaseMult(&public, &scalar)
+		ka.privateKey = scalar[:]
+		ecdhePublic = public[:]
+	} else {
+		curve, ok := curveForCurveID(ka.curveid)
+		if !ok {
+			return nil, errors.New("tls: preferredCurves includes unsupported curve")
+		}
+
+		var x, y *big.Int
+		var err error
+		ka.privateKey, x, y, err = elliptic.GenerateKey(curve, config.rand())
+		if err != nil {
+			return nil, err
+		}
+		ecdhePublic = elliptic.Marshal(curve, x, y)
 	}
-	ecdhePublic := elliptic.Marshal(ka.curve, x, y)
 
 	// http://tools.ietf.org/html/rfc4492#section-5.4
 	serverECDHParams := make([]byte, 1+2+1+len(ecdhePublic))
 	serverECDHParams[0] = 3 // named curve
-	serverECDHParams[1] = byte(curveid >> 8)
-	serverECDHParams[2] = byte(curveid)
+	serverECDHParams[1] = byte(ka.curveid >> 8)
+	serverECDHParams[2] = byte(ka.curveid)
 	serverECDHParams[3] = byte(len(ecdhePublic))
 	copy(serverECDHParams[4:], ecdhePublic)
 
 	sigAndHash := signatureAndHash{signature: ka.sigType}
 
 	if ka.version >= VersionTLS12 {
+		var err error
 		if sigAndHash.hash, err = pickTLS12HashForSignature(ka.sigType, clientHello.signatureAndHashes); err != nil {
 			return nil, err
 		}
@@ -281,15 +302,32 @@
 	if len(ckx.ciphertext) == 0 || int(ckx.ciphertext[0]) != len(ckx.ciphertext)-1 {
 		return nil, errClientKeyExchange
 	}
-	x, y := elliptic.Unmarshal(ka.curve, ckx.ciphertext[1:])
+
+	if ka.curveid == X25519 {
+		if len(ckx.ciphertext) != 1+32 {
+			return nil, errClientKeyExchange
+		}
+
+		var theirPublic, sharedKey, scalar [32]byte
+		copy(theirPublic[:], ckx.ciphertext[1:])
+		copy(scalar[:], ka.privateKey)
+		curve25519.ScalarMult(&sharedKey, &scalar, &theirPublic)
+		return sharedKey[:], nil
+	}
+
+	curve, ok := curveForCurveID(ka.curveid)
+	if !ok {
+		panic("internal error")
+	}
+	x, y := elliptic.Unmarshal(curve, ckx.ciphertext[1:])
 	if x == nil {
 		return nil, errClientKeyExchange
 	}
-	if !ka.curve.IsOnCurve(x, y) {
+	if !curve.IsOnCurve(x, y) {
 		return nil, errClientKeyExchange
 	}
-	x, _ = ka.curve.ScalarMult(x, y, ka.privateKey)
-	preMasterSecret := make([]byte, (ka.curve.Params().BitSize+7)>>3)
+	x, _ = curve.ScalarMult(x, y, ka.privateKey)
+	preMasterSecret := make([]byte, (curve.Params().BitSize+7)>>3)
 	xBytes := x.Bytes()
 	copy(preMasterSecret[len(preMasterSecret)-len(xBytes):], xBytes)
 
@@ -303,31 +341,40 @@
 	if skx.key[0] != 3 { // named curve
 		return errors.New("tls: server selected unsupported curve")
 	}
-	curveid := CurveID(skx.key[1])<<8 | CurveID(skx.key[2])
-
-	var ok bool
-	if ka.curve, ok = curveForCurveID(curveid); !ok {
-		return errors.New("tls: server selected unsupported curve")
-	}
+	ka.curveid = CurveID(skx.key[1])<<8 | CurveID(skx.key[2])
 
 	publicLen := int(skx.key[3])
 	if publicLen+4 > len(skx.key) {
 		return errServerKeyExchange
 	}
-	ka.x, ka.y = elliptic.Unmarshal(ka.curve, skx.key[4:4+publicLen])
-	if ka.x == nil {
-		return errServerKeyExchange
-	}
-	if !ka.curve.IsOnCurve(ka.x, ka.y) {
-		return errServerKeyExchange
-	}
 	serverECDHParams := skx.key[:4+publicLen]
+	publicKey := serverECDHParams[4:]
 
 	sig := skx.key[4+publicLen:]
 	if len(sig) < 2 {
 		return errServerKeyExchange
 	}
 
+	if ka.curveid == X25519 {
+		if len(publicKey) != 32 {
+			return errors.New("tls: bad X25519 public value")
+		}
+		ka.publicKey = publicKey
+	} else {
+		curve, ok := curveForCurveID(ka.curveid)
+		if !ok {
+			return errors.New("tls: server selected unsupported curve")
+		}
+
+		ka.x, ka.y = elliptic.Unmarshal(curve, publicKey)
+		if ka.x == nil {
+			return errServerKeyExchange
+		}
+		if !curve.IsOnCurve(ka.x, ka.y) {
+			return errServerKeyExchange
+		}
+	}
+
 	sigAndHash := signatureAndHash{signature: ka.sigType}
 	if ka.version >= VersionTLS12 {
 		// handle SignatureAndHashAlgorithm
@@ -382,19 +429,40 @@
 }
 
 func (ka *ecdheKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
-	if ka.curve == nil {
+	if ka.curveid == 0 {
 		return nil, nil, errors.New("tls: missing ServerKeyExchange message")
 	}
-	priv, mx, my, err := elliptic.GenerateKey(ka.curve, config.rand())
-	if err != nil {
-		return nil, nil, err
-	}
-	x, _ := ka.curve.ScalarMult(ka.x, ka.y, priv)
-	preMasterSecret := make([]byte, (ka.curve.Params().BitSize+7)>>3)
-	xBytes := x.Bytes()
-	copy(preMasterSecret[len(preMasterSecret)-len(xBytes):], xBytes)
 
-	serialized := elliptic.Marshal(ka.curve, mx, my)
+	var serialized, preMasterSecret []byte
+
+	if ka.curveid == X25519 {
+		var ourPublic, theirPublic, sharedKey, scalar [32]byte
+
+		if _, err := io.ReadFull(config.rand(), scalar[:]); err != nil {
+			return nil, nil, err
+		}
+
+		copy(theirPublic[:], ka.publicKey)
+		curve25519.ScalarBaseMult(&ourPublic, &scalar)
+		curve25519.ScalarMult(&sharedKey, &scalar, &theirPublic)
+		serialized = ourPublic[:]
+		preMasterSecret = sharedKey[:]
+	} else {
+		curve, ok := curveForCurveID(ka.curveid)
+		if !ok {
+			panic("internal error")
+		}
+		priv, mx, my, err := elliptic.GenerateKey(curve, config.rand())
+		if err != nil {
+			return nil, nil, err
+		}
+		x, _ := curve.ScalarMult(ka.x, ka.y, priv)
+		preMasterSecret = make([]byte, (curve.Params().BitSize+7)>>3)
+		xBytes := x.Bytes()
+		copy(preMasterSecret[len(preMasterSecret)-len(xBytes):], xBytes)
+
+		serialized = elliptic.Marshal(curve, mx, my)
+	}
 
 	ckx := new(clientKeyExchangeMsg)
 	ckx.ciphertext = make([]byte, 1+len(serialized))
diff --git a/src/crypto/tls/testdata/Client-TLSv12-X25519-ECDHE-RSA-AES-GCM b/src/crypto/tls/testdata/Client-TLSv12-X25519-ECDHE-RSA-AES-GCM
new file mode 100644
index 0000000..dcbce97
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-X25519-ECDHE-RSA-AES-GCM
@@ -0,0 +1,85 @@
+>>> Flow 1 (client to server)
+00000000  16 03 01 00 87 01 00 00  83 03 03 00 00 00 00 00  |................|
+00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 28 c0 2f  |.............(./|
+00000030  c0 2b c0 30 c0 2c c0 27  c0 13 c0 23 c0 09 c0 14  |.+.0.,.'...#....|
+00000040  c0 0a 00 9c 00 9d 00 3c  00 2f 00 35 c0 12 00 0a  |.......<./.5....|
+00000050  00 05 c0 11 c0 07 01 00  00 32 00 05 00 05 01 00  |.........2......|
+00000060  00 00 00 00 0a 00 04 00  02 00 1d 00 0b 00 02 01  |................|
+00000070  00 00 0d 00 0e 00 0c 04  01 04 03 05 01 05 03 02  |................|
+00000080  01 02 03 ff 01 00 01 00  00 12 00 00              |............|
+>>> Flow 2 (server to client)
+00000000  16 03 03 00 59 02 00 00  55 03 03 64 2f 20 bb e0  |....Y...U..d/ ..|
+00000010  0c 8b 1e d9 fc 96 1d d7  66 02 62 bd 63 d8 52 48  |........f.b.c.RH|
+00000020  61 6d 4e f9 e4 26 43 f2  dd 75 00 20 e9 7d 2b 02  |amN..&C..u. .}+.|
+00000030  39 df 15 b7 24 c8 7a 61  81 cc a4 3a 3f 80 36 e2  |9...$.za...:?.6.|
+00000040  44 fd cd e1 a8 db ad a0  79 2d d3 f6 c0 2f 00 00  |D.......y-.../..|
+00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
+00000060  03 02 59 0b 00 02 55 00  02 52 00 02 4f 30 82 02  |..Y...U..R..O0..|
+00000070  4b 30 82 01 b4 a0 03 02  01 02 02 09 00 e8 f0 9d  |K0..............|
+00000080  3f e2 5b ea a6 30 0d 06  09 2a 86 48 86 f7 0d 01  |?.[..0...*.H....|
+00000090  01 0b 05 00 30 1f 31 0b  30 09 06 03 55 04 0a 13  |....0.1.0...U...|
+000000a0  02 47 6f 31 10 30 0e 06  03 55 04 03 13 07 47 6f  |.Go1.0...U....Go|
+000000b0  20 52 6f 6f 74 30 1e 17  0d 31 36 30 31 30 31 30  | Root0...1601010|
+000000c0  30 30 30 30 30 5a 17 0d  32 35 30 31 30 31 30 30  |00000Z..25010100|
+000000d0  30 30 30 30 5a 30 1a 31  0b 30 09 06 03 55 04 0a  |0000Z0.1.0...U..|
+000000e0  13 02 47 6f 31 0b 30 09  06 03 55 04 03 13 02 47  |..Go1.0...U....G|
+000000f0  6f 30 81 9f 30 0d 06 09  2a 86 48 86 f7 0d 01 01  |o0..0...*.H.....|
+00000100  01 05 00 03 81 8d 00 30  81 89 02 81 81 00 db 46  |.......0.......F|
+00000110  7d 93 2e 12 27 06 48 bc  06 28 21 ab 7e c4 b6 a2  |}...'.H..(!.~...|
+00000120  5d fe 1e 52 45 88 7a 36  47 a5 08 0d 92 42 5b c2  |]..RE.z6G....B[.|
+00000130  81 c0 be 97 79 98 40 fb  4f 6d 14 fd 2b 13 8b c2  |....y.@.Om..+...|
+00000140  a5 2e 67 d8 d4 09 9e d6  22 38 b7 4a 0b 74 73 2b  |..g....."8.J.ts+|
+00000150  c2 34 f1 d1 93 e5 96 d9  74 7b f3 58 9f 6c 61 3c  |.4......t{.X.la<|
+00000160  c0 b0 41 d4 d9 2b 2b 24  23 77 5b 1c 3b bd 75 5d  |..A..++$#w[.;.u]|
+00000170  ce 20 54 cf a1 63 87 1d  1e 24 c4 f3 1d 1a 50 8b  |. T..c...$....P.|
+00000180  aa b6 14 43 ed 97 a7 75  62 f4 14 c8 52 d7 02 03  |...C...ub...R...|
+00000190  01 00 01 a3 81 93 30 81  90 30 0e 06 03 55 1d 0f  |......0..0...U..|
+000001a0  01 01 ff 04 04 03 02 05  a0 30 1d 06 03 55 1d 25  |.........0...U.%|
+000001b0  04 16 30 14 06 08 2b 06  01 05 05 07 03 01 06 08  |..0...+.........|
+000001c0  2b 06 01 05 05 07 03 02  30 0c 06 03 55 1d 13 01  |+.......0...U...|
+000001d0  01 ff 04 02 30 00 30 19  06 03 55 1d 0e 04 12 04  |....0.0...U.....|
+000001e0  10 9f 91 16 1f 43 43 3e  49 a6 de 6d b6 80 d7 9f  |.....CC>I..m....|
+000001f0  60 30 1b 06 03 55 1d 23  04 14 30 12 80 10 48 13  |`0...U.#..0...H.|
+00000200  49 4d 13 7e 16 31 bb a3  01 d5 ac ab 6e 7b 30 19  |IM.~.1......n{0.|
+00000210  06 03 55 1d 11 04 12 30  10 82 0e 65 78 61 6d 70  |..U....0...examp|
+00000220  6c 65 2e 67 6f 6c 61 6e  67 30 0d 06 09 2a 86 48  |le.golang0...*.H|
+00000230  86 f7 0d 01 01 0b 05 00  03 81 81 00 9d 30 cc 40  |.............0.@|
+00000240  2b 5b 50 a0 61 cb ba e5  53 58 e1 ed 83 28 a9 58  |+[P.a...SX...(.X|
+00000250  1a a9 38 a4 95 a1 ac 31  5a 1a 84 66 3d 43 d3 2d  |..8....1Z..f=C.-|
+00000260  d9 0b f2 97 df d3 20 64  38 92 24 3a 00 bc cf 9c  |...... d8.$:....|
+00000270  7d b7 40 20 01 5f aa d3  16 61 09 a2 76 fd 13 c3  |}.@ ._...a..v...|
+00000280  cc e1 0c 5c ee b1 87 82  f1 6c 04 ed 73 bb b3 43  |...\.....l..s..C|
+00000290  77 8d 0c 1c f1 0f a1 d8  40 83 61 c9 4c 72 2b 9d  |w.......@.a.Lr+.|
+000002a0  ae db 46 06 06 4d f4 c1  b3 3e c0 d1 bd 42 d4 db  |..F..M...>...B..|
+000002b0  fe 3d 13 60 84 5c 21 d3  3b e9 fa e7 16 03 03 00  |.=.`.\!.;.......|
+000002c0  ac 0c 00 00 a8 03 00 1d  20 27 08 d8 54 80 58 52  |........ '..T.XR|
+000002d0  fa d3 4e ba 1a 49 7b 20  b7 c3 c8 dc 91 42 90 9a  |..N..I{ .....B..|
+000002e0  7d 63 b7 88 16 39 6b 2f  4a 04 01 00 80 97 3b 72  |}c...9k/J.....;r|
+000002f0  f0 94 ef 26 07 b9 37 f5  6a 00 30 34 1f b8 90 46  |...&..7.j.04...F|
+00000300  fc 36 9b 19 9c de 60 c1  9a da 8e a0 94 d5 f9 d8  |.6....`.........|
+00000310  aa f0 c4 7a 3e 0a 55 9e  97 bd 27 09 77 20 a7 72  |...z>.U...'.w .r|
+00000320  bc a0 46 75 96 ab 0b 42  2c 24 06 eb ee 5a 07 cc  |..Fu...B,$...Z..|
+00000330  94 42 25 57 d9 ad a6 ae  28 fe 94 c8 bc ca a8 e0  |.B%W....(.......|
+00000340  9e 18 b0 f2 b5 b5 93 a7  a0 20 17 7e 18 ac 8f cf  |......... .~....|
+00000350  30 ea fd e8 43 25 c1 fc  48 51 5a d2 ef b5 95 13  |0...C%..HQZ.....|
+00000360  6c 37 5a 6b 55 34 8d b0  3c 8f 9e 1b e8 16 03 03  |l7ZkU4..<.......|
+00000370  00 04 0e 00 00 00                                 |......|
+>>> Flow 3 (client to server)
+00000000  16 03 03 00 25 10 00 00  21 20 2f e5 7d a3 47 cd  |....%...! /.}.G.|
+00000010  62 43 15 28 da ac 5f bb  29 07 30 ff f6 84 af c4  |bC.(.._.).0.....|
+00000020  cf c2 ed 90 99 5f 58 cb  3b 74 14 03 03 00 01 01  |....._X.;t......|
+00000030  16 03 03 00 28 00 00 00  00 00 00 00 00 17 40 ca  |....(.........@.|
+00000040  78 e3 f2 c9 05 71 6b 37  98 79 21 d0 b1 e1 49 b5  |x....qk7.y!...I.|
+00000050  54 45 35 e9 58 bd f9 60  5f c8 16 e7 42           |TE5.X..`_...B|
+>>> Flow 4 (server to client)
+00000000  14 03 03 00 01 01 16 03  03 00 28 2d d9 e6 e1 eb  |..........(-....|
+00000010  b7 65 e5 f4 fc 56 4a 35  00 0c 90 bf 5f c3 73 dc  |.e...VJ5...._.s.|
+00000020  86 f8 44 2c c7 18 fd ca  24 f6 34 98 5e ef 25 44  |..D,....$.4.^.%D|
+00000030  41 74 4a                                          |AtJ|
+>>> Flow 5 (client to server)
+00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 84 48 a7  |..............H.|
+00000010  d1 2e f0 75 1a da f9 d4  bc 88 42 e0 8c 68 09 ae  |...u......B..h..|
+00000020  0a ac 46 15 03 03 00 1a  00 00 00 00 00 00 00 02  |..F.............|
+00000030  0b fb c3 cb 27 17 0c 35  e9 8f 8f 96 dd ce d5 5d  |....'..5.......]|
+00000040  42 44                                             |BD|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-X25519-ECDHE-RSA-AES-GCM b/src/crypto/tls/testdata/Server-TLSv12-X25519-ECDHE-RSA-AES-GCM
new file mode 100644
index 0000000..c2c0199
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-X25519-ECDHE-RSA-AES-GCM
@@ -0,0 +1,79 @@
+>>> Flow 1 (client to server)
+00000000  16 03 01 00 73 01 00 00  6f 03 03 c5 04 fb 19 85  |....s...o.......|
+00000010  7c 1d 96 0a 68 50 5d f9  03 4d be d6 62 e0 ba 08  ||...hP]..M..b...|
+00000020  8e 36 d5 4e ed ed 1a 63  72 eb 94 00 00 04 c0 2f  |.6.N...cr....../|
+00000030  00 ff 01 00 00 42 00 0b  00 04 03 00 01 02 00 0a  |.....B..........|
+00000040  00 0a 00 08 00 1d 00 17  00 19 00 18 00 0d 00 20  |............... |
+00000050  00 1e 06 01 06 02 06 03  05 01 05 02 05 03 04 01  |................|
+00000060  04 02 04 03 03 01 03 02  03 03 02 01 02 02 02 03  |................|
+00000070  00 16 00 00 00 17 00 00                           |........|
+>>> Flow 2 (server to client)
+00000000  16 03 03 00 31 02 00 00  2d 03 03 00 00 00 00 00  |....1...-.......|
+00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 c0 2f 00 00  |............./..|
+00000030  05 ff 01 00 01 00 16 03  03 02 59 0b 00 02 55 00  |..........Y...U.|
+00000040  02 52 00 02 4f 30 82 02  4b 30 82 01 b4 a0 03 02  |.R..O0..K0......|
+00000050  01 02 02 09 00 e8 f0 9d  3f e2 5b ea a6 30 0d 06  |........?.[..0..|
+00000060  09 2a 86 48 86 f7 0d 01  01 0b 05 00 30 1f 31 0b  |.*.H........0.1.|
+00000070  30 09 06 03 55 04 0a 13  02 47 6f 31 10 30 0e 06  |0...U....Go1.0..|
+00000080  03 55 04 03 13 07 47 6f  20 52 6f 6f 74 30 1e 17  |.U....Go Root0..|
+00000090  0d 31 36 30 31 30 31 30  30 30 30 30 30 5a 17 0d  |.160101000000Z..|
+000000a0  32 35 30 31 30 31 30 30  30 30 30 30 5a 30 1a 31  |250101000000Z0.1|
+000000b0  0b 30 09 06 03 55 04 0a  13 02 47 6f 31 0b 30 09  |.0...U....Go1.0.|
+000000c0  06 03 55 04 03 13 02 47  6f 30 81 9f 30 0d 06 09  |..U....Go0..0...|
+000000d0  2a 86 48 86 f7 0d 01 01  01 05 00 03 81 8d 00 30  |*.H............0|
+000000e0  81 89 02 81 81 00 db 46  7d 93 2e 12 27 06 48 bc  |.......F}...'.H.|
+000000f0  06 28 21 ab 7e c4 b6 a2  5d fe 1e 52 45 88 7a 36  |.(!.~...]..RE.z6|
+00000100  47 a5 08 0d 92 42 5b c2  81 c0 be 97 79 98 40 fb  |G....B[.....y.@.|
+00000110  4f 6d 14 fd 2b 13 8b c2  a5 2e 67 d8 d4 09 9e d6  |Om..+.....g.....|
+00000120  22 38 b7 4a 0b 74 73 2b  c2 34 f1 d1 93 e5 96 d9  |"8.J.ts+.4......|
+00000130  74 7b f3 58 9f 6c 61 3c  c0 b0 41 d4 d9 2b 2b 24  |t{.X.la<..A..++$|
+00000140  23 77 5b 1c 3b bd 75 5d  ce 20 54 cf a1 63 87 1d  |#w[.;.u]. T..c..|
+00000150  1e 24 c4 f3 1d 1a 50 8b  aa b6 14 43 ed 97 a7 75  |.$....P....C...u|
+00000160  62 f4 14 c8 52 d7 02 03  01 00 01 a3 81 93 30 81  |b...R.........0.|
+00000170  90 30 0e 06 03 55 1d 0f  01 01 ff 04 04 03 02 05  |.0...U..........|
+00000180  a0 30 1d 06 03 55 1d 25  04 16 30 14 06 08 2b 06  |.0...U.%..0...+.|
+00000190  01 05 05 07 03 01 06 08  2b 06 01 05 05 07 03 02  |........+.......|
+000001a0  30 0c 06 03 55 1d 13 01  01 ff 04 02 30 00 30 19  |0...U.......0.0.|
+000001b0  06 03 55 1d 0e 04 12 04  10 9f 91 16 1f 43 43 3e  |..U..........CC>|
+000001c0  49 a6 de 6d b6 80 d7 9f  60 30 1b 06 03 55 1d 23  |I..m....`0...U.#|
+000001d0  04 14 30 12 80 10 48 13  49 4d 13 7e 16 31 bb a3  |..0...H.IM.~.1..|
+000001e0  01 d5 ac ab 6e 7b 30 19  06 03 55 1d 11 04 12 30  |....n{0...U....0|
+000001f0  10 82 0e 65 78 61 6d 70  6c 65 2e 67 6f 6c 61 6e  |...example.golan|
+00000200  67 30 0d 06 09 2a 86 48  86 f7 0d 01 01 0b 05 00  |g0...*.H........|
+00000210  03 81 81 00 9d 30 cc 40  2b 5b 50 a0 61 cb ba e5  |.....0.@+[P.a...|
+00000220  53 58 e1 ed 83 28 a9 58  1a a9 38 a4 95 a1 ac 31  |SX...(.X..8....1|
+00000230  5a 1a 84 66 3d 43 d3 2d  d9 0b f2 97 df d3 20 64  |Z..f=C.-...... d|
+00000240  38 92 24 3a 00 bc cf 9c  7d b7 40 20 01 5f aa d3  |8.$:....}.@ ._..|
+00000250  16 61 09 a2 76 fd 13 c3  cc e1 0c 5c ee b1 87 82  |.a..v......\....|
+00000260  f1 6c 04 ed 73 bb b3 43  77 8d 0c 1c f1 0f a1 d8  |.l..s..Cw.......|
+00000270  40 83 61 c9 4c 72 2b 9d  ae db 46 06 06 4d f4 c1  |@.a.Lr+...F..M..|
+00000280  b3 3e c0 d1 bd 42 d4 db  fe 3d 13 60 84 5c 21 d3  |.>...B...=.`.\!.|
+00000290  3b e9 fa e7 16 03 03 00  ac 0c 00 00 a8 03 00 1d  |;...............|
+000002a0  20 2f e5 7d a3 47 cd 62  43 15 28 da ac 5f bb 29  | /.}.G.bC.(.._.)|
+000002b0  07 30 ff f6 84 af c4 cf  c2 ed 90 99 5f 58 cb 3b  |.0.........._X.;|
+000002c0  74 05 01 00 80 93 b5 4c  a5 01 aa c4 dd ab de 51  |t......L.......Q|
+000002d0  16 79 81 b3 61 06 88 4c  56 4f ad 10 89 a4 95 62  |.y..a..LVO.....b|
+000002e0  4e be bb c0 a2 13 31 1d  29 aa c1 d4 c5 ac b1 39  |N.....1.)......9|
+000002f0  9d 23 07 ba b9 a1 5e 00  ed e2 32 bb 2b 7c 7f e8  |.#....^...2.+|..|
+00000300  81 c0 bf 22 6a 99 e7 1a  f8 88 08 80 ba e3 2d c6  |..."j.........-.|
+00000310  64 7b c6 f1 c5 3f 86 a8  0d 61 bb df 46 43 b2 72  |d{...?...a..FC.r|
+00000320  4f ef 00 13 15 d1 4a 5d  66 82 88 76 26 b8 9f ee  |O.....J]f..v&...|
+00000330  c5 fb 39 55 16 11 79 3e  ef 52 80 b7 3e 8f 0d 9f  |..9U..y>.R..>...|
+00000340  59 6a 23 1a 75 16 03 03  00 04 0e 00 00 00        |Yj#.u.........|
+>>> Flow 3 (client to server)
+00000000  16 03 03 00 25 10 00 00  21 20 c5 a2 cd 04 66 cf  |....%...! ....f.|
+00000010  18 3a c6 55 7c 23 87 f2  e9 1e 08 d1 77 17 1d ee  |.:.U|#......w...|
+00000020  ea 46 48 b2 f1 a6 00 90  d0 0b 14 03 03 00 01 01  |.FH.............|
+00000030  16 03 03 00 28 f6 13 89  ff 83 6a 6f 2c 9e d4 49  |....(.....jo,..I|
+00000040  0d 1b 28 68 00 e4 fb f7  61 a3 e6 61 c7 12 1d 87  |..(h....a..a....|
+00000050  65 23 77 0a 47 fe 82 74  09 1b c1 05 e7           |e#w.G..t.....|
+>>> Flow 4 (server to client)
+00000000  14 03 03 00 01 01 16 03  03 00 28 00 00 00 00 00  |..........(.....|
+00000010  00 00 00 e3 14 42 2a 28  3c 8a df 74 1a 4f 13 b1  |.....B*(<..t.O..|
+00000020  d8 ec a5 bb 26 02 b1 a9  70 8c e3 81 30 ba 87 c5  |....&...p...0...|
+00000030  45 bf a5 17 03 03 00 25  00 00 00 00 00 00 00 01  |E......%........|
+00000040  29 8f bb c2 42 f4 40 61  d5 fe 04 87 a6 5f 0e 2d  |)...B.@a....._.-|
+00000050  0c ce 9e 2f d6 df be 10  fe 3d 4f d4 72 15 03 03  |.../.....=O.r...|
+00000060  00 1a 00 00 00 00 00 00  00 02 55 da b5 79 7b 1e  |..........U..y{.|
+00000070  be e0 d2 83 40 6f 0c 38  83 a5 6e bd              |....@o.8..n.|
diff --git a/src/go/build/deps_test.go b/src/go/build/deps_test.go
index 8b382ec..95accdb 100644
--- a/src/go/build/deps_test.go
+++ b/src/go/build/deps_test.go
@@ -333,6 +333,7 @@
 		"crypto/sha1",
 		"crypto/sha256",
 		"crypto/sha512",
+		"golang_org/x/crypto/curve25519",
 	},
 
 	// Random byte, number generation.