...

Source file src/vendor/golang.org/x/crypto/chacha20poly1305/xchacha20poly1305.go

     1	// Copyright 2018 The Go Authors. All rights reserved.
     2	// Use of this source code is governed by a BSD-style
     3	// license that can be found in the LICENSE file.
     4	
     5	package chacha20poly1305
     6	
     7	import (
     8		"crypto/cipher"
     9		"encoding/binary"
    10		"errors"
    11	
    12		"golang.org/x/crypto/internal/chacha20"
    13	)
    14	
    15	type xchacha20poly1305 struct {
    16		key [8]uint32
    17	}
    18	
    19	// NewX returns a XChaCha20-Poly1305 AEAD that uses the given 256-bit key.
    20	//
    21	// XChaCha20-Poly1305 is a ChaCha20-Poly1305 variant that takes a longer nonce,
    22	// suitable to be generated randomly without risk of collisions. It should be
    23	// preferred when nonce uniqueness cannot be trivially ensured, or whenever
    24	// nonces are randomly generated.
    25	func NewX(key []byte) (cipher.AEAD, error) {
    26		if len(key) != KeySize {
    27			return nil, errors.New("chacha20poly1305: bad key length")
    28		}
    29		ret := new(xchacha20poly1305)
    30		ret.key[0] = binary.LittleEndian.Uint32(key[0:4])
    31		ret.key[1] = binary.LittleEndian.Uint32(key[4:8])
    32		ret.key[2] = binary.LittleEndian.Uint32(key[8:12])
    33		ret.key[3] = binary.LittleEndian.Uint32(key[12:16])
    34		ret.key[4] = binary.LittleEndian.Uint32(key[16:20])
    35		ret.key[5] = binary.LittleEndian.Uint32(key[20:24])
    36		ret.key[6] = binary.LittleEndian.Uint32(key[24:28])
    37		ret.key[7] = binary.LittleEndian.Uint32(key[28:32])
    38		return ret, nil
    39	}
    40	
    41	func (*xchacha20poly1305) NonceSize() int {
    42		return NonceSizeX
    43	}
    44	
    45	func (*xchacha20poly1305) Overhead() int {
    46		return 16
    47	}
    48	
    49	func (x *xchacha20poly1305) Seal(dst, nonce, plaintext, additionalData []byte) []byte {
    50		if len(nonce) != NonceSizeX {
    51			panic("chacha20poly1305: bad nonce length passed to Seal")
    52		}
    53	
    54		// XChaCha20-Poly1305 technically supports a 64-bit counter, so there is no
    55		// size limit. However, since we reuse the ChaCha20-Poly1305 implementation,
    56		// the second half of the counter is not available. This is unlikely to be
    57		// an issue because the cipher.AEAD API requires the entire message to be in
    58		// memory, and the counter overflows at 256 GB.
    59		if uint64(len(plaintext)) > (1<<38)-64 {
    60			panic("chacha20poly1305: plaintext too large")
    61		}
    62	
    63		hNonce := [4]uint32{
    64			binary.LittleEndian.Uint32(nonce[0:4]),
    65			binary.LittleEndian.Uint32(nonce[4:8]),
    66			binary.LittleEndian.Uint32(nonce[8:12]),
    67			binary.LittleEndian.Uint32(nonce[12:16]),
    68		}
    69		c := &chacha20poly1305{
    70			key: chacha20.HChaCha20(&x.key, &hNonce),
    71		}
    72		// The first 4 bytes of the final nonce are unused counter space.
    73		cNonce := make([]byte, NonceSize)
    74		copy(cNonce[4:12], nonce[16:24])
    75	
    76		return c.seal(dst, cNonce[:], plaintext, additionalData)
    77	}
    78	
    79	func (x *xchacha20poly1305) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
    80		if len(nonce) != NonceSizeX {
    81			panic("chacha20poly1305: bad nonce length passed to Open")
    82		}
    83		if len(ciphertext) < 16 {
    84			return nil, errOpen
    85		}
    86		if uint64(len(ciphertext)) > (1<<38)-48 {
    87			panic("chacha20poly1305: ciphertext too large")
    88		}
    89	
    90		hNonce := [4]uint32{
    91			binary.LittleEndian.Uint32(nonce[0:4]),
    92			binary.LittleEndian.Uint32(nonce[4:8]),
    93			binary.LittleEndian.Uint32(nonce[8:12]),
    94			binary.LittleEndian.Uint32(nonce[12:16]),
    95		}
    96		c := &chacha20poly1305{
    97			key: chacha20.HChaCha20(&x.key, &hNonce),
    98		}
    99		// The first 4 bytes of the final nonce are unused counter space.
   100		cNonce := make([]byte, NonceSize)
   101		copy(cNonce[4:12], nonce[16:24])
   102	
   103		return c.open(dst, cNonce[:], ciphertext, additionalData)
   104	}
   105	

View as plain text