Left: | ||
Right: |
OLD | NEW |
---|---|
1 // Copyright 2010 The Go Authors. All rights reserved. | 1 // Copyright 2010 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // CFB (Cipher Feedback) Mode. | 5 // CFB (Cipher Feedback) Mode. |
6 | 6 |
7 package cipher | 7 package cipher |
8 | 8 |
9 type cfb struct { | 9 type cfb struct { |
10 b Block | 10 b Block |
11 next []byte | |
11 out []byte | 12 out []byte |
12 outUsed int | 13 outUsed int |
14 | |
15 // We can precompute a larger segment of the keystream on | |
agl1
2013/12/10 18:18:10
Is this a TODO?
hanwen-google
2013/12/10 23:10:28
perhaps? You think I should rather remove the comm
agl
2013/12/11 16:28:26
In which case I think it's ok to keep the comment
| |
16 // decryption. This will allow larger batches for xor, and we | |
17 // should be able to match CTR/OFB performance. | |
13 decrypt bool | 18 decrypt bool |
14 } | 19 } |
15 | 20 |
21 func (x *cfb) XORKeyStream(dst, src []byte) { | |
22 for i := 0; i < len(src); i++ { | |
23 if x.outUsed == len(x.out) { | |
24 x.b.Encrypt(x.out, x.next) | |
25 x.outUsed = 0 | |
26 } | |
27 | |
28 n := xorBytes(dst, src, x.out[x.outUsed:]) | |
29 if x.decrypt { | |
30 copy(x.next[x.outUsed:], src[:n]) | |
31 } else { | |
32 copy(x.next[x.outUsed:], dst[:n]) | |
33 } | |
34 dst = dst[n:] | |
35 src = src[n:] | |
36 x.outUsed += n | |
37 } | |
38 } | |
39 | |
16 // NewCFBEncrypter returns a Stream which encrypts with cipher feedback mode, | 40 // NewCFBEncrypter returns a Stream which encrypts with cipher feedback mode, |
17 // using the given Block. The iv must be the same length as the Block's block | 41 // using the given Block. The iv must be the same length as the Block's block |
18 // size. | 42 // size. |
19 func NewCFBEncrypter(block Block, iv []byte) Stream { | 43 func NewCFBEncrypter(block Block, iv []byte) Stream { |
20 if len(iv) != block.BlockSize() { | |
21 panic("cipher.NewCBFEncrypter: IV length must equal block size") | |
22 } | |
23 return newCFB(block, iv, false) | 44 return newCFB(block, iv, false) |
24 } | 45 } |
25 | 46 |
26 // NewCFBDecrypter returns a Stream which decrypts with cipher feedback mode, | 47 // NewCFBDecrypter returns a Stream which decrypts with cipher feedback mode, |
27 // using the given Block. The iv must be the same length as the Block's block | 48 // using the given Block. The iv must be the same length as the Block's block |
28 // size. | 49 // size. |
29 func NewCFBDecrypter(block Block, iv []byte) Stream { | 50 func NewCFBDecrypter(block Block, iv []byte) Stream { |
30 if len(iv) != block.BlockSize() { | |
31 panic("cipher.NewCBFEncrypter: IV length must equal block size") | |
32 } | |
33 return newCFB(block, iv, true) | 51 return newCFB(block, iv, true) |
34 } | 52 } |
35 | 53 |
36 func newCFB(block Block, iv []byte, decrypt bool) Stream { | 54 func newCFB(block Block, iv []byte, decrypt bool) Stream { |
37 blockSize := block.BlockSize() | 55 blockSize := block.BlockSize() |
38 if len(iv) != blockSize { | 56 if len(iv) != blockSize { |
39 » » return nil | 57 » » // stack trace will indicate whether it was de or encryption |
58 » » panic("cipher.NewCFB: IV length must equal block size") | |
agl1
2013/12/10 18:18:10
s/NewCFB/newCFB/
hanwen-google
2013/12/10 23:10:28
Done.
| |
40 } | 59 } |
41 | |
42 x := &cfb{ | 60 x := &cfb{ |
43 b: block, | 61 b: block, |
44 out: make([]byte, blockSize), | 62 out: make([]byte, blockSize), |
45 » » outUsed: 0, | 63 » » next: make([]byte, blockSize), |
64 » » outUsed: blockSize, | |
46 decrypt: decrypt, | 65 decrypt: decrypt, |
47 } | 66 } |
48 » block.Encrypt(x.out, iv) | 67 » copy(x.next, iv) |
49 | 68 |
50 return x | 69 return x |
51 } | 70 } |
52 | |
53 func (x *cfb) XORKeyStream(dst, src []byte) { | |
54 for i := 0; i < len(src); i++ { | |
55 if x.outUsed == len(x.out) { | |
56 x.b.Encrypt(x.out, x.out) | |
57 x.outUsed = 0 | |
58 } | |
59 | |
60 if x.decrypt { | |
61 t := src[i] | |
62 dst[i] = src[i] ^ x.out[x.outUsed] | |
63 x.out[x.outUsed] = t | |
64 } else { | |
65 x.out[x.outUsed] ^= src[i] | |
66 dst[i] = x.out[x.outUsed] | |
67 } | |
68 x.outUsed++ | |
69 } | |
70 } | |
OLD | NEW |