// 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 implements the ChaCha20-Poly1305 AEAD and its // extended nonce variant XChaCha20-Poly1305, as specified in RFC 8439 and // draft-irtf-cfrg-xchacha-01.
package chacha20poly1305 // import "golang.org/x/crypto/chacha20poly1305" import ( ) const ( // KeySize is the size of the key used by this AEAD, in bytes. KeySize = 32 // NonceSize is the size of the nonce used with the standard variant of this // AEAD, 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-Poly1305 // variant of this AEAD, in bytes. NonceSizeX = 24 // Overhead is the size of the Poly1305 authentication tag, and the // difference between a ciphertext length and its plaintext. Overhead = 16 ) type chacha20poly1305 struct { key [KeySize]byte } // New returns a ChaCha20-Poly1305 AEAD that uses the given 256-bit key. func ( []byte) (cipher.AEAD, error) { if len() != KeySize { return nil, errors.New("chacha20poly1305: bad key length") } := new(chacha20poly1305) copy(.key[:], ) return , nil } func ( *chacha20poly1305) () int { return NonceSize } func ( *chacha20poly1305) () int { return Overhead } func ( *chacha20poly1305) (, , , []byte) []byte { if len() != NonceSize { panic("chacha20poly1305: bad nonce length passed to Seal") } if uint64(len()) > (1<<38)-64 { panic("chacha20poly1305: plaintext too large") } return .seal(, , , ) } var errOpen = errors.New("chacha20poly1305: message authentication failed") func ( *chacha20poly1305) (, , , []byte) ([]byte, error) { if len() != NonceSize { panic("chacha20poly1305: bad nonce length passed to Open") } if len() < 16 { return nil, errOpen } if uint64(len()) > (1<<38)-48 { panic("chacha20poly1305: ciphertext too large") } return .open(, , , ) } // sliceForAppend takes a slice and a requested number of bytes. It returns a // slice with the contents of the given slice followed by that many bytes and a // second slice that aliases into it and contains only the extra bytes. If the // original slice has sufficient capacity then no allocation is performed. func sliceForAppend( []byte, int) (, []byte) { if := len() + ; cap() >= { = [:] } else { = make([]byte, ) copy(, ) } = [len():] return }