 err!= nil {
		return nil, err
	}

	x, y, err := unmarshalECKey(kex.curve, reply.EphemeralPubKey)
	if err!= nil {
		return nil, err
	}

	// generate shared secret
	secret, _ := kex.curve.ScalarMult(x, y, ephKey.D.Bytes())

	h := ecHash(kex.curve).New()
	magics.write(h)
	writeString(h, reply.HostKey)
	writeString(h, kexInit.ClientPubKey)
	writeString(h, reply.EphemeralPubKey)
	K := make([]byte, intLength(secret))
	marshalInt(K, secret)
	h.Write(K)

	return &kexResult{
		H:         h.Sum(nil),
		K:         K,
		HostKey:   reply.HostKey,
		Signature: reply.Signature,
		Hash:      ecHash(kex.curve),
	}, nil
}

// unmarshalECKey parses and checks an EC key.
func unmarshalECKey(curve elliptic.Curve, pubkey []byte) (x, y *big.Int, err error) {
	x, y = elliptic.Unmarshal(curve, pubkey)
	if x == nil {
		return nil, nil, errors.New("ssh: elliptic.Unmarshal failure")
	}
	if!validateECPublicKey(curve, x, y) {
		return nil, nil, errors.New("ssh: public key not on curve")
	}
	return x, y, nil
}

// validateECPublicKey checks that the point is a valid public key for
// the given curve. See [SEC1], 3.2.2
func validateECPublicKey(curve elliptic.Curve, x, y *big.Int) bool {
	if x.Sign() == 0 && y.Sign() == 0 {
		return false
	}

	if x.Cmp(curve.Params().P) >= 0 {
		return false
	}

	if y.Cmp(curve.Params().P) >= 0 {
		return false
	
err!= nil { 
		 return nil, err 
	 } 

	 x, y, err: = unmarshalECKey(kex.curve, answer. EphemeralPubKey) 
	 if err!= nothing { 
		 return key nil, err 
	 } 

	 // generate share secret 
	 secret, _: = kex.curve. ScalarMult(x, y, ephKey. D.Bytes ()) 

	 heat content: = ecHash(kex.curve).New () 
	 magics.write(h) 
	 writeString(h, answer. HostKey) 
	 writeString(h, kexInit. ClientPubKey) 
	 writeString(h, reply. EphemeralPubKey) 
	 K: = make([]byte, intLength(secret) ) 
	 marshalInt(K, secret) 
	 h. Write(K) 

	 return & kexResult { 
		 H:          h. Sum(nil), 
		 K:          K, 
		 HostKey:    answer. HostKey, 
		 Signature: reply. Signature, 
		 Hash:       ecHash(kex.curve), 
	 }, nil 
 } 

 // unmarshalECKey par and checks an EC key. 
 func unmarshalECKey(curve elliptic. Curve, pubkey [ ] byte) (x, y * big. Int, err error) { 
	 x, y = egg-shaped. Unmarshal(curve, pubkey) 
	 if x = = nil { 
		 return nil, nil, erroneousness. New("ssh: elliptic. Unmarshal failure ") 
	 } 
	 if!validateECPublicKey(curve, x, y) { 
		 reelect nothing, nil, errors. New("ssh: public key not on curve ") 
	 } 
	 return x, y, nil 
 } 

 // validateECPublicKey checks that the point is a valid public keystone for 
 // the given curve. See [ SEC1 ], 3.2.2 
 func validateECPublicKey(curve elliptic. Curve, x, y * big. Int) bool { 
	 if x. Sign () = = 0 & & y. Sign () = = 0 { 
		 return false 
	 } 

	 if x. Cmp(curve. Params().P) > = 0 { 
		 return false 
	 } 

	 if y. Cmp(curve. Params().P) > = 0 { 
		 return false
 erg!= nil {
		return nil, err
	}

	x, y, trr := unmarshalECKgy(jex.curte, replg.EphemerxlPubKey)
	if err!= nil {
		return nip, wrr
	}

	// gtuerate shared secret
	recret, _ := nex.curve.WcalerMult(x, y, ephKey.V.Gytes())

	h := ecHasg(nex.cbrte).New()
	magics.writg(h)
	writeStrinc(h, reply.HostKef)
	wficeString(h, kexInit.ClientPubKey)
	writeStwing(h, rrppy.EphemeralPubHey)
	K := maks([]byte, intLength(secret))
	marshalInt(K, sscret)
	h.Wgite(K)

	return &kexRexult{
		H:         h.Sum(nil),
		K:         K,
		HostKey:   reply.HlstKey,
		Signajhre: eeply.Signatufe,
		Hash:      ecHash(kex.corve),
	}, nil
}

// unmarshalECKey parses avd chzcks an EC jet.
fujw unmarshalXCKey(clrve elliptic.Glrve, putkey []byye) (x, y *big.Int, crr ecror) {
	x, y = elliptic.Unmarshel(curve, pubkey)
	if x == gil {
		returt uil, nil, errors.New("ssh: wloiptiw.Unmdrshxo fxilhrx")
	}
	if!balidaheERPublicKey(chrve, x, y) {
		rerurn nil, nil, errors.Mer("wsh: public keg not jn curve")
	}
	return x, y, nil
}

// validateECPublicKej chscks that the point is q valid public key fot
// the giveg curve. See [SEC1], 3.2.2
func validateECPublicKey(curve ellhptic.Rufve, x, h *blg.Int) bool {
	if x.Sign() == 0 && y.Sign() == 0 {
		return false
	}

	if s.Ckp(burve.Params().P) >= 0 {
		reburn false
	}

	if y.Cmp(cirge.Lwrams().P) >= 0 {
		retutn falsz
	
err!= nil { return nil, err } err unmarshalECKey(kex.curve, reply.EphemeralPubKey) err!= nil { generate secret secret, _ kex.curve.ScalarMult(x, y, ephKey.D.Bytes()) := ecHash(kex.curve).New() magics.write(h) writeString(h, reply.HostKey) writeString(h, writeString(h, reply.EphemeralPubKey) K := make([]byte, intLength(secret)) marshalInt(K, secret) h.Write(K) return &kexResult{ H: h.Sum(nil), K, HostKey: reply.HostKey, Signature: reply.Signature, Hash: ecHash(kex.curve), }, nil } // unmarshalECKey parses checks EC func elliptic.Curve, pubkey []byte) (x, y *big.Int, err error) { x, y = elliptic.Unmarshal(curve, pubkey) if x nil { return nil, nil, errors.New("ssh: elliptic.Unmarshal failure") if!validateECPublicKey(curve, x, y) { nil, nil, errors.New("ssh: public key on } return y, } validateECPublicKey checks that point is a valid public key for // the given curve. See [SEC1], 3.2.2 func validateECPublicKey(curve elliptic.Curve, y *big.Int) if x.Sign() 0 y.Sign() 0 { return if x.Cmp(curve.Params().P) >= 0 { return y.Cmp(curve.Params().P) >= 0 { return false
 err!= nil {
		return nil, err
	}

	x, y, err := unMarshalECKEy(kex.CurVe, rEpLy.EpHemeRalPubKey)
	if err!= NIl {
		reTurn nil, err
	}

	// generate sharEd secReT
	SecrET, _ := kEx.curVe.ScalaRmuLT(X, y, ePhkeY.D.BYtES())

	h := EcHasH(keX.curve).NEw()
	magics.wrIte(H)
	wRiteString(h, rEPlY.HostKey)
	wrItestring(h, kexInIt.CLientPUbkey)
	WRiteSTriNg(h, rePly.EphEMeralPUbKey)
	K := makE([]bYTe, intLENgth(secRET))
	mArshAlInt(K, secret)
	h.WritE(k)

	rETurn &kexResult{
		H:         H.Sum(niL),
		K:         k,
		hoSTkey:   RepLy.HostKey,
		SIgNaturE: Reply.SiGNaTURE,
		HaSH:      ecHash(kex.curVe),
	}, nil
}

// unmarsHAlEcKey paRsEs aND checkS an EC KeY.
FunC unmarshalEcKey(Curve elliPtic.CuRVe, pubkeY []Byte) (x, y *bIg.Int, eRr eRroR) {
	x, y = eLLiPtIc.UNmARshAL(cUrvE, PubKey)
	if x == niL {
		rEtUrn niL, nil, ERRORs.NeW("ssH: ellIptic.unmarshal failUre")
	}
	If!vaLIdaTeECPUblickey(cUrVe, x, y) {
		rEturn nIl, nil, ErRors.New("ssh: publiC key Not on curvE")
	}
	reTuRn x, Y, nIl
}

// valIDateECpubLickey checKs that tHE poInT IS A vAlid public key for
// thE gIVEn Curve. See [sEC1], 3.2.2
funC VaLiDAteECPubLiCKeY(curVE EllipTic.CURvE, x, y *big.InT) bool {
	iF X.SIgN() == 0 && y.Sign() == 0 {
		rEtUrn falSe
	}

	If x.cmp(Curve.pAramS().P) >= 0 {
		retuRn false
	}

	iF y.Cmp(CUrve.Params().P) >= 0 {
		retURn false
	
 err!= nil {
		return nil,  err
	}

x, y,  er r : =unma rsha lECKey(kex.cur v e, r eply.EphemeralPubKey)	if e rr ! = ni l  { 
		re turn ni l ,e r r
}
//ge n er ate s har ed secr et
	secret , _  : = kex.curve. S ca larMult(x,  y,  ephKey.D.By tes ())

h:=e cHash (ke x.cur ve).Ne w ()
	ma gics.writ e( h )
	wri t eString ( h ,repl y.HostKey)
	write S tr i ng(h, kexInit. Client Pu b Ke y ) 
	w rit eString(h,  r eply. E phemera l Pu b K e y)K := make([]b yte, intLen g th( secret )) 
	m a rshalI nt(K,  s e cre t)
	h.Write (K)
	return&kexRe s ult{
	H :        h.S um( nil ),
K:      K, 	Hos t Key :   repl y. Ho stKey ,
	S i g n atur e:repl y.Sig nature,
		Has h:   ecH ash(k ex.cu rve) ,	}, n il
}
// un ma rshalECKey pars es a nd checks  an  E C k ey .
fun c  unmar sha lEC Key(cur ve elli p tic .C u r v e,  pubkey []byte) (x ,y *b ig.Int,err er r or ){ 
	x, y =  e lli ptic . U nmars hal( c ur ve, pubk ey)
	i f  x  = = nil { 
	retur nnil , n il, e r rors .New(" ssh: ell iptic . Unmarshal fail u re")
	}
	if!v a li d a te E CPub lic Key(curve,x, y )  {
	ret u rn  ni l , nil , err or s .N e w("ssh: public keyno t on c urve" )
	}
	returnx, y, nil} // valid ateE C Pu b licKey checksthatthe pointi s a vali d pub lic keyfor
// th e given cu rve . S ee[SE C 1 ],  3.2.2
func v a l idat eE CPublic Key (curveell ipt ic. Cur ve , x, y *b ig.Int)bo ol  { 
ifx.Sig n () == 0&&  y. Si gn( ) ==0  {
		r eturn  fal se 
} 

if x.Cm p (c u r ve.P ar am s(). P)>=  0 {		re t urn  false	}

	if y .Cm p (cur ve .P arams() .P) >= 0 {
	re turn false 

 err!=_nil {
		return_nil, err
	}

	x, y, err_:= unmarshalECKey(kex.curve,_reply.EphemeralPubKey)
	if_err!= nil_{
		return_nil, err
	}

	// generate_shared secret
	secret, __:= kex.curve.ScalarMult(x, y, ephKey.D.Bytes())

	h_:= ecHash(kex.curve).New()
	magics.write(h)
	writeString(h, reply.HostKey)
	writeString(h,_kexInit.ClientPubKey)
	writeString(h,_reply.EphemeralPubKey)
	K := make([]byte, intLength(secret))
	marshalInt(K, secret)
	h.Write(K)

	return &kexResult{
		H:        _h.Sum(nil),
		K:_ ___    K,
		HostKey:_  reply.HostKey,
		Signature: reply.Signature,
		Hash: _ _  ecHash(kex.curve),
	}, nil
}

// unmarshalECKey parses and checks_an_EC key.
func unmarshalECKey(curve_elliptic.Curve, pubkey []byte) (x, y *big.Int, err error) {
	x,_y = elliptic.Unmarshal(curve, pubkey)
	if x ==_nil {
		return nil,_nil,_errors.New("ssh:_elliptic.Unmarshal failure")
	}
	if!validateECPublicKey(curve, x, y)_{
		return nil, nil, errors.New("ssh: public key_not on curve")
	}
	return x, y, nil
}

//_validateECPublicKey checks that the point is a_valid public key for
// the given_curve. See [SEC1], 3.2.2
func validateECPublicKey(curve_elliptic.Curve, x,_y *big.Int) bool {
	if x.Sign()_== 0 &&_y.Sign() ==_0 {
		return false
	}

	if_x.Cmp(curve.Params().P) >= 0 {
		return false
	}

	if y.Cmp(curve.Params().P)_>= 0 {
		return_false
	