Left: | ||
Right: |
LEFT | RIGHT |
---|---|
1 // Copyright 2011 The Go Authors. All rights reserved. | 1 // Copyright 2011 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 // OFB (Output Feedback) Mode. | 5 // OFB (Output Feedback) Mode. |
6 | 6 |
7 package cipher | 7 package cipher |
8 | 8 |
9 type ofb struct { | 9 type ofb struct { |
10 b Block | 10 b Block |
11 cipher []byte | 11 cipher []byte |
12 out []byte | 12 out []byte |
13 outUsed int | 13 outUsed int |
14 } | 14 } |
15 | 15 |
16 // NewOFB returns a Stream that encrypts or decrypts using the block cipher b | 16 // NewOFB returns a Stream that encrypts or decrypts using the block cipher b |
17 // in output feedback mode. The initialization vector iv's length must be equal | 17 // in output feedback mode. The initialization vector iv's length must be equal |
18 // to b's block size. | 18 // to b's block size. |
19 func NewOFB(b Block, iv []byte) Stream { | 19 func NewOFB(b Block, iv []byte) Stream { |
20 blockSize := b.BlockSize() | 20 blockSize := b.BlockSize() |
21 if len(iv) != blockSize { | 21 if len(iv) != blockSize { |
22 return nil | 22 return nil |
23 } | 23 } |
24 | 24 » bufSize := streamBufferSize |
25 » if bufSize < blockSize { | |
26 » » bufSize = blockSize | |
27 » } | |
25 x := &ofb{ | 28 x := &ofb{ |
26 b: b, | 29 b: b, |
27 cipher: make([]byte, blockSize), | 30 cipher: make([]byte, blockSize), |
28 » » out: make([]byte, 0, streamBufferSize), | 31 » » out: make([]byte, 0, bufSize), |
29 outUsed: 0, | 32 outUsed: 0, |
30 } | 33 } |
31 | 34 |
32 copy(x.cipher, iv) | 35 copy(x.cipher, iv) |
33 return x | 36 return x |
34 } | 37 } |
35 | 38 |
36 func (x *ofb) refill() { | 39 func (x *ofb) refill() { |
37 bs := x.b.BlockSize() | 40 bs := x.b.BlockSize() |
38 remain := len(x.out) - x.outUsed | 41 remain := len(x.out) - x.outUsed |
39 if remain > x.outUsed { | 42 if remain > x.outUsed { |
40 return | 43 return |
41 } | 44 } |
42 copy(x.out, x.out[x.outUsed:]) | 45 copy(x.out, x.out[x.outUsed:]) |
43 x.out = x.out[:cap(x.out)] | 46 x.out = x.out[:cap(x.out)] |
44 » for remain < cap(x.out)-bs { | 47 » for remain < len(x.out)-bs { |
agl1
2013/12/10 18:18:10
again, s/cap/len/ to make the loop clearer.
hanwen-google
2013/12/10 23:10:28
Done.
| |
45 x.b.Encrypt(x.cipher, x.cipher) | 48 x.b.Encrypt(x.cipher, x.cipher) |
46 copy(x.out[remain:], x.cipher) | 49 copy(x.out[remain:], x.cipher) |
47 remain += bs | 50 remain += bs |
48 } | 51 } |
49 x.out = x.out[:remain] | 52 x.out = x.out[:remain] |
50 x.outUsed = 0 | 53 x.outUsed = 0 |
51 } | 54 } |
52 | 55 |
53 func (x *ofb) XORKeyStream(dst, src []byte) { | 56 func (x *ofb) XORKeyStream(dst, src []byte) { |
54 for len(src) > 0 { | 57 for len(src) > 0 { |
55 if x.outUsed >= len(x.out)-x.b.BlockSize() { | 58 if x.outUsed >= len(x.out)-x.b.BlockSize() { |
56 x.refill() | 59 x.refill() |
57 } | 60 } |
58 n := xorBytes(dst, src, x.out[x.outUsed:]) | 61 n := xorBytes(dst, src, x.out[x.outUsed:]) |
59 dst = dst[n:] | 62 dst = dst[n:] |
60 src = src[n:] | 63 src = src[n:] |
61 x.outUsed += n | 64 x.outUsed += n |
62 } | 65 } |
63 } | 66 } |
LEFT | RIGHT |