1
2
3
4
5
6
7 package rc4
8
9
10
11
12 import (
13 "os"
14 "strconv"
15 )
16
17
18 type Cipher struct {
19 s [256]byte
20 i, j uint8
21 }
22
23 type KeySizeError int
24
25 func (k KeySizeError) String() string {
26 return "crypto/rc4: invalid key size " + strconv.Itoa(int(k))
27 }
28
29
30
31 func NewCipher(key []byte) (*Cipher, os.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] = uint8(i)
39 }
40 var j uint8 = 0
41 for i := 0; i < 256; i++ {
42 j += 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 func (c *Cipher) XORKeyStream(dst, src []byte) {
51 for i := range src {
52 c.i += 1
53 c.j += c.s[c.i]
54 c.s[c.i], c.s[c.j] = c.s[c.j], c.s[c.i]
55 dst[i] = src[i] ^ c.s[c.s[c.i]+c.s[c.j]]
56 }
57 }
58
59
60
61 func (c *Cipher) Reset() {
62 for i := range c.s {
63 c.s[i] = 0
64 }
65 c.i, c.j = 0, 0
66 }