package handshake

import (
	
	
	
	
	
	

	
)

// TokenProtectorKey is the key used to encrypt both Retry and session resumption tokens.
type TokenProtectorKey [32]byte

const tokenNonceSize = 32

// tokenProtector is used to create and verify a token
type tokenProtector struct {
	key TokenProtectorKey
}

// newTokenProtector creates a source for source address tokens
func newTokenProtector( TokenProtectorKey) *tokenProtector {
	return &tokenProtector{key: }
}

// NewToken encodes data into a new token.
func ( *tokenProtector) ( []byte) ([]byte, error) {
	var  [tokenNonceSize]byte
	if ,  := rand.Read([:]);  != nil {
		return nil, 
	}
	, ,  := .createAEAD([:])
	if  != nil {
		return nil, 
	}
	return append([:], .Seal(nil, , , nil)...), nil
}

// DecodeToken decodes a token.
func ( *tokenProtector) ( []byte) ([]byte, error) {
	if len() < tokenNonceSize {
		return nil, fmt.Errorf("token too short: %d", len())
	}
	 := [:tokenNonceSize]
	, ,  := .createAEAD()
	if  != nil {
		return nil, 
	}
	return .Open(nil, , [tokenNonceSize:], nil)
}

func ( *tokenProtector) ( []byte) (cipher.AEAD, []byte, error) {
	 := hkdf.New(sha256.New, .key[:], , []byte("quic-go token source"))
	 := make([]byte, 32) // use a 32 byte key, in order to select AES-256
	if ,  := io.ReadFull(, );  != nil {
		return nil, nil, 
	}
	 := make([]byte, 12)
	if ,  := io.ReadFull(, );  != nil {
		return nil, nil, 
	}
	,  := aes.NewCipher()
	if  != nil {
		return nil, nil, 
	}
	,  := cipher.NewGCM()
	if  != nil {
		return nil, nil, 
	}
	return , , nil
}