OSDN Git Service

new repo
[bytom/vapor.git] / vendor / golang.org / x / crypto / chacha20poly1305 / chacha20poly1305.go
1 // Copyright 2016 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 implements the ChaCha20-Poly1305 AEAD as specified in RFC 7539.
6 package chacha20poly1305 // import "golang.org/x/crypto/chacha20poly1305"
7
8 import (
9         "crypto/cipher"
10         "errors"
11 )
12
13 const (
14         // KeySize is the size of the key used by this AEAD, in bytes.
15         KeySize = 32
16         // NonceSize is the size of the nonce used with this AEAD, in bytes.
17         NonceSize = 12
18 )
19
20 type chacha20poly1305 struct {
21         key [32]byte
22 }
23
24 // New returns a ChaCha20-Poly1305 AEAD that uses the given, 256-bit key.
25 func New(key []byte) (cipher.AEAD, error) {
26         if len(key) != KeySize {
27                 return nil, errors.New("chacha20poly1305: bad key length")
28         }
29         ret := new(chacha20poly1305)
30         copy(ret.key[:], key)
31         return ret, nil
32 }
33
34 func (c *chacha20poly1305) NonceSize() int {
35         return NonceSize
36 }
37
38 func (c *chacha20poly1305) Overhead() int {
39         return 16
40 }
41
42 func (c *chacha20poly1305) Seal(dst, nonce, plaintext, additionalData []byte) []byte {
43         if len(nonce) != NonceSize {
44                 panic("chacha20poly1305: bad nonce length passed to Seal")
45         }
46
47         if uint64(len(plaintext)) > (1<<38)-64 {
48                 panic("chacha20poly1305: plaintext too large")
49         }
50
51         return c.seal(dst, nonce, plaintext, additionalData)
52 }
53
54 var errOpen = errors.New("chacha20poly1305: message authentication failed")
55
56 func (c *chacha20poly1305) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
57         if len(nonce) != NonceSize {
58                 panic("chacha20poly1305: bad nonce length passed to Open")
59         }
60         if len(ciphertext) < 16 {
61                 return nil, errOpen
62         }
63         if uint64(len(ciphertext)) > (1<<38)-48 {
64                 panic("chacha20poly1305: ciphertext too large")
65         }
66
67         return c.open(dst, nonce, ciphertext, additionalData)
68 }
69
70 // sliceForAppend takes a slice and a requested number of bytes. It returns a
71 // slice with the contents of the given slice followed by that many bytes and a
72 // second slice that aliases into it and contains only the extra bytes. If the
73 // original slice has sufficient capacity then no allocation is performed.
74 func sliceForAppend(in []byte, n int) (head, tail []byte) {
75         if total := len(in) + n; cap(in) >= total {
76                 head = in[:total]
77         } else {
78                 head = make([]byte, total)
79                 copy(head, in)
80         }
81         tail = head[len(in):]
82         return
83 }