libgo: Merge from revision 18783:00cce3a34d7e of master library.
[official-gcc.git] / libgo / go / crypto / cipher / cfb.go
blob9b4eebf5b454164c794e6e166f1e2769a1c3adbd
1 // Copyright 2010 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.
5 // CFB (Cipher Feedback) Mode.
7 package cipher
9 type cfb struct {
10 b Block
11 next []byte
12 out []byte
13 outUsed int
15 decrypt bool
18 func (x *cfb) XORKeyStream(dst, src []byte) {
19 for len(src) > 0 {
20 if x.outUsed == len(x.out) {
21 x.b.Encrypt(x.out, x.next)
22 x.outUsed = 0
25 if x.decrypt {
26 // We can precompute a larger segment of the
27 // keystream on decryption. This will allow
28 // larger batches for xor, and we should be
29 // able to match CTR/OFB performance.
30 copy(x.next[x.outUsed:], src)
32 n := xorBytes(dst, src, x.out[x.outUsed:])
33 if !x.decrypt {
34 copy(x.next[x.outUsed:], dst)
36 dst = dst[n:]
37 src = src[n:]
38 x.outUsed += n
42 // NewCFBEncrypter returns a Stream which encrypts with cipher feedback mode,
43 // using the given Block. The iv must be the same length as the Block's block
44 // size.
45 func NewCFBEncrypter(block Block, iv []byte) Stream {
46 return newCFB(block, iv, false)
49 // NewCFBDecrypter returns a Stream which decrypts with cipher feedback mode,
50 // using the given Block. The iv must be the same length as the Block's block
51 // size.
52 func NewCFBDecrypter(block Block, iv []byte) Stream {
53 return newCFB(block, iv, true)
56 func newCFB(block Block, iv []byte, decrypt bool) Stream {
57 blockSize := block.BlockSize()
58 if len(iv) != blockSize {
59 // stack trace will indicate whether it was de or encryption
60 panic("cipher.newCFB: IV length must equal block size")
62 x := &cfb{
63 b: block,
64 out: make([]byte, blockSize),
65 next: make([]byte, blockSize),
66 outUsed: blockSize,
67 decrypt: decrypt,
69 copy(x.next, iv)
71 return x