package  tls13 
 
import  ( 
	"crypto/internal/fips140/hkdf"  
	"crypto/internal/fips140deps/byteorder"  
	"hash"  
) 
 
 
 
 
 
 
func  ExpandLabel  [H  hash .Hash ](hash  func () H , secret  []byte , label  string , context  []byte , length  int ) []byte  { 
	if  len ("tls13 " )+len (label ) > 255  || len (context ) > 255  { 
		 
 
 
 
 
 
 
 
		panic ("tls13: label or context too long" ) 
	} 
	hkdfLabel  := make ([]byte , 0 , 2 +1 +len ("tls13 " )+len (label )+1 +len (context )) 
	hkdfLabel  = byteorder .BEAppendUint16 (hkdfLabel , uint16 (length )) 
	hkdfLabel  = append (hkdfLabel , byte (len ("tls13 " )+len (label ))) 
	hkdfLabel  = append (hkdfLabel , "tls13 " ...) 
	hkdfLabel  = append (hkdfLabel , label ...) 
	hkdfLabel  = append (hkdfLabel , byte (len (context ))) 
	hkdfLabel  = append (hkdfLabel , context ...) 
	return  hkdf .Expand (hash , secret , string (hkdfLabel ), length ) 
} 
 
func  extract[H  hash .Hash ](hash  func () H , newSecret , currentSecret  []byte ) []byte  { 
	if  newSecret  == nil  { 
		newSecret  = make ([]byte , hash ().Size ()) 
	} 
	return  hkdf .Extract (hash , newSecret , currentSecret ) 
} 
 
func  deriveSecret[H  hash .Hash ](hash  func () H , secret  []byte , label  string , transcript  hash .Hash ) []byte  { 
	if  transcript  == nil  { 
		transcript  = hash () 
	} 
	return  ExpandLabel (hash , secret , label , transcript .Sum (nil ), transcript .Size ()) 
} 
 
const  ( 
	resumptionBinderLabel         = "res binder"  
	clientEarlyTrafficLabel       = "c e traffic"  
	clientHandshakeTrafficLabel   = "c hs traffic"  
	serverHandshakeTrafficLabel   = "s hs traffic"  
	clientApplicationTrafficLabel = "c ap traffic"  
	serverApplicationTrafficLabel = "s ap traffic"  
	earlyExporterLabel            = "e exp master"  
	exporterLabel                 = "exp master"  
	resumptionLabel               = "res master"  
) 
 
type  EarlySecret  struct  { 
	secret []byte  
	hash   func () hash .Hash  
} 
 
func  NewEarlySecret  [H  hash .Hash ](h  func () H , psk  []byte ) *EarlySecret  { 
	return  &EarlySecret { 
		secret : extract (h , psk , nil ), 
		hash :   func () hash .Hash  { return  h () }, 
	} 
} 
 
func  (s  *EarlySecret ) ResumptionBinderKey () []byte  { 
	return  deriveSecret (s .hash , s .secret , resumptionBinderLabel , nil ) 
} 
 
 
 
func  (s  *EarlySecret ) ClientEarlyTrafficSecret (transcript  hash .Hash ) []byte  { 
	return  deriveSecret (s .hash , s .secret , clientEarlyTrafficLabel , transcript ) 
} 
 
type  HandshakeSecret  struct  { 
	secret []byte  
	hash   func () hash .Hash  
} 
 
func  (s  *EarlySecret ) HandshakeSecret (sharedSecret  []byte ) *HandshakeSecret  { 
	derived  := deriveSecret (s .hash , s .secret , "derived" , nil ) 
	return  &HandshakeSecret { 
		secret : extract (s .hash , sharedSecret , derived ), 
		hash :   s .hash , 
	} 
} 
 
 
 
func  (s  *HandshakeSecret ) ClientHandshakeTrafficSecret (transcript  hash .Hash ) []byte  { 
	return  deriveSecret (s .hash , s .secret , clientHandshakeTrafficLabel , transcript ) 
} 
 
 
 
func  (s  *HandshakeSecret ) ServerHandshakeTrafficSecret (transcript  hash .Hash ) []byte  { 
	return  deriveSecret (s .hash , s .secret , serverHandshakeTrafficLabel , transcript ) 
} 
 
type  MasterSecret  struct  { 
	secret []byte  
	hash   func () hash .Hash  
} 
 
func  (s  *HandshakeSecret ) MasterSecret () *MasterSecret  { 
	derived  := deriveSecret (s .hash , s .secret , "derived" , nil ) 
	return  &MasterSecret { 
		secret : extract (s .hash , nil , derived ), 
		hash :   s .hash , 
	} 
} 
 
 
 
func  (s  *MasterSecret ) ClientApplicationTrafficSecret (transcript  hash .Hash ) []byte  { 
	return  deriveSecret (s .hash , s .secret , clientApplicationTrafficLabel , transcript ) 
} 
 
 
 
func  (s  *MasterSecret ) ServerApplicationTrafficSecret (transcript  hash .Hash ) []byte  { 
	return  deriveSecret (s .hash , s .secret , serverApplicationTrafficLabel , transcript ) 
} 
 
 
 
func  (s  *MasterSecret ) ResumptionMasterSecret (transcript  hash .Hash ) []byte  { 
	return  deriveSecret (s .hash , s .secret , resumptionLabel , transcript ) 
} 
 
type  ExporterMasterSecret  struct  { 
	secret []byte  
	hash   func () hash .Hash  
} 
 
 
 
func  (s  *MasterSecret ) ExporterMasterSecret (transcript  hash .Hash ) *ExporterMasterSecret  { 
	return  &ExporterMasterSecret { 
		secret : deriveSecret (s .hash , s .secret , exporterLabel , transcript ), 
		hash :   s .hash , 
	} 
} 
 
 
 
func  (s  *EarlySecret ) EarlyExporterMasterSecret (transcript  hash .Hash ) *ExporterMasterSecret  { 
	return  &ExporterMasterSecret { 
		secret : deriveSecret (s .hash , s .secret , earlyExporterLabel , transcript ), 
		hash :   s .hash , 
	} 
} 
 
func  (s  *ExporterMasterSecret ) Exporter (label  string , context  []byte , length  int ) []byte  { 
	secret  := deriveSecret (s .hash , s .secret , label , nil ) 
	h  := s .hash () 
	h .Write (context ) 
	return  ExpandLabel (s .hash , secret , "exporter" , h .Sum (nil ), length ) 
} 
 
func  TestingOnlyExporterSecret  (s  *ExporterMasterSecret ) []byte  { 
	return  s .secret  
} 
  
The pages are generated with Golds   v0.7.9-preview . (GOOS=linux GOARCH=amd64)
Golds  is a Go 101  project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101  (reachable from the left QR code) to get the latest news of Golds .