Left: | ||
Right: |
LEFT | RIGHT |
---|---|
1 // Copyright 2010 The Go Authors. All rights reserved. | 1 // Copyright 2010 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // This package implements Blowfish: a symmetric 64-bit block cipher designed | 5 // This package implements Bruce Schneier's Blowfish encryption algorithm. |
rsc
2010/02/25 09:01:02
the package comment should say what users need to
rsn
2010/02/25 12:23:34
Done.
rsn
2010/02/25 12:23:34
Done.
| |
6 // by Bruce Schneier. | |
7 // The code is a port of Bruce Schneier's C implementation. For up-to-date | |
8 // information on the algorithm see: http://www.schneier.com/blowfish.html | |
9 package blowfish | 6 package blowfish |
7 | |
8 // The code is a port of Bruce Schneier's C implementation. | |
9 // See http://www.schneier.com/blowfish.html. | |
10 | 10 |
11 import ( | 11 import ( |
12 "os" | 12 "os" |
13 "strconv" | 13 "strconv" |
14 ) | 14 ) |
15 | 15 |
16 // The Blowfish block size (64 bits) in bytes. | 16 // The Blowfish block size in bytes. |
rsc
2010/02/25 09:01:02
can drop (64 bits) which is redundant given the de
rsn
2010/02/25 12:23:34
Done.
| |
17 const BlockSize = 8 | 17 const BlockSize = 8 |
18 | 18 |
19 // Cipher is an instance of the internal Blowfish key constructed from user | 19 // A Cipher is an instance of Blowfish encryption using a particular key. |
rsc
2010/02/25 09:01:02
please copy the comments from the AES implementati
rsn
2010/02/25 12:23:34
Done.
| |
20 // supplied key material. | |
21 type Cipher struct { | 20 type Cipher struct { |
22 » p, s0, s1, s2, s3 []uint32 | 21 » p [18]uint32 |
rsc
2010/02/25 09:01:02
Since these are fixed size, the slice is unnecessa
rsn
2010/02/25 12:23:34
Done.
| |
22 » s0, s1, s2, s3 [256]uint32 | |
23 } | 23 } |
24 | 24 |
25 type KeySizeError int | 25 type KeySizeError int |
26 | 26 |
27 func (k KeySizeError) String() string { | 27 func (k KeySizeError) String() string { |
28 » return "crypto/blowfish: Invalid key size " + strconv.Itoa(int(k)) | 28 » return "crypto/blowfish: invalid key size " + strconv.Itoa(int(k)) |
rsc
2010/02/25 09:01:02
lowercase letter after : please. (invalid not Inv
rsn
2010/02/25 12:23:34
Done.
| |
29 } | 29 } |
30 | 30 |
31 // NewCipher creates and returns a new Blowfish Cipher. The 'key' argument | 31 // NewCipher creates and returns a Cipher. |
rsc
2010/02/25 09:01:02
you're in package blowfish already.
no need for qu
rsn
2010/02/25 12:23:34
Done.
| |
32 // MUST be in the range [32..448] bits in increments of 8 bits. | 32 // The key argument should be the Blowfish key, 4 to 56 bytes. |
33 func NewCipher(key []byte) (*Cipher, os.Error) { | 33 func NewCipher(key []byte) (*Cipher, os.Error) { |
34 k := len(key) | 34 k := len(key) |
35 if k < 4 || k > 56 { | 35 if k < 4 || k > 56 { |
36 return nil, KeySizeError(k) | 36 return nil, KeySizeError(k) |
37 } | 37 } |
38 » // allocate space for the cipher's context | 38 » var result Cipher |
rsc
2010/02/25 09:01:02
with the changed Cipher above this shortens to
va
rsn
2010/02/25 12:23:34
Done.
| |
39 » var p = make([]uint32, 18) | 39 » expandKey(key, &result) |
40 » var s0 = make([]uint32, 256) | 40 » return &result, nil |
41 » var s1 = make([]uint32, 256) | |
42 » var s2 = make([]uint32, 256) | |
43 » var s3 = make([]uint32, 256) | |
44 » result := &Cipher{p, s0, s1, s2, s3} | |
45 » expandKey(key, result) | |
46 » return result, nil | |
47 } | 41 } |
48 | 42 |
49 // BlockSize returns the Blowfish block size in bytes. It is needed to | 43 // BlockSize returns the Blowfish block size, 8 bytes. |
50 // satisfy the Key interface in the package "crypto/modes". | 44 // It is necessary to satisfy the Cipher interface in the |
rsc
2010/02/25 09:01:02
re-copy aes comment now that it says crypto/block.
rsn
2010/02/25 12:23:34
Done.
| |
45 // package "crypto/block". | |
51 func (c *Cipher) BlockSize() int { return BlockSize } | 46 func (c *Cipher) BlockSize() int { return BlockSize } |
52 | 47 |
53 // Encrypt enciphers the first 8 bytes (64 bits) in 'src' using the Cipher's | 48 // Encrypt encrypts the 8-byte buffer src using the key k |
rsc
2010/02/25 09:01:02
copy aes comment
rsn
2010/02/25 12:23:34
done but note that this and the next one (for the
| |
54 // internal key and stores the result in the first 8 bytes of 'dst'. | 49 // and stores the result in dst. |
50 // Note that for amounts of data larger than a block, | |
51 // it is not safe to just call Encrypt on successive blocks; | |
52 // instead, use an encryption mode like CBC (see crypto/block/cbc.go). | |
55 func (c *Cipher) Encrypt(src, dst []byte) { | 53 func (c *Cipher) Encrypt(src, dst []byte) { |
56 l := uint32(src[0])<<24 | uint32(src[1])<<16 | uint32(src[2])<<8 | uint3 2(src[3]) | 54 l := uint32(src[0])<<24 | uint32(src[1])<<16 | uint32(src[2])<<8 | uint3 2(src[3]) |
57 r := uint32(src[4])<<24 | uint32(src[5])<<16 | uint32(src[6])<<8 | uint3 2(src[7]) | 55 r := uint32(src[4])<<24 | uint32(src[5])<<16 | uint32(src[6])<<8 | uint3 2(src[7]) |
58 l, r = encryptBlock(l, r, c) | 56 l, r = encryptBlock(l, r, c) |
59 dst[0], dst[1], dst[2], dst[3] = byte(l>>24), byte(l>>16), byte(l>>8), b yte(l) | 57 dst[0], dst[1], dst[2], dst[3] = byte(l>>24), byte(l>>16), byte(l>>8), b yte(l) |
60 dst[4], dst[5], dst[6], dst[7] = byte(r>>24), byte(r>>16), byte(r>>8), b yte(r) | 58 dst[4], dst[5], dst[6], dst[7] = byte(r>>24), byte(r>>16), byte(r>>8), b yte(r) |
61 l, r = 0, 0 | |
rsc
2010/02/25 09:01:02
delete
(compiler will just optimize away)
rsn
2010/02/25 12:23:34
Done.
| |
62 } | 59 } |
63 | 60 |
64 // Decrypt deciphers the first 8 bytes (64 bits) in 'src' using the Cipher's | 61 // Decrypt decrypts the 8-byte buffer src using the key k |
rsc
2010/02/25 09:01:02
copy aes comment
rsn
2010/02/25 12:23:34
Done.
| |
65 // internal key and stores the result in the first 8 bytes of 'dst'. | 62 // and stores the result in dst. |
66 func (c *Cipher) Decrypt(src, dst []byte) { | 63 func (c *Cipher) Decrypt(src, dst []byte) { |
67 l := uint32(src[0])<<24 | uint32(src[1])<<16 | uint32(src[2])<<8 | uint3 2(src[3]) | 64 l := uint32(src[0])<<24 | uint32(src[1])<<16 | uint32(src[2])<<8 | uint3 2(src[3]) |
68 r := uint32(src[4])<<24 | uint32(src[5])<<16 | uint32(src[6])<<8 | uint3 2(src[7]) | 65 r := uint32(src[4])<<24 | uint32(src[5])<<16 | uint32(src[6])<<8 | uint3 2(src[7]) |
69 l, r = decryptBlock(l, r, c) | 66 l, r = decryptBlock(l, r, c) |
70 dst[0], dst[1], dst[2], dst[3] = byte(l>>24), byte(l>>16), byte(l>>8), b yte(l) | 67 dst[0], dst[1], dst[2], dst[3] = byte(l>>24), byte(l>>16), byte(l>>8), b yte(l) |
71 dst[4], dst[5], dst[6], dst[7] = byte(r>>24), byte(r>>16), byte(r>>8), b yte(r) | 68 dst[4], dst[5], dst[6], dst[7] = byte(r>>24), byte(r>>16), byte(r>>8), b yte(r) |
72 l, r = 0, 0 | |
rsc
2010/02/25 09:01:02
delete
rsn
2010/02/25 12:23:34
Done.
| |
73 } | 69 } |
74 | 70 |
75 // Reset zeroes the cipher's internal key. | 71 // Reset zeros the key data, so that it will no longer |
rsc
2010/02/25 09:01:02
copy aes comment
rsn
2010/02/25 12:23:34
Done.
| |
72 // appear in the process's memory. | |
76 func (c *Cipher) Reset() { | 73 func (c *Cipher) Reset() { |
77 » var i int = 0 | 74 » zero(&c.p) |
rsc
2010/02/25 09:01:02
i suggest writing a helper
func zero(x []uint32)
rsn
2010/02/25 12:23:34
Done.
| |
78 » for ; i < 18; i++ { | 75 » zero(&c.s0) |
79 » » c.p[i], c.s0[i], c.s1[i], c.s2[i], c.s3[i] = 0, 0, 0, 0, 0 | 76 » zero(&c.s1) |
80 » } | 77 » zero(&c.s2) |
81 » for ; i < 256; i++ { | 78 » zero(&c.s3) |
82 » » c.s0[i], c.s1[i], c.s2[i], c.s3[i] = 0, 0, 0, 0 | |
83 » } | |
84 } | 79 } |
LEFT | RIGHT |