You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: chacha_generic.go
    path of file: ./repos/kubeedge/vendor/golang.org/x/crypto/chacha20
    
    the code of the file until where you have to start completion: // Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package chacha20 implements the ChaCha20 and XChaCha20 encryption algorithms
// as specified in RFC 8439 and draft-irtf-cfrg-xchacha-01.
package chacha20

import (
	"crypto/cipher"
	"encoding/binary"
	"errors"
	"math/bits"

	"golang.org/x/crypto/internal/alias"
)

const (
	// KeySize is the size of the key used by this cipher, in bytes.
	KeySize = 32

	// NonceSize is the size of the nonce used with the standard variant of this
	// cipher, in bytes.
	//
	// Note that this is too short to be safely generated at random if the same
	// key is reused more than 2³² times.
	NonceSize = 12

	// NonceSizeX is the size of the nonce used with the XChaCha20 variant of
	// this cipher, in bytes.
	NonceSizeX = 24
)

// Cipher is a stateful instance of ChaCha20 or XChaCha20 using a particular key
// and nonce. A *Cipher implements the cipher.Stream interface.
type Cipher struct {
	// The ChaCha20 state is 16 words: 4 constant, 8 of key, 1 of counter
	// (incremented after each block), and 3 of nonce.
	key     [8]uint32
	counter uint32
	nonce   [3]uint32

	// The last len bytes of buf are leftover key stream bytes from the previous
	// XORKeyStream invocation. The size of buf depends on how many blocks are
	// computed at a time by xorKeyStreamBlocks.
	buf [bufSize]byte
	len int

	// overflow is set when the counter overflowed, no more blocks can be
	// generated, and the next XORKeyStream call should panic.
	overflow bool

	// The counter-independent results of the first round are cached after they
	// are computed the first time.
	precompDone      bool
	p1, p5, p9, p13  uint32
	p2, p6, p10, p14 uint32
	p3, p7, p11, p15 uint32
}

var _ cipher.Stream = (*Cipher)(nil)

// NewUnauthenticatedCipher creates a new ChaCha20 stream cipher with the given
// 32 bytes key and a 12 or 24 bytes nonce. If a nonce of 24 bytes is provided,
// the XChaCha20 construction will be used. It returns an error if key or nonce
// have any other length.
//
// Note that ChaCha20, l
    
func (s *Cipher) XORKeyStream(dst, src []byte) {
	if len(src) == 0 {
		return
	}
	if len(dst) < len(src) {
		panic("chacha20: output smaller than input")
	}
	dst = dst[:len(src)]
	if alias.InexactOverlap(dst, src) {
		panic("chacha20: invalid buffer overlap")
	}

	// First, drain any remaining key stream from a previous XORKeyStream.
	if s.len != 0 {
		keyStream := s.buf[bufSize-s.len:]
		if len(src) < len(keyStream) {
			keyStream = keyStream[:len(src)]
		}
		_ = src[len(keyStream)-1] // bounds check elimination hint
		for i, b := range keyStream {
			dst[i] = src[i] ^ b
		}
		s.len -= len(keyStream)
		dst, src = dst[len(keyStream):], src[len(keyStream):]
	}
	if len(src) == 0 {
		return
	}

	// If we'd need to let the counter overflow and keep generating output,
	// panic immediately. If instead we'd only reach the last block, remember
	// not to generate any more output after the buffer is drained.
	numBlocks := (uint64(len(src)) + blockSize - 1) / blockSize
	if s.overflow || uint64(s.counter)+numBlocks > 1<<32 {
		panic("chacha20: counter overflow")
	} else if uint64(s.counter)+numBlocks == 1<<32 {
		s.overflow = true
	}

	// xorKeyStreamBlocks implementations expect input lengths that are a
	// multiple of bufSize. Platform-specific ones process multiple blocks at a
	// time, so have bufSizes that are a multiple of blockSize.

	full := len(src) - len(src)%bufSize
	if full > 0 {
		s.xorKeyStreamBlocks(dst[:full], src[:full])
	}
	dst, src = dst[full:], src[full:]

	// If using a multi-block xorKeyStreamBlocks would overflow, use the generic
	// one that does one block at a time.
	const blocksPerBuf = bufSize / blockSize
	if uint64(s.counter)+blocksPerBuf > 1<<32 {
		s.buf = [bufSize]byte{}
		numBlocks := (len(src) + blockSize - 1) / blockSize
		buf := s.buf[bufSize-numBlocks*blockSize:]
		copy(buf, src)
		s.xorKeyStreamBlocksGeneric(buf, buf)
		s.len = len(buf) - copy(dst, buf)
		return
	}

	// If we have a partial (multi-)block, pad it for xorKeyStreamBlocks, and
	// keep the leftover keystream for the next XORKeyStream invocation.
	if len(src) > 0 {
		s.buf = [bufSize]byte{}
		copy(s.buf[:], src)
		s.xorKeyStreamBlocks(s.buf[:], s.buf[:])
		s.len = bufSize - copy(dst, s.buf[:])
	}
}