1
2
3
4
5
6
7
8
9
10 package rc4
11
12 import (
13 "crypto/internal/alias"
14 "strconv"
15 )
16
17
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
30
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
49
50
51
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
60
61 func (c *Cipher) XORKeyStream(dst, src []byte) {
62 if len(src) == 0 {
63 return
64 }
65 if alias.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)]
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 }
81
View as plain text