| // Copyright 2009 The Go Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style | 
 | // license that can be found in the LICENSE file. | 
 |  | 
 | // Package rc4 implements RC4 encryption, as defined in Bruce Schneier's | 
 | // Applied Cryptography. | 
 | // | 
 | // RC4 is cryptographically broken and should not be used for secure | 
 | // applications. | 
 | package rc4 | 
 |  | 
 | import ( | 
 | 	"crypto/internal/subtle" | 
 | 	"strconv" | 
 | ) | 
 |  | 
 | // A Cipher is an instance of RC4 using a particular key. | 
 | type Cipher struct { | 
 | 	s    [256]uint32 | 
 | 	i, j uint8 | 
 | } | 
 |  | 
 | type KeySizeError int | 
 |  | 
 | func (k KeySizeError) Error() string { | 
 | 	return "crypto/rc4: invalid key size " + strconv.Itoa(int(k)) | 
 | } | 
 |  | 
 | // NewCipher creates and returns a new Cipher. The key argument should be the | 
 | // RC4 key, at least 1 byte and at most 256 bytes. | 
 | func NewCipher(key []byte) (*Cipher, error) { | 
 | 	k := len(key) | 
 | 	if k < 1 || k > 256 { | 
 | 		return nil, KeySizeError(k) | 
 | 	} | 
 | 	var c Cipher | 
 | 	for i := 0; i < 256; i++ { | 
 | 		c.s[i] = uint32(i) | 
 | 	} | 
 | 	var j uint8 = 0 | 
 | 	for i := 0; i < 256; i++ { | 
 | 		j += uint8(c.s[i]) + key[i%k] | 
 | 		c.s[i], c.s[j] = c.s[j], c.s[i] | 
 | 	} | 
 | 	return &c, nil | 
 | } | 
 |  | 
 | // Reset zeros the key data and makes the Cipher unusable. | 
 | // | 
 | // Deprecated: Reset can't guarantee that the key will be entirely removed from | 
 | // the process's memory. | 
 | func (c *Cipher) Reset() { | 
 | 	for i := range c.s { | 
 | 		c.s[i] = 0 | 
 | 	} | 
 | 	c.i, c.j = 0, 0 | 
 | } | 
 |  | 
 | // XORKeyStream sets dst to the result of XORing src with the key stream. | 
 | // Dst and src must overlap entirely or not at all. | 
 | func (c *Cipher) XORKeyStream(dst, src []byte) { | 
 | 	if len(src) == 0 { | 
 | 		return | 
 | 	} | 
 | 	if subtle.InexactOverlap(dst[:len(src)], src) { | 
 | 		panic("crypto/rc4: invalid buffer overlap") | 
 | 	} | 
 | 	i, j := c.i, c.j | 
 | 	_ = dst[len(src)-1] | 
 | 	dst = dst[:len(src)] // eliminate bounds check from loop | 
 | 	for k, v := range src { | 
 | 		i += 1 | 
 | 		x := c.s[i] | 
 | 		j += uint8(x) | 
 | 		y := c.s[j] | 
 | 		c.s[i], c.s[j] = y, x | 
 | 		dst[k] = v ^ uint8(c.s[uint8(x+y)]) | 
 | 	} | 
 | 	c.i, c.j = i, j | 
 | } |