github.com/varialus/godfly@v0.0.0-20130904042352-1934f9f095ab/src/pkg/crypto/cipher/ctr.go (about)

     1  // Copyright 2009 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  // Counter (CTR) mode.
     6  
     7  // CTR converts a block cipher into a stream cipher by
     8  // repeatedly encrypting an incrementing counter and
     9  // xoring the resulting stream of data with the input.
    10  
    11  // See NIST SP 800-38A, pp 13-15
    12  
    13  package cipher
    14  
    15  type ctr struct {
    16  	b       Block
    17  	ctr     []byte
    18  	out     []byte
    19  	outUsed int
    20  }
    21  
    22  // NewCTR returns a Stream which encrypts/decrypts using the given Block in
    23  // counter mode. The length of iv must be the same as the Block's block size.
    24  func NewCTR(block Block, iv []byte) Stream {
    25  	if len(iv) != block.BlockSize() {
    26  		panic("cipher.NewCTR: IV length must equal block size")
    27  	}
    28  
    29  	return &ctr{
    30  		b:       block,
    31  		ctr:     dup(iv),
    32  		out:     make([]byte, len(iv)),
    33  		outUsed: len(iv),
    34  	}
    35  }
    36  
    37  func (x *ctr) XORKeyStream(dst, src []byte) {
    38  	for i := 0; i < len(src); i++ {
    39  		if x.outUsed == len(x.ctr) {
    40  			x.b.Encrypt(x.out, x.ctr)
    41  			x.outUsed = 0
    42  
    43  			// Increment counter
    44  			for i := len(x.ctr) - 1; i >= 0; i-- {
    45  				x.ctr[i]++
    46  				if x.ctr[i] != 0 {
    47  					break
    48  				}
    49  			}
    50  		}
    51  
    52  		dst[i] = src[i] ^ x.out[x.outUsed]
    53  		x.outUsed++
    54  	}
    55  }