source sync 20190409
[platform/core/system/edge-orchestration.git] / vendor / github.com / miekg / dns / vendor / golang.org / x / crypto / tea / cipher.go
1 // Copyright 2015 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 tea implements the TEA algorithm, as defined in Needham and
6 // Wheeler's 1994 technical report, “TEA, a Tiny Encryption Algorithm”. See
7 // http://www.cix.co.uk/~klockstone/tea.pdf for details.
8 package tea
9
10 import (
11         "crypto/cipher"
12         "encoding/binary"
13         "errors"
14 )
15
16 const (
17         // BlockSize is the size of a TEA block, in bytes.
18         BlockSize = 8
19
20         // KeySize is the size of a TEA key, in bytes.
21         KeySize = 16
22
23         // delta is the TEA key schedule constant.
24         delta = 0x9e3779b9
25
26         // numRounds is the standard number of rounds in TEA.
27         numRounds = 64
28 )
29
30 // tea is an instance of the TEA cipher with a particular key.
31 type tea struct {
32         key    [16]byte
33         rounds int
34 }
35
36 // NewCipher returns an instance of the TEA cipher with the standard number of
37 // rounds. The key argument must be 16 bytes long.
38 func NewCipher(key []byte) (cipher.Block, error) {
39         return NewCipherWithRounds(key, numRounds)
40 }
41
42 // NewCipherWithRounds returns an instance of the TEA cipher with a given
43 // number of rounds, which must be even. The key argument must be 16 bytes
44 // long.
45 func NewCipherWithRounds(key []byte, rounds int) (cipher.Block, error) {
46         if len(key) != 16 {
47                 return nil, errors.New("tea: incorrect key size")
48         }
49
50         if rounds&1 != 0 {
51                 return nil, errors.New("tea: odd number of rounds specified")
52         }
53
54         c := &tea{
55                 rounds: rounds,
56         }
57         copy(c.key[:], key)
58
59         return c, nil
60 }
61
62 // BlockSize returns the TEA block size, which is eight bytes. It is necessary
63 // to satisfy the Block interface in the package "crypto/cipher".
64 func (*tea) BlockSize() int {
65         return BlockSize
66 }
67
68 // Encrypt encrypts the 8 byte buffer src using the key in t and stores the
69 // result in dst. Note that for amounts of data larger than a block, it is not
70 // safe to just call Encrypt on successive blocks; instead, use an encryption
71 // mode like CBC (see crypto/cipher/cbc.go).
72 func (t *tea) Encrypt(dst, src []byte) {
73         e := binary.BigEndian
74         v0, v1 := e.Uint32(src), e.Uint32(src[4:])
75         k0, k1, k2, k3 := e.Uint32(t.key[0:]), e.Uint32(t.key[4:]), e.Uint32(t.key[8:]), e.Uint32(t.key[12:])
76
77         sum := uint32(0)
78         delta := uint32(delta)
79
80         for i := 0; i < t.rounds/2; i++ {
81                 sum += delta
82                 v0 += ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1)
83                 v1 += ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3)
84         }
85
86         e.PutUint32(dst, v0)
87         e.PutUint32(dst[4:], v1)
88 }
89
90 // Decrypt decrypts the 8 byte buffer src using the key in t and stores the
91 // result in dst.
92 func (t *tea) Decrypt(dst, src []byte) {
93         e := binary.BigEndian
94         v0, v1 := e.Uint32(src), e.Uint32(src[4:])
95         k0, k1, k2, k3 := e.Uint32(t.key[0:]), e.Uint32(t.key[4:]), e.Uint32(t.key[8:]), e.Uint32(t.key[12:])
96
97         delta := uint32(delta)
98         sum := delta * uint32(t.rounds/2) // in general, sum = delta * n
99
100         for i := 0; i < t.rounds/2; i++ {
101                 v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3)
102                 v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1)
103                 sum -= delta
104         }
105
106         e.PutUint32(dst, v0)
107         e.PutUint32(dst[4:], v1)
108 }