...
Run Format

Source file src/crypto/cipher/ofb.go

     1	// Copyright 2011 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	// OFB (Output Feedback) Mode.
     6	
     7	package cipher
     8	
     9	type ofb struct {
    10		b       Block
    11		cipher  []byte
    12		out     []byte
    13		outUsed int
    14	}
    15	
    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
    18	// to b's block size.
    19	func NewOFB(b Block, iv []byte) Stream {
    20		blockSize := b.BlockSize()
    21		if len(iv) != blockSize {
    22			return nil
    23		}
    24		bufSize := streamBufferSize
    25		if bufSize < blockSize {
    26			bufSize = blockSize
    27		}
    28		x := &ofb{
    29			b:       b,
    30			cipher:  make([]byte, blockSize),
    31			out:     make([]byte, 0, bufSize),
    32			outUsed: 0,
    33		}
    34	
    35		copy(x.cipher, iv)
    36		return x
    37	}
    38	
    39	func (x *ofb) refill() {
    40		bs := x.b.BlockSize()
    41		remain := len(x.out) - x.outUsed
    42		if remain > x.outUsed {
    43			return
    44		}
    45		copy(x.out, x.out[x.outUsed:])
    46		x.out = x.out[:cap(x.out)]
    47		for remain < len(x.out)-bs {
    48			x.b.Encrypt(x.cipher, x.cipher)
    49			copy(x.out[remain:], x.cipher)
    50			remain += bs
    51		}
    52		x.out = x.out[:remain]
    53		x.outUsed = 0
    54	}
    55	
    56	func (x *ofb) XORKeyStream(dst, src []byte) {
    57		for len(src) > 0 {
    58			if x.outUsed >= len(x.out)-x.b.BlockSize() {
    59				x.refill()
    60			}
    61			n := xorBytes(dst, src, x.out[x.outUsed:])
    62			dst = dst[n:]
    63			src = src[n:]
    64			x.outUsed += n
    65		}
    66	}
    67	

View as plain text