// 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 chacha20poly1305

import (
	

	
	
	
)

func writeWithPadding( *poly1305.MAC,  []byte) {
	.Write()
	if  := len() % 16;  != 0 {
		var  [16]byte
		 := 16 - 
		.Write([:])
	}
}

func writeUint64( *poly1305.MAC,  int) {
	var  [8]byte
	binary.LittleEndian.PutUint64([:], uint64())
	.Write([:])
}

func ( *chacha20poly1305) (, , ,  []byte) []byte {
	,  := sliceForAppend(, len()+poly1305.TagSize)
	,  := [:len()], [len():]
	if subtle.InexactOverlap(, ) {
		panic("chacha20poly1305: invalid buffer overlap")
	}

	var  [32]byte
	,  := chacha20.NewUnauthenticatedCipher(.key[:], )
	.XORKeyStream([:], [:])
	.SetCounter(1) // set the counter to 1, skipping 32 bytes
	.XORKeyStream(, )

	 := poly1305.New(&)
	writeWithPadding(, )
	writeWithPadding(, )
	writeUint64(, len())
	writeUint64(, len())
	.Sum([:0])

	return 
}

func ( *chacha20poly1305) (, , ,  []byte) ([]byte, error) {
	 := [len()-16:]
	 = [:len()-16]

	var  [32]byte
	,  := chacha20.NewUnauthenticatedCipher(.key[:], )
	.XORKeyStream([:], [:])
	.SetCounter(1) // set the counter to 1, skipping 32 bytes

	 := poly1305.New(&)
	writeWithPadding(, )
	writeWithPadding(, )
	writeUint64(, len())
	writeUint64(, len())

	,  := sliceForAppend(, len())
	if subtle.InexactOverlap(, ) {
		panic("chacha20poly1305: invalid buffer overlap")
	}
	if !.Verify() {
		for  := range  {
			[] = 0
		}
		return nil, errOpen
	}

	.XORKeyStream(, )
	return , nil
}