Beispiel #1
0
func main() {
	u := must(url.Parse("http://SUCCESS"))
	b, x, y := must(elliptic.GenerateKey(elliptic.P224(), ConstWriter(0)))
	if must(url.Parse("http://example.com/a/b")).IsAbs() {
		fmt.Println(u.Host)
	}
}
Beispiel #2
0
func (alg *Ecdh) WrapNewKey(cekSizeBits int, key interface{}, header map[string]interface{}) (cek []byte, encryptedCek []byte, err error) {

	if pubKey, ok := key.(*ecdsa.PublicKey); ok {

		if _, ok := header[alg.idHeader()].(string); !ok {
			return nil, nil, errors.New(fmt.Sprintf("Ecdh.WrapNewKey(): expected '%v' param in JWT header, but was not found.", alg.idHeader()))
		}

		var d []byte
		var x, y *big.Int

		if d, x, y, err = elliptic.GenerateKey(pubKey.Curve, rand.Reader); err != nil {
			return nil, nil, err
		}

		ephemeral := ecc.NewPrivate(x.Bytes(), y.Bytes(), d)

		xBytes := padding.Align(x.Bytes(), pubKey.Curve.Params().BitSize)
		yBytes := padding.Align(y.Bytes(), pubKey.Curve.Params().BitSize)

		epk := map[string]string{
			"kty": "EC",
			"x":   base64url.Encode(xBytes),
			"y":   base64url.Encode(yBytes),
			"crv": name(pubKey.Curve),
		}

		header["epk"] = epk

		return alg.deriveKey(pubKey, ephemeral, cekSizeBits, header), nil, nil
	}

	return nil, nil, errors.New("Ecdh.WrapNewKey(): expected key to be '*ecdsa.PublicKey'")
}
Beispiel #3
0
func (e *ellipticECDHCurve) offer(rand io.Reader) (publicKey []byte, err error) {
	var x, y *big.Int
	e.privateKey, x, y, err = elliptic.GenerateKey(e.curve, rand)
	if err != nil {
		return nil, err
	}
	return elliptic.Marshal(e.curve, x, y), nil
}
Beispiel #4
0
// Create a new Public-Private ECC-256 Keypair.
func CreateKey(log chan string) ([]byte, *big.Int, *big.Int) {
	priv, x, y, err := elliptic.GenerateKey(elliptic.P256(), rand.Reader)
	if err != nil {
		log <- "Key Generation Error"
		return nil, nil, nil
	}
	return priv, x, y
}
Beispiel #5
0
// GenerateKey returns a new keypair
func (curve Curve) GenerateKey() (priv []byte, pub *Point, err error) {
	priv, x, y, err := elliptic.GenerateKey(curve.Curve, curve.Rand)
	if err != nil {
		return nil, nil, err
	}
	pub = new(Point)
	pub.X, pub.Y = x, y
	return priv, pub, nil
}
Beispiel #6
0
func (ka *ecdheRSAKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
	var curveid uint16

Curve:
	for _, c := range clientHello.supportedCurves {
		switch c {
		case curveP256:
			ka.curve = elliptic.P256()
			curveid = c
			break Curve
		case curveP384:
			ka.curve = elliptic.P384()
			curveid = c
			break Curve
		case curveP521:
			ka.curve = elliptic.P521()
			curveid = c
			break Curve
		}
	}

	if curveid == 0 {
		return nil, errors.New("tls: no supported elliptic curves offered")
	}

	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
	}
	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[3] = byte(len(ecdhePublic))
	copy(serverECDHParams[4:], ecdhePublic)

	md5sha1 := md5SHA1Hash(clientHello.random, hello.random, serverECDHParams)
	sig, err := rsa.SignPKCS1v15(config.rand(), cert.PrivateKey.(*rsa.PrivateKey), crypto.MD5SHA1, md5sha1)
	if err != nil {
		return nil, errors.New("failed to sign ECDHE parameters: " + err.Error())
	}

	skx := new(serverKeyExchangeMsg)
	skx.key = make([]byte, len(serverECDHParams)+2+len(sig))
	copy(skx.key, serverECDHParams)
	k := skx.key[len(serverECDHParams):]
	k[0] = byte(len(sig) >> 8)
	k[1] = byte(len(sig))
	copy(k[2:], sig)

	return skx, nil
}
Beispiel #7
0
func BenchmarkVerify(b *testing.B) {
	c := elliptic.P256()
	_, px, py, _ := elliptic.GenerateKey(c, rand.Reader)
	box := VoteZero(c, px, py)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		IsValidBox(c, box, px, py)
	}
}
Beispiel #8
0
func eciesEncrypt(rand io.Reader, pub *ecdsa.PublicKey, s1, s2 []byte, plain []byte) ([]byte, error) {
	params := pub.Curve

	// Select an ephemeral elliptic curve key pair associated with
	// elliptic curve domain parameters params
	priv, Rx, Ry, err := elliptic.GenerateKey(pub.Curve, rand)
	//fmt.Printf("Rx %s\n", utils.EncodeBase64(Rx.Bytes()))
	//fmt.Printf("Ry %s\n", utils.EncodeBase64(Ry.Bytes()))

	// Convert R=(Rx,Ry) to an octed string R bar
	// This is uncompressed
	Rb := elliptic.Marshal(pub.Curve, Rx, Ry)

	// Derive a shared secret field element z from the ephemeral secret key k
	// and convert z to an octet string Z
	z, _ := params.ScalarMult(pub.X, pub.Y, priv)
	Z := z.Bytes()
	//fmt.Printf("Z %s\n", utils.EncodeBase64(Z))

	// generate keying data K of length ecnKeyLen + macKeyLen octects from Z
	// ans s1
	kE := make([]byte, 32)
	kM := make([]byte, 32)
	hkdf := hkdf.New(primitives.GetDefaultHash(), Z, s1, nil)
	_, err = hkdf.Read(kE)
	if err != nil {
		return nil, err
	}
	_, err = hkdf.Read(kM)
	if err != nil {
		return nil, err
	}

	// Use the encryption operation of the symmetric encryption scheme
	// to encrypt m under EK as ciphertext EM
	EM, err := aesEncrypt(kE, plain)

	// Use the tagging operation of the MAC scheme to compute
	// the tag D on EM || s2
	mac := hmac.New(primitives.GetDefaultHash(), kM)
	mac.Write(EM)
	if len(s2) > 0 {
		mac.Write(s2)
	}
	D := mac.Sum(nil)

	// Output R,EM,D
	ciphertext := make([]byte, len(Rb)+len(EM)+len(D))
	//fmt.Printf("Rb %s\n", utils.EncodeBase64(Rb))
	//fmt.Printf("EM %s\n", utils.EncodeBase64(EM))
	//fmt.Printf("D %s\n", utils.EncodeBase64(D))
	copy(ciphertext, Rb)
	copy(ciphertext[len(Rb):], EM)
	copy(ciphertext[len(Rb)+len(EM):], D)

	return ciphertext, nil
}
Beispiel #9
0
func keypairGen() KeyPair {
	if fakeRandom {
		priv := new(Scalar).fromSmallInt(1)
		pub := priv.toPoint()
		return KeyPair{*priv, pub}
	} else {
		priv, x, y, _ := elliptic.GenerateKey(getCurve(), rand.Reader)
		return KeyPair{Scalar{priv}, Point{x, y}}
	}
}
Beispiel #10
0
func (g genericCurve) GenerateKey(rand io.Reader) (private PrivateKey, public PublicKey, err error) {
	if rand == nil {
		rand = cryptorand.Reader
	}
	private, x, y, err := elliptic.GenerateKey(g.curve, rand)
	if err != nil {
		private = nil
		return
	}
	public = elliptic.Marshal(g.curve, x, y)
	return
}
Beispiel #11
0
// Q = curve.G * k
// Q => k is ECDLP
func GenerateECKey(curve elliptic.Curve) (*ECKey, error) {
	k, xq, yq, e := elliptic.GenerateKey(curve, rand.Reader)
	if e != nil {
		return nil, e
	}
	return &ECKey{
		curve: curve,
		priv:  k,
		xQ:    xq,
		yQ:    yq,
	}, nil
}
Beispiel #12
0
// NewECDH_P256 returns an Elliptic Curve Diffie-Hellman P-256 KeyExchange algorithm.
func NewECDH_P256() (error, KeyExchange) {
	curve := elliptic.P256()
	priv, x, y, err := elliptic.GenerateKey(curve, rand.Reader)
	if err != nil {
		return err, nil
	}
	return nil, &p256{
		curve:      curve,
		publicX:    x,
		publicY:    y,
		privateKey: priv}
}
Beispiel #13
0
// GenerateKey generates an appropriate private and public keypair for
// use in box.
func GenerateKey() (PrivateKey, PublicKey, bool) {
	key, x, y, err := elliptic.GenerateKey(curve, PRNG)
	if err != nil {
		return nil, nil, false
	}
	peer := elliptic.Marshal(curve, x, y)
	if peer == nil {
	}
	if len(key) != privateKeySize || len(peer) != publicKeySize {
		return nil, nil, false
	}
	return key, peer, true
}
Beispiel #14
0
func main() {
	c := elliptic.P256()
	priv, x, y, err := elliptic.GenerateKey(c, rand.Reader)
	if err != nil {
		fmt.Printf("Error!\n")
	} else {
		fmt.Printf("Public Key is %s\n Private key is %s\n",
			base64.StdEncoding.EncodeToString(
				(elliptic.Marshal(c, x, y))),
			hex.EncodeToString(priv))
	}

}
Beispiel #15
0
func generateKey() (*key, error) {
	var (
		k   = &key{}
		err error
	)

	k.prv.d, k.pub.x, k.pub.y, err = elliptic.GenerateKey(secp160r1.P160(), rand.Reader)
	if err != nil {
		return nil, err
	}

	return k, nil
}
Beispiel #16
0
func Test_ComputeShared_P160(t *testing.T) {
	assert := assert.New(t)
	curve := secp160r1.P160()

	for i := 100; i > 0; i-- {
		prv1, x1, y1, err := elliptic.GenerateKey(curve, rand.Reader)
		assert.NoError(err)
		assert.NotNil(prv1)
		assert.NotNil(x1)
		assert.NotNil(y1)

		prv2, x2, y2, err := elliptic.GenerateKey(curve, rand.Reader)
		assert.NoError(err)
		assert.NotNil(prv2)
		assert.NotNil(x2)
		assert.NotNil(y2)

		shared1 := ComputeShared(curve, x2, y2, prv1)
		shared2 := ComputeShared(curve, x1, y1, prv2)

		assert.Equal(shared1, shared2)
	}
}
Beispiel #17
0
func GenerateKeys() (PublicKey, PrivateKey, error) {
	priv, x, y, err := elliptic.GenerateKey(curve, rand.Reader)
	if err != nil {
		return nil, nil, err
	}

	pub := elliptic.Marshal(curve, x, y)

	if len(pub) != publicKeySize {
		panic("Public key is incorrect size")
	}

	return pub, priv, nil
}
Beispiel #18
0
// Generates an ephemeral public key and returns a function that will compute
// the shared secret key.  Used in the identify module.
//
// Focuses only on ECDH now, but can be made more general in the future.
func GenerateEKeyPair(curveName string) ([]byte, GenSharedKey, error) {
	var curve elliptic.Curve

	switch curveName {
	case "P-224":
		curve = elliptic.P224()
	case "P-256":
		curve = elliptic.P256()
	case "P-384":
		curve = elliptic.P384()
	case "P-521":
		curve = elliptic.P521()
	}

	priv, x, y, err := elliptic.GenerateKey(curve, rand.Reader)
	if err != nil {
		return nil, nil, err
	}

	var pubKey bytes.Buffer
	pubKey.Write(x.Bytes())
	pubKey.Write(y.Bytes())

	done := func(theirPub []byte) ([]byte, error) {
		// Verify and unpack node's public key.
		curveSize := curve.Params().BitSize

		if len(theirPub) != (curveSize / 4) {
			return nil, errors.New("Malformed public key.")
		}

		bound := (curveSize / 8)
		x := big.NewInt(0)
		y := big.NewInt(0)

		x.SetBytes(theirPub[0:bound])
		y.SetBytes(theirPub[bound : bound*2])

		if !curve.IsOnCurve(x, y) {
			return nil, errors.New("Invalid public key.")
		}

		// Generate shared secret.
		secret, _ := curve.ScalarMult(x, y, priv)

		return secret.Bytes(), nil
	}

	return pubKey.Bytes(), done, nil
}
Beispiel #19
0
func generateKey() *ecdsa.PrivateKey {
	prv, x, y, err := elliptic.GenerateKey(elliptic.P521(), rand.Reader)
	if err != nil {
		fmt.Printf("Key generation failed: %v\n", err.Error())
		os.Exit(1)
	}
	return &ecdsa.PrivateKey{
		D: new(big.Int).SetBytes(prv),
		PublicKey: ecdsa.PublicKey{
			Curve: elliptic.P521(),
			X:     x,
			Y:     y,
		},
	}
}
Beispiel #20
0
func NegativeTest(t *testing.T) {
	var vote *Checkbox
	c := elliptic.P256()
	_, px, py, err := elliptic.GenerateKey(c, rand.Reader)
	if err != nil {
		t.Fail()
	}
	vote = VoteZero(c, px, py)
	vote.c1, err = rand.Int(rand.Reader, c.Params().N)
	if err != nil {
		t.Fail()
	}
	if IsValidBox(c, vote, px, py) {
		t.Fail()
	}
}
Beispiel #21
0
// Generate an elliptic curve public / private keypair. If params is nil,
// the recommended default paramters for the key will be chosen.
func GenerateKey(rand io.Reader, curve elliptic.Curve, params *ECIESParams) (prv *PrivateKey, err error) {
	pb, x, y, err := elliptic.GenerateKey(curve, rand)
	if err != nil {
		return
	}
	prv = new(PrivateKey)
	prv.PublicKey.X = x
	prv.PublicKey.Y = y
	prv.PublicKey.Curve = curve
	prv.D = new(big.Int).SetBytes(pb)
	if params == nil {
		params = ParamsFromCurve(curve)
	}
	prv.PublicKey.Params = params
	return
}
Beispiel #22
0
func GenerateExchangeKey() (pub, priv []byte, err error) {
	priv, x, y, err := elliptic.GenerateKey(curve, rand.Reader)

	if err != nil {
		return nil, nil, err
	}

	pub = elliptic.Marshal(curve, x, y)

	if len(pub) != PublicKeySize {
		panic(fmt.Sprintf(
			"Public key size mismatch: expected %d, actual %d.",
			PublicKeySize, len(pub)))
	}

	return pub, priv, nil
}
Beispiel #23
0
func TestParse(t *testing.T) {
	rsaPriv, err := rsa.GenerateKey(rand.Reader, 2048)
	if err != nil {
		t.Fatalf("%v")
	}

	rsaPub, err := x509.MarshalPKIXPublicKey(&rsaPriv.PublicKey)
	if err != nil {
		t.Fatalf("%v")
	}

	_, x, y, err := elliptic.GenerateKey(elliptic.P256(), rand.Reader)
	if err != nil {
		t.Fatalf("%v")
	}

	pub := elliptic.Marshal(elliptic.P256(), x, y)
	if err != nil {
		t.Fatalf("%v")
	}

	if _, err = ParseECPublicKey(rsaPub); err == nil {
		t.Fatal("Expected RSA public key to fail to parse as a PKIX EC key")
	}

	if _, err = ParseECPublicKey(pub); err == nil {
		t.Fatal("Expected EC public key to fail to parse as a PKIX EC key")
	}

	ecdsaPriv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
	if err != nil {
		t.Fatalf("%v")
	}

	pub, err = x509.MarshalPKIXPublicKey(&ecdsaPriv.PublicKey)
	if err != nil {
		t.Fatalf("%v")
	}

	_, err = ParseECPublicKey(pub)
	if err != nil {
		t.Fatalf("%v")
	}
}
Beispiel #24
0
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
				break NextCandidate
			}
		}
	}

	if 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 x, y *big.Int
	var err error
	ka.privateKey, x, y, err = elliptic.GenerateKey(ka.curve, config.rand())
	if err != nil {
		return nil, err
	}
	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)
	if config.Bugs.InvalidSKXCurve {
		serverECDHParams[2] ^= 0xff
	}
	serverECDHParams[3] = byte(len(ecdhePublic))
	copy(serverECDHParams[4:], ecdhePublic)

	return ka.auth.signParameters(config, cert, clientHello, hello, serverECDHParams)
}
Beispiel #25
0
func TestElection(t *testing.T) {
	c := elliptic.P256()
	var s [3]*Reckoning
	priv, px, py, err := elliptic.GenerateKey(c, rand.Reader)
	if err != nil {
		t.Fail()
		return
	}
	b1, err := UnmarshalBallot(c,
		MarshalBallot(c, FillBallot(c, px, py, 0, 2)))
	if err != nil {
		t.Log(err.Error())
		t.Fail()
		return
	}
	b2 := FillBallot(c, px, py, 0, 2)
	b3 := FillBallot(c, px, py, 1, 2)
	if !(IsValidBallot(c, px, py, b1) && IsValidBallot(c, px, py, b2) &&
		IsValidBallot(c, px, py, b3)) {
		t.Log("Failed Validation")
		t.Fail()
	}
	s[0] = ExtractReckoning(b1)
	s[1] = ExtractReckoning(b2)
	s[2] = ExtractReckoning(b3)
	s[0], err = UnmarshalReckoning(c, MarshalReckoning(c, s[0]))
	if err != nil {
		t.Fail()
		return
	}
	result := SumReckonings(c, s[0:])
	answer, err := DecryptResults(c, priv, result)
	if err != nil {
		t.Fail()
		return
	}
	if len(answer) != 2 {
		t.Fail()
		return
	}
	if answer[0] != 2 && answer[1] != 1 {
		t.Fail()
	}
}
Beispiel #26
0
func (ka *ecdheKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
	if ka.curveid == 0 {
		return nil, nil, errors.New("tls: missing ServerKeyExchange message")
	}

	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))
	ckx.ciphertext[0] = byte(len(serialized))
	copy(ckx.ciphertext[1:], serialized)

	return preMasterSecret, ckx, nil
}
Beispiel #27
0
func TestCheckandMarks5(t *testing.T) {
	var votes [5]*Checkbox
	var marks [5]*Mark
	c := elliptic.P256()
	priv, px, py, err := elliptic.GenerateKey(c, rand.Reader)
	if err != nil {
		t.Fail()
	}
	for i := 0; i < 5; i++ {
		if i%2 == 0 {
			vote := VoteOne(c, px, py)
			votes[i] = UnmarshalCheckbox(c,
				MarshalCheckbox(c, vote))
		} else {
			votes[i] = VoteZero(c, px, py)
		}
	}
	for i := 0; i < 5; i++ {
		if !IsValidBox(c, votes[i], px, py) {
			t.Fail()
		}
		marks[i] = UnmarshalMark(c, MarshalMark(c, ExtractMark(votes[i])))
		res, bad := DecryptMark(c, marks[i], priv)
		if bad != nil {
			t.Log("invalid vote", i)
			t.Log(marks[i].ax, marks[i].ay,
				marks[i].bx, marks[i].by)
		} else {
			t.Log("vote ", i, " was ", res)
		}
	}

	final := SumMarks(c, marks[:])
	res, bad := DecryptMark(c, final, priv)
	if bad != nil {
		t.Log("failed decryption")
	} else {
		t.Log("got", res, "as result")
	}
	if (bad != nil) || (res != 3) {
		t.Fail()
	}
}
Beispiel #28
0
// Generates an ephemeral public key and returns a function that will compute
// the shared secret key.  Used in the identify module.
//
// Focuses only on ECDH now, but can be made more general in the future.
func GenerateEKeyPair(curveName string) ([]byte, GenSharedKey, error) {
	var curve elliptic.Curve

	switch curveName {
	case "P-224":
		curve = elliptic.P224()
	case "P-256":
		curve = elliptic.P256()
	case "P-384":
		curve = elliptic.P384()
	case "P-521":
		curve = elliptic.P521()
	}

	priv, x, y, err := elliptic.GenerateKey(curve, rand.Reader)
	if err != nil {
		return nil, nil, err
	}

	pubKey := elliptic.Marshal(curve, x, y)
	// log.Debug("GenerateEKeyPair %d", len(pubKey))

	done := func(theirPub []byte) ([]byte, error) {
		// Verify and unpack node's public key.
		x, y := elliptic.Unmarshal(curve, theirPub)
		if x == nil {
			return nil, fmt.Errorf("Malformed public key: %d %v", len(theirPub), theirPub)
		}

		if !curve.IsOnCurve(x, y) {
			return nil, errors.New("Invalid public key.")
		}

		// Generate shared secret.
		secret, _ := curve.ScalarMult(x, y, priv)

		return secret.Bytes(), nil
	}

	return pubKey, done, nil
}
Beispiel #29
0
func (e *ellipticECDH) GenerateKey(rand io.Reader) (crypto.PrivateKey, crypto.PublicKey, error) {
	var d []byte
	var x, y *big.Int
	var priv *ellipticPrivateKey
	var pub *ellipticPublicKey
	var err error

	d, x, y, err = elliptic.GenerateKey(e.curve, rand)
	if err != nil {
		return nil, nil, err
	}

	priv = &ellipticPrivateKey{
		D: d,
	}
	pub = &ellipticPublicKey{
		Curve: e.curve,
		X:     x,
		Y:     y,
	}

	return priv, pub, nil
}
Beispiel #30
-1
func (ka *ecdheKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
	if ka.curve == nil {
		return nil, nil, errors.New("missing ServerKeyExchange message")
	}
	priv, mx, my, err := elliptic.GenerateKey(ka.curve, config.rand())
	if err != nil {
		return nil, nil, err
	}

	ka.clientPrivKey = make([]byte, len(priv))
	copy(ka.clientPrivKey, priv)
	ka.clientX = mx
	ka.clientY = my

	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)

	ckx := new(clientKeyExchangeMsg)
	var body []byte
	ckx.ciphertext = make([]byte, 1+len(serialized))
	ckx.ciphertext[0] = byte(len(serialized))
	body = ckx.ciphertext[1:]
	copy(body, serialized)

	return preMasterSecret, ckx, nil
}