github.com/geraldss/go/src@v0.0.0-20210511222824-ac7d0ebfc235/crypto/rc4/rc4.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 // Package rc4 implements RC4 encryption, as defined in Bruce Schneier's 6 // Applied Cryptography. 7 // 8 // RC4 is cryptographically broken and should not be used for secure 9 // applications. 10 package rc4 11 12 import ( 13 "crypto/internal/subtle" 14 "strconv" 15 ) 16 17 // A Cipher is an instance of RC4 using a particular key. 18 type Cipher struct { 19 s [256]uint32 20 i, j uint8 21 } 22 23 type KeySizeError int 24 25 func (k KeySizeError) Error() string { 26 return "crypto/rc4: invalid key size " + strconv.Itoa(int(k)) 27 } 28 29 // NewCipher creates and returns a new Cipher. The key argument should be the 30 // RC4 key, at least 1 byte and at most 256 bytes. 31 func NewCipher(key []byte) (*Cipher, error) { 32 k := len(key) 33 if k < 1 || k > 256 { 34 return nil, KeySizeError(k) 35 } 36 var c Cipher 37 for i := 0; i < 256; i++ { 38 c.s[i] = uint32(i) 39 } 40 var j uint8 = 0 41 for i := 0; i < 256; i++ { 42 j += uint8(c.s[i]) + key[i%k] 43 c.s[i], c.s[j] = c.s[j], c.s[i] 44 } 45 return &c, nil 46 } 47 48 // Reset zeros the key data and makes the Cipher unusable. 49 // 50 // Deprecated: Reset can't guarantee that the key will be entirely removed from 51 // the process's memory. 52 func (c *Cipher) Reset() { 53 for i := range c.s { 54 c.s[i] = 0 55 } 56 c.i, c.j = 0, 0 57 } 58 59 // XORKeyStream sets dst to the result of XORing src with the key stream. 60 // Dst and src must overlap entirely or not at all. 61 func (c *Cipher) XORKeyStream(dst, src []byte) { 62 if len(src) == 0 { 63 return 64 } 65 if subtle.InexactOverlap(dst[:len(src)], src) { 66 panic("crypto/rc4: invalid buffer overlap") 67 } 68 i, j := c.i, c.j 69 _ = dst[len(src)-1] 70 dst = dst[:len(src)] // eliminate bounds check from loop 71 for k, v := range src { 72 i += 1 73 x := c.s[i] 74 j += uint8(x) 75 y := c.s[j] 76 c.s[i], c.s[j] = y, x 77 dst[k] = v ^ uint8(c.s[uint8(x+y)]) 78 } 79 c.i, c.j = i, j 80 }