// Copyright 2017 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package tls

import (
	
	
	
	
	
	
)

// ClientHandshakeState includes both TLS 1.3-only and TLS 1.2-only states,
// only one of them will be used, depending on negotiated version.
//
// ClientHandshakeState will be converted into and from either
//   - clientHandshakeState      (TLS 1.2)
//   - clientHandshakeStateTLS13 (TLS 1.3)
//
// uTLS will call .handshake() on one of these private internal states,
// to perform TLS handshake using standard crypto/tls implementation.
type PubClientHandshakeState struct {
	C            *Conn
	ServerHello  *PubServerHelloMsg
	Hello        *PubClientHelloMsg
	MasterSecret []byte
	Session      *SessionState

	State12 TLS12OnlyState
	State13 TLS13OnlyState

	uconn *UConn
}

// TLS 1.3 only
type TLS13OnlyState struct {
	// Deprecated: Use KeyShareKeys instead. KeyShareKeys will take precedence if both are set.
	// Support may be removed in the future.
	EcdheKey *ecdh.PrivateKey
	// Deprecated: Use KeyShareKeys instead. This variable is no longer used.
	// Will be removed in the future.
	KeySharesParams *KeySharesParameters
	// Deprecated: Use KeyShareKeys instead. This variable is no longer used.
	// Will be removed in the future.
	KEMKey *KemPrivateKey

	KeyShareKeys  *KeySharePrivateKeys
	Suite         *PubCipherSuiteTLS13
	EarlySecret   []byte
	BinderKey     []byte
	CertReq       *CertificateRequestMsgTLS13
	UsingPSK      bool // don't set this field when building client hello
	SentDummyCCS  bool
	Transcript    hash.Hash
	TrafficSecret []byte // client_application_traffic_secret_0
}

// TLS 1.2 and before only
type TLS12OnlyState struct {
	FinishedHash FinishedHash
	Suite        PubCipherSuite
}

func ( *TLS13OnlyState) () *keySharePrivateKeys {
	if .KeyShareKeys != nil {
		return .KeyShareKeys.ToPrivate()
	}

	if .EcdheKey != nil {
		return &keySharePrivateKeys{
			ecdhe: .EcdheKey,
		}
	}

	return nil
}

// func kyberGoToCircl(kyberKey *mlkem768.DecapsulationKey, ecdhKey *ecdh.PrivateKey) (kem.PrivateKey, error) {
// 	return hybrid.Kyber768X25519().UnmarshalBinaryPrivateKey(append(ecdhKey.Bytes(), kyberKey.Bytes()...))
// }

func ( *PubClientHandshakeState) () *clientHandshakeStateTLS13 {
	if  == nil {
		return nil
	} else {
		return &clientHandshakeStateTLS13{
			c:            .C,
			serverHello:  .ServerHello.getPrivatePtr(),
			hello:        .Hello.getPrivatePtr(),
			keyShareKeys: .State13.private13KeyShareKeys(),

			session:   .Session,
			binderKey: .State13.BinderKey,

			certReq:       .State13.CertReq.toPrivate(),
			usingPSK:      .State13.UsingPSK,
			sentDummyCCS:  .State13.SentDummyCCS,
			suite:         .State13.Suite.toPrivate(),
			transcript:    .State13.Transcript,
			trafficSecret: .State13.TrafficSecret,

			uconn: .uconn,
		}
	}
}

func ( *clientHandshakeStateTLS13) () *PubClientHandshakeState {
	if  == nil {
		return nil
	} else {
		 := TLS13OnlyState{
			KeyShareKeys:  .keyShareKeys.ToPublic(),
			EarlySecret:   .earlySecret.Secret(),
			BinderKey:     .binderKey,
			CertReq:       .certReq.toPublic(),
			UsingPSK:      .usingPSK,
			SentDummyCCS:  .sentDummyCCS,
			Suite:         .suite.toPublic(),
			TrafficSecret: .trafficSecret,
			Transcript:    .transcript,
		}
		return &PubClientHandshakeState{
			C:           .c,
			ServerHello: .serverHello.getPublicPtr(),
			Hello:       .hello.getPublicPtr(),

			Session: .session,

			MasterSecret: .masterSecret.Secret(),

			State13: ,

			uconn: .uconn,
		}
	}
}

func ( *PubClientHandshakeState) () *clientHandshakeState {
	if  == nil {
		return nil
	} else {
		return &clientHandshakeState{
			c:           .C,
			serverHello: .ServerHello.getPrivatePtr(),
			hello:       .Hello.getPrivatePtr(),
			suite:       .State12.Suite.getPrivatePtr(),
			session:     .Session,

			masterSecret: .MasterSecret,

			finishedHash: .State12.FinishedHash.getPrivateObj(),

			uconn: .uconn,
		}
	}
}

func ( *clientHandshakeState) () *PubClientHandshakeState {
	if  == nil {
		return nil
	} else {
		 := TLS12OnlyState{
			Suite:        .suite.getPublicObj(),
			FinishedHash: .finishedHash.getPublicObj(),
		}
		return &PubClientHandshakeState{
			C:           .c,
			ServerHello: .serverHello.getPublicPtr(),
			Hello:       .hello.getPublicPtr(),

			Session: .session,

			MasterSecret: .masterSecret,

			State12: ,

			uconn: .uconn,
		}
	}
}

// type EcdheParameters interface {
// 	ecdheParameters
// }

type CertificateRequestMsgTLS13 struct {
	// Deprecated: crypto/tls no longer use this variable. This field won't be read or used by utls, but will still be populated.
	// Support may be removed in the future.
	Raw []byte

	OcspStapling                     bool
	Scts                             bool
	SupportedSignatureAlgorithms     []SignatureScheme
	SupportedSignatureAlgorithmsCert []SignatureScheme
	CertificateAuthorities           [][]byte
}

func ( *certificateRequestMsgTLS13) () *CertificateRequestMsgTLS13 {
	if  == nil {
		return nil
	} else {
		 := []byte{}
		if ,  := .marshal();  == nil {
			 = 
		}

		return &CertificateRequestMsgTLS13{
			Raw:                              ,
			OcspStapling:                     .ocspStapling,
			Scts:                             .scts,
			SupportedSignatureAlgorithms:     .supportedSignatureAlgorithms,
			SupportedSignatureAlgorithmsCert: .supportedSignatureAlgorithmsCert,
			CertificateAuthorities:           .certificateAuthorities,
		}
	}
}

func ( *CertificateRequestMsgTLS13) () *certificateRequestMsgTLS13 {
	if  == nil {
		return nil
	} else {
		return &certificateRequestMsgTLS13{
			ocspStapling:                     .OcspStapling,
			scts:                             .Scts,
			supportedSignatureAlgorithms:     .SupportedSignatureAlgorithms,
			supportedSignatureAlgorithmsCert: .SupportedSignatureAlgorithmsCert,
			certificateAuthorities:           .CertificateAuthorities,
		}
	}
}

type PubCipherSuiteTLS13 struct {
	Id     uint16
	KeyLen int
	Aead   func(key, fixedNonce []byte) aead
	Hash   crypto.Hash
}

func ( *cipherSuiteTLS13) () *PubCipherSuiteTLS13 {
	if  == nil {
		return nil
	} else {
		return &PubCipherSuiteTLS13{
			Id:     .id,
			KeyLen: .keyLen,
			Aead:   .aead,
			Hash:   .hash,
		}
	}
}

func ( *PubCipherSuiteTLS13) () *cipherSuiteTLS13 {
	if  == nil {
		return nil
	} else {
		return &cipherSuiteTLS13{
			id:     .Id,
			keyLen: .KeyLen,
			aead:   .Aead,
			hash:   .Hash,
		}
	}
}

type PubServerHelloMsg struct {
	Raw                          []byte // renamed to serverHelloMsg.original in crypto/tls
	Vers                         uint16
	Random                       []byte
	SessionId                    []byte
	CipherSuite                  uint16
	CompressionMethod            uint8
	NextProtoNeg                 bool
	NextProtos                   []string
	OcspStapling                 bool
	Scts                         [][]byte
	ExtendedMasterSecret         bool
	TicketSupported              bool // used by go tls to determine whether to add the session ticket ext
	SecureRenegotiation          []byte
	SecureRenegotiationSupported bool
	AlpnProtocol                 string

	// 1.3
	SupportedVersion        uint16
	ServerShare             KeyShare
	SelectedIdentityPresent bool
	SelectedIdentity        uint16
	Cookie                  []byte  // HelloRetryRequest extension
	SelectedGroup           CurveID // HelloRetryRequest extension

}

func ( *PubServerHelloMsg) () *serverHelloMsg {
	if  == nil {
		return nil
	} else {
		return &serverHelloMsg{
			original:                     .Raw,
			vers:                         .Vers,
			random:                       .Random,
			sessionId:                    .SessionId,
			cipherSuite:                  .CipherSuite,
			compressionMethod:            .CompressionMethod,
			nextProtoNeg:                 .NextProtoNeg,
			nextProtos:                   .NextProtos,
			ocspStapling:                 .OcspStapling,
			scts:                         .Scts,
			extendedMasterSecret:         .ExtendedMasterSecret,
			ticketSupported:              .TicketSupported,
			secureRenegotiation:          .SecureRenegotiation,
			secureRenegotiationSupported: .SecureRenegotiationSupported,
			alpnProtocol:                 .AlpnProtocol,
			supportedVersion:             .SupportedVersion,
			serverShare:                  .ServerShare.ToPrivate(),
			selectedIdentityPresent:      .SelectedIdentityPresent,
			selectedIdentity:             .SelectedIdentity,
			cookie:                       .Cookie,
			selectedGroup:                .SelectedGroup,
		}
	}
}

func ( *serverHelloMsg) () *PubServerHelloMsg {
	if  == nil {
		return nil
	} else {
		return &PubServerHelloMsg{
			Raw:                          .original,
			Vers:                         .vers,
			Random:                       .random,
			SessionId:                    .sessionId,
			CipherSuite:                  .cipherSuite,
			CompressionMethod:            .compressionMethod,
			NextProtoNeg:                 .nextProtoNeg,
			NextProtos:                   .nextProtos,
			OcspStapling:                 .ocspStapling,
			Scts:                         .scts,
			ExtendedMasterSecret:         .extendedMasterSecret,
			TicketSupported:              .ticketSupported,
			SecureRenegotiation:          .secureRenegotiation,
			SecureRenegotiationSupported: .secureRenegotiationSupported,
			AlpnProtocol:                 .alpnProtocol,
			SupportedVersion:             .supportedVersion,
			ServerShare:                  .serverShare.ToPublic(),
			SelectedIdentityPresent:      .selectedIdentityPresent,
			SelectedIdentity:             .selectedIdentity,
			Cookie:                       .cookie,
			SelectedGroup:                .selectedGroup,
		}
	}
}

type PubClientHelloMsg struct {
	Raw                          []byte // renamed to clientHelloMsg.original in crypto/tls
	Vers                         uint16
	Random                       []byte
	SessionId                    []byte
	CipherSuites                 []uint16
	CompressionMethods           []uint8
	NextProtoNeg                 bool
	ServerName                   string
	OcspStapling                 bool
	Scts                         bool
	Ems                          bool // [uTLS] actually implemented due to its prevalence
	SupportedCurves              []CurveID
	SupportedPoints              []uint8
	TicketSupported              bool
	SessionTicket                []uint8
	SupportedSignatureAlgorithms []SignatureScheme
	SecureRenegotiation          []byte
	SecureRenegotiationSupported bool
	AlpnProtocols                []string

	// 1.3
	SupportedSignatureAlgorithmsCert []SignatureScheme
	SupportedVersions                []uint16
	Cookie                           []byte
	KeyShares                        []KeyShare
	EarlyData                        bool
	PskModes                         []uint8
	PskIdentities                    []PskIdentity
	PskBinders                       [][]byte
	QuicTransportParameters          []byte

	cachedPrivateHello   *clientHelloMsg // todo: further optimize to reduce clientHelloMsg construction
	encryptedClientHello []byte
}

func ( *PubClientHelloMsg) () *clientHelloMsg {
	if  == nil {
		return nil
	} else {
		 := &clientHelloMsg{
			original:                         .Raw,
			vers:                             .Vers,
			random:                           .Random,
			sessionId:                        .SessionId,
			cipherSuites:                     .CipherSuites,
			compressionMethods:               .CompressionMethods,
			serverName:                       .ServerName,
			ocspStapling:                     .OcspStapling,
			supportedCurves:                  .SupportedCurves,
			supportedPoints:                  .SupportedPoints,
			ticketSupported:                  .TicketSupported,
			sessionTicket:                    .SessionTicket,
			supportedSignatureAlgorithms:     .SupportedSignatureAlgorithms,
			supportedSignatureAlgorithmsCert: .SupportedSignatureAlgorithmsCert,
			secureRenegotiationSupported:     .SecureRenegotiationSupported,
			secureRenegotiation:              .SecureRenegotiation,
			extendedMasterSecret:             .Ems,
			alpnProtocols:                    .AlpnProtocols,
			scts:                             .Scts,

			supportedVersions:       .SupportedVersions,
			cookie:                  .Cookie,
			keyShares:               KeyShares(.KeyShares).ToPrivate(),
			earlyData:               .EarlyData,
			pskModes:                .PskModes,
			pskIdentities:           PskIdentities(.PskIdentities).ToPrivate(),
			pskBinders:              .PskBinders,
			quicTransportParameters: .QuicTransportParameters,
			encryptedClientHello:    .encryptedClientHello,

			nextProtoNeg: .NextProtoNeg,
		}
		.cachedPrivateHello = 
		return 
	}
}

func ( *PubClientHelloMsg) () *clientHelloMsg {
	if  == nil {
		return nil
	} else {
		return .cachedPrivateHello
	}
}

func ( *clientHelloMsg) () *PubClientHelloMsg {
	if  == nil {
		return nil
	} else {
		return &PubClientHelloMsg{
			Raw:                          .original,
			Vers:                         .vers,
			Random:                       .random,
			SessionId:                    .sessionId,
			CipherSuites:                 .cipherSuites,
			CompressionMethods:           .compressionMethods,
			NextProtoNeg:                 .nextProtoNeg,
			ServerName:                   .serverName,
			OcspStapling:                 .ocspStapling,
			Scts:                         .scts,
			Ems:                          .extendedMasterSecret,
			SupportedCurves:              .supportedCurves,
			SupportedPoints:              .supportedPoints,
			TicketSupported:              .ticketSupported,
			SessionTicket:                .sessionTicket,
			SupportedSignatureAlgorithms: .supportedSignatureAlgorithms,
			SecureRenegotiation:          .secureRenegotiation,
			SecureRenegotiationSupported: .secureRenegotiationSupported,
			AlpnProtocols:                .alpnProtocols,

			SupportedSignatureAlgorithmsCert: .supportedSignatureAlgorithmsCert,
			SupportedVersions:                .supportedVersions,
			Cookie:                           .cookie,
			KeyShares:                        keyShares(.keyShares).ToPublic(),
			EarlyData:                        .earlyData,
			PskModes:                         .pskModes,
			PskIdentities:                    pskIdentities(.pskIdentities).ToPublic(),
			PskBinders:                       .pskBinders,
			QuicTransportParameters:          .quicTransportParameters,
			cachedPrivateHello:               ,
			encryptedClientHello:             .encryptedClientHello,
		}
	}
}

// UnmarshalClientHello allows external code to parse raw client hellos.
// It returns nil on failure.
func ( []byte) *PubClientHelloMsg {
	 := &clientHelloMsg{}
	if .unmarshal() {
		return .getPublicPtr()
	}
	return nil
}

// Marshal allows external code to convert a ClientHello object back into
// raw bytes.
func ( *PubClientHelloMsg) () ([]byte, error) {
	return .getPrivatePtr().marshal()
}

// A CipherSuite is a specific combination of key agreement, cipher and MAC
// function. All cipher suites currently assume RSA key agreement.
type PubCipherSuite struct {
	Id uint16
	// the lengths, in bytes, of the key material needed for each component.
	KeyLen int
	MacLen int
	IvLen  int
	Ka     func(version uint16) keyAgreement
	// flags is a bitmask of the suite* values, above.
	Flags  int
	Cipher func(key, iv []byte, isRead bool) interface{}
	Mac    func(macKey []byte) hash.Hash
	Aead   func(key, fixedNonce []byte) aead
}

func ( *PubCipherSuite) () *cipherSuite {
	if  == nil {
		return nil
	} else {
		return &cipherSuite{
			id:     .Id,
			keyLen: .KeyLen,
			macLen: .MacLen,
			ivLen:  .IvLen,
			ka:     .Ka,
			flags:  .Flags,
			cipher: .Cipher,
			mac:    .Mac,
			aead:   .Aead,
		}
	}
}

func ( *cipherSuite) () PubCipherSuite {
	if  == nil {
		return PubCipherSuite{}
	} else {
		return PubCipherSuite{
			Id:     .id,
			KeyLen: .keyLen,
			MacLen: .macLen,
			IvLen:  .ivLen,
			Ka:     .ka,
			Flags:  .flags,
			Cipher: .cipher,
			Mac:    .mac,
			Aead:   .aead,
		}
	}
}

// A FinishedHash calculates the hash of a set of handshake messages suitable
// for including in a Finished message.
type FinishedHash struct {
	Client hash.Hash
	Server hash.Hash

	// Prior to TLS 1.2, an additional MD5 hash is required.
	ClientMD5 hash.Hash
	ServerMD5 hash.Hash

	// In TLS 1.2, a full buffer is sadly required.
	Buffer []byte

	Version uint16
	Prfv2   prfFunc

	// Deprecated: Use Prfv2 instead. Prfv2 will be used if both are set.
	Prf prfFuncOld
}

type prfFuncOld func(result, secret, label, seed []byte)

func ( prfFuncOld) prfFunc {
	return func( []byte,  string,  []byte,  int) []byte {
		 := make([]byte, )
		(, , []byte(), )
		return 
	}
}

func ( prfFunc) prfFuncOld {
	return func(, , ,  []byte) {
		copy(, (, string(), , len()))
	}
}

func ( *FinishedHash) () finishedHash {
	if  == nil {
		return finishedHash{}
	} else {
		 := finishedHash{
			client:    .Client,
			server:    .Server,
			clientMD5: .ClientMD5,
			serverMD5: .ServerMD5,
			buffer:    .Buffer,
			version:   .Version,
		}

		if .Prfv2 != nil {
			.prf = .Prfv2
		} else if .Prf != nil {
			.prf = prfFuncV1ToV2(.Prf)
		}

		return 
	}
}

func ( *finishedHash) () FinishedHash {
	if  == nil {
		return FinishedHash{}
	} else {
		 := FinishedHash{
			Client:    .client,
			Server:    .server,
			ClientMD5: .clientMD5,
			ServerMD5: .serverMD5,
			Buffer:    .buffer,
			Version:   .version,
		}

		.Prfv2 = .prf
		.Prf = prfFuncV2ToV1(.prf)

		return 
	}
}

// TLS 1.3 Key Share. See RFC 8446, Section 4.2.8.
type KeyShare struct {
	Group CurveID `json:"group"`
	Data  []byte  `json:"key_exchange,omitempty"` // optional
}

func ( KeyShare) () keyShare {
	return keyShare{group: .Group, data: .Data}
}

func ( keyShare) () KeyShare {
	return KeyShare{Group: .group, Data: .data}
}

type KeyShares []KeyShare
type keyShares []keyShare

func ( keyShares) () []KeyShare {
	var  []KeyShare
	for ,  := range  {
		 = append(, .ToPublic())
	}
	return 
}
func ( KeyShares) () []keyShare {
	var  []keyShare
	for ,  := range  {
		 = append(, .ToPrivate())
	}
	return 
}

// TLS 1.3 PSK Identity. Can be a Session Ticket, or a reference to a saved
// session. See RFC 8446, Section 4.2.11.
type PskIdentity struct {
	Label               []byte `json:"identity"`
	ObfuscatedTicketAge uint32 `json:"obfuscated_ticket_age"`
}

type PskIdentities []PskIdentity
type pskIdentities []pskIdentity

func ( pskIdentities) () []PskIdentity {
	var  []PskIdentity
	for ,  := range  {
		 = append(, PskIdentity{Label: .label, ObfuscatedTicketAge: .obfuscatedTicketAge})
	}
	return 
}

func ( PskIdentities) () []pskIdentity {
	var  []pskIdentity
	for ,  := range  {
		 = append(, pskIdentity{label: .Label, obfuscatedTicketAge: .ObfuscatedTicketAge})
	}
	return 
}

// ClientSessionState is public, but all its fields are private. Let's add setters, getters and constructor

// ClientSessionState contains the state needed by clients to resume TLS sessions.
func (
	 []uint8,
	 uint16,
	 uint16,
	 []byte,
	 []*x509.Certificate,
	 [][]*x509.Certificate) *ClientSessionState {
	// TODO: Add EMS to this constructor in uTLS v2
	 := &ClientSessionState{
		session: &SessionState{
			version:          ,
			cipherSuite:      ,
			secret:           ,
			peerCertificates: ,
			verifiedChains:   ,
			ticket:           ,
		},
	}
	return 
}

// Encrypted ticket used for session resumption with server
func ( *ClientSessionState) () []uint8 {
	return .session.ticket
}

// SSL/TLS version negotiated for the session
func ( *ClientSessionState) () uint16 {
	return .session.version
}

// Ciphersuite negotiated for the session
func ( *ClientSessionState) () uint16 {
	return .session.cipherSuite
}

// MasterSecret generated by client on a full handshake
func ( *ClientSessionState) () []byte {
	return .session.secret
}

func ( *ClientSessionState) () bool {
	return .session.extMasterSecret
}

// Certificate chain presented by the server
func ( *ClientSessionState) () []*x509.Certificate {
	return .session.peerCertificates
}

// Certificate chains we built for verification
func ( *ClientSessionState) () [][]*x509.Certificate {
	return .session.verifiedChains
}

func ( *ClientSessionState) ( []uint8) {
	.session.ticket = 
}

func ( *ClientSessionState) ( uint16) {
	if .session == nil {
		.session = &SessionState{}
	}
	.session.version = 
}

func ( *ClientSessionState) ( uint16) {
	if .session == nil {
		.session = &SessionState{}
	}
	.session.cipherSuite = 
}

func ( *ClientSessionState) ( uint64) {
	if .session == nil {
		.session = &SessionState{}
	}
	.session.createdAt = 
}

func ( *ClientSessionState) ( []byte) {
	if .session == nil {
		.session = &SessionState{}
	}
	.session.secret = 
}

func ( *ClientSessionState) ( bool) {
	if .session == nil {
		.session = &SessionState{}
	}
	.session.extMasterSecret = 
}

func ( *ClientSessionState) ( []*x509.Certificate) {
	if .session == nil {
		.session = &SessionState{}
	}
	.session.peerCertificates = 
}

func ( *ClientSessionState) ( [][]*x509.Certificate) {
	if .session == nil {
		.session = &SessionState{}
	}
	.session.verifiedChains = 
}

func ( *ClientSessionState) ( uint64) {
	if .session == nil {
		.session = &SessionState{}
	}
	.session.useBy = 
}

func ( *ClientSessionState) ( uint32) {
	if .session == nil {
		.session = &SessionState{}
	}
	.session.ageAdd = 
}

// TicketKey is the internal representation of a session ticket key.
type TicketKey struct {
	AesKey  [16]byte
	HmacKey [16]byte
	// created is the time at which this ticket key was created. See Config.ticketKeys.
	Created time.Time
}

type TicketKeys []TicketKey
type ticketKeys []ticketKey

func ( [32]byte) TicketKey {
	// [uTLS]
	// empty config is required
	 := &Config{}
	 := .ticketKeyFromBytes()
	return .ToPublic()
}

func ( ticketKey) () TicketKey {
	return TicketKey{
		AesKey:  .aesKey,
		HmacKey: .hmacKey,
		Created: .created,
	}
}

func ( TicketKey) () ticketKey {
	return ticketKey{
		aesKey:  .AesKey,
		hmacKey: .HmacKey,
		created: .Created,
	}
}

func ( ticketKeys) () []TicketKey {
	var  []TicketKey
	for ,  := range  {
		 = append(, .ToPublic())
	}
	return 
}

func ( TicketKeys) () []ticketKey {
	var  []ticketKey
	for ,  := range  {
		 = append(, .ToPrivate())
	}
	return 
}

type kemPrivateKey struct {
	secretKey any
	curveID   CurveID
}

// Deprecated: Use KeySharePrivateKeys instead. This type is no longer used.
// Will be removed in the future.
type KemPrivateKey struct {
	SecretKey any
	CurveID   CurveID
}

func ( *KemPrivateKey) () *kemPrivateKey {
	if  == nil {
		return nil
	} else {
		return &kemPrivateKey{
			secretKey: .SecretKey,
			curveID:   .CurveID,
		}
	}
}

func ( *kemPrivateKey) () *KemPrivateKey {
	if  == nil {
		return nil
	} else {
		return &KemPrivateKey{
			SecretKey: .secretKey,
			CurveID:   .curveID,
		}
	}
}

type KeySharePrivateKeys struct {
	CurveID    CurveID
	Ecdhe      *ecdh.PrivateKey
	Mlkem      *mlkem.DecapsulationKey768
	MlkemEcdhe *ecdh.PrivateKey
}

func ( *KeySharePrivateKeys) () *keySharePrivateKeys {
	if  == nil {
		return nil
	}
	return &keySharePrivateKeys{
		curveID:    .CurveID,
		ecdhe:      .Ecdhe,
		mlkem:      .Mlkem,
		mlkemEcdhe: .MlkemEcdhe,
	}
}

func ( *keySharePrivateKeys) () *KeySharePrivateKeys {
	if  == nil {
		return nil
	}
	return &KeySharePrivateKeys{
		CurveID:    .curveID,
		Ecdhe:      .ecdhe,
		Mlkem:      .mlkem,
		MlkemEcdhe: .mlkemEcdhe,
	}
}