1 // Copyright 2011 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.
5 // Package twofish implements Bruce Schneier's Twofish encryption algorithm.
6 package twofish // import "golang.org/x/crypto/twofish"
8 // Twofish is defined in https://www.schneier.com/paper-twofish-paper.pdf [TWOFISH]
10 // This code is a port of the LibTom C implementation.
11 // See http://libtom.org/?page=features&newsitems=5&whatfile=crypt.
12 // LibTomCrypt is free for all purposes under the public domain.
13 // It was heavily inspired by the go blowfish package.
17 // BlockSize is the constant block size of Twofish.
20 const mdsPolynomial = 0x169 // x^8 + x^6 + x^5 + x^3 + 1, see [TWOFISH] 4.2
21 const rsPolynomial = 0x14d // x^8 + x^6 + x^3 + x^2 + 1, see [TWOFISH] 4.3
23 // A Cipher is an instance of Twofish encryption using a particular key.
31 func (k KeySizeError) Error() string {
32 return "crypto/twofish: invalid key size " + strconv.Itoa(int(k))
35 // NewCipher creates and returns a Cipher.
36 // The key argument should be the Twofish key, 16, 24 or 32 bytes.
37 func NewCipher(key []byte) (*Cipher, error) {
40 if keylen != 16 && keylen != 24 && keylen != 32 {
41 return nil, KeySizeError(keylen)
44 // k is the number of 64 bit words in key
47 // Create the S[..] words
49 for i := 0; i < k; i++ {
50 // Computes [y0 y1 y2 y3] = rs . [x0 x1 x2 x3 x4 x5 x6 x7]
51 for j, rsRow := range rs {
52 for k, rsVal := range rsRow {
53 S[4*i+j] ^= gfMult(key[8*i+k], rsVal, rsPolynomial)
61 for i := byte(0); i < 20; i++ {
66 A := h(tmp[:], key, 0)
68 // B = rolc(h(p * (2x + 1), Mo), 8)
72 B := h(tmp[:], key, 1)
77 // K[2i+1] = (A + 2B) <<< 9
78 c.k[2*i+1] = rol(2*B+A, 9)
84 for i := range c.s[0] {
85 c.s[0][i] = mdsColumnMult(sbox[1][sbox[0][sbox[0][byte(i)]^S[0]]^S[4]], 0)
86 c.s[1][i] = mdsColumnMult(sbox[0][sbox[0][sbox[1][byte(i)]^S[1]]^S[5]], 1)
87 c.s[2][i] = mdsColumnMult(sbox[1][sbox[1][sbox[0][byte(i)]^S[2]]^S[6]], 2)
88 c.s[3][i] = mdsColumnMult(sbox[0][sbox[1][sbox[1][byte(i)]^S[3]]^S[7]], 3)
91 for i := range c.s[0] {
92 c.s[0][i] = mdsColumnMult(sbox[1][sbox[0][sbox[0][sbox[1][byte(i)]^S[0]]^S[4]]^S[8]], 0)
93 c.s[1][i] = mdsColumnMult(sbox[0][sbox[0][sbox[1][sbox[1][byte(i)]^S[1]]^S[5]]^S[9]], 1)
94 c.s[2][i] = mdsColumnMult(sbox[1][sbox[1][sbox[0][sbox[0][byte(i)]^S[2]]^S[6]]^S[10]], 2)
95 c.s[3][i] = mdsColumnMult(sbox[0][sbox[1][sbox[1][sbox[0][byte(i)]^S[3]]^S[7]]^S[11]], 3)
98 for i := range c.s[0] {
99 c.s[0][i] = mdsColumnMult(sbox[1][sbox[0][sbox[0][sbox[1][sbox[1][byte(i)]^S[0]]^S[4]]^S[8]]^S[12]], 0)
100 c.s[1][i] = mdsColumnMult(sbox[0][sbox[0][sbox[1][sbox[1][sbox[0][byte(i)]^S[1]]^S[5]]^S[9]]^S[13]], 1)
101 c.s[2][i] = mdsColumnMult(sbox[1][sbox[1][sbox[0][sbox[0][sbox[0][byte(i)]^S[2]]^S[6]]^S[10]]^S[14]], 2)
102 c.s[3][i] = mdsColumnMult(sbox[0][sbox[1][sbox[1][sbox[0][sbox[1][byte(i)]^S[3]]^S[7]]^S[11]]^S[15]], 3)
109 // BlockSize returns the Twofish block size, 16 bytes.
110 func (c *Cipher) BlockSize() int { return BlockSize }
112 // store32l stores src in dst in little-endian form.
113 func store32l(dst []byte, src uint32) {
115 dst[1] = byte(src >> 8)
116 dst[2] = byte(src >> 16)
117 dst[3] = byte(src >> 24)
121 // load32l reads a little-endian uint32 from src.
122 func load32l(src []byte) uint32 {
123 return uint32(src[0]) | uint32(src[1])<<8 | uint32(src[2])<<16 | uint32(src[3])<<24
126 // rol returns x after a left circular rotation of y bits.
127 func rol(x, y uint32) uint32 {
128 return (x << (y & 31)) | (x >> (32 - (y & 31)))
131 // ror returns x after a right circular rotation of y bits.
132 func ror(x, y uint32) uint32 {
133 return (x >> (y & 31)) | (x << (32 - (y & 31)))
136 // The RS matrix. See [TWOFISH] 4.3
138 {0x01, 0xA4, 0x55, 0x87, 0x5A, 0x58, 0xDB, 0x9E},
139 {0xA4, 0x56, 0x82, 0xF3, 0x1E, 0xC6, 0x68, 0xE5},
140 {0x02, 0xA1, 0xFC, 0xC1, 0x47, 0xAE, 0x3D, 0x19},
141 {0xA4, 0x55, 0x87, 0x5A, 0x58, 0xDB, 0x9E, 0x03},
145 var sbox = [2][256]byte{
147 0xa9, 0x67, 0xb3, 0xe8, 0x04, 0xfd, 0xa3, 0x76, 0x9a, 0x92, 0x80, 0x78, 0xe4, 0xdd, 0xd1, 0x38,
148 0x0d, 0xc6, 0x35, 0x98, 0x18, 0xf7, 0xec, 0x6c, 0x43, 0x75, 0x37, 0x26, 0xfa, 0x13, 0x94, 0x48,
149 0xf2, 0xd0, 0x8b, 0x30, 0x84, 0x54, 0xdf, 0x23, 0x19, 0x5b, 0x3d, 0x59, 0xf3, 0xae, 0xa2, 0x82,
150 0x63, 0x01, 0x83, 0x2e, 0xd9, 0x51, 0x9b, 0x7c, 0xa6, 0xeb, 0xa5, 0xbe, 0x16, 0x0c, 0xe3, 0x61,
151 0xc0, 0x8c, 0x3a, 0xf5, 0x73, 0x2c, 0x25, 0x0b, 0xbb, 0x4e, 0x89, 0x6b, 0x53, 0x6a, 0xb4, 0xf1,
152 0xe1, 0xe6, 0xbd, 0x45, 0xe2, 0xf4, 0xb6, 0x66, 0xcc, 0x95, 0x03, 0x56, 0xd4, 0x1c, 0x1e, 0xd7,
153 0xfb, 0xc3, 0x8e, 0xb5, 0xe9, 0xcf, 0xbf, 0xba, 0xea, 0x77, 0x39, 0xaf, 0x33, 0xc9, 0x62, 0x71,
154 0x81, 0x79, 0x09, 0xad, 0x24, 0xcd, 0xf9, 0xd8, 0xe5, 0xc5, 0xb9, 0x4d, 0x44, 0x08, 0x86, 0xe7,
155 0xa1, 0x1d, 0xaa, 0xed, 0x06, 0x70, 0xb2, 0xd2, 0x41, 0x7b, 0xa0, 0x11, 0x31, 0xc2, 0x27, 0x90,
156 0x20, 0xf6, 0x60, 0xff, 0x96, 0x5c, 0xb1, 0xab, 0x9e, 0x9c, 0x52, 0x1b, 0x5f, 0x93, 0x0a, 0xef,
157 0x91, 0x85, 0x49, 0xee, 0x2d, 0x4f, 0x8f, 0x3b, 0x47, 0x87, 0x6d, 0x46, 0xd6, 0x3e, 0x69, 0x64,
158 0x2a, 0xce, 0xcb, 0x2f, 0xfc, 0x97, 0x05, 0x7a, 0xac, 0x7f, 0xd5, 0x1a, 0x4b, 0x0e, 0xa7, 0x5a,
159 0x28, 0x14, 0x3f, 0x29, 0x88, 0x3c, 0x4c, 0x02, 0xb8, 0xda, 0xb0, 0x17, 0x55, 0x1f, 0x8a, 0x7d,
160 0x57, 0xc7, 0x8d, 0x74, 0xb7, 0xc4, 0x9f, 0x72, 0x7e, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34,
161 0x6e, 0x50, 0xde, 0x68, 0x65, 0xbc, 0xdb, 0xf8, 0xc8, 0xa8, 0x2b, 0x40, 0xdc, 0xfe, 0x32, 0xa4,
162 0xca, 0x10, 0x21, 0xf0, 0xd3, 0x5d, 0x0f, 0x00, 0x6f, 0x9d, 0x36, 0x42, 0x4a, 0x5e, 0xc1, 0xe0,
165 0x75, 0xf3, 0xc6, 0xf4, 0xdb, 0x7b, 0xfb, 0xc8, 0x4a, 0xd3, 0xe6, 0x6b, 0x45, 0x7d, 0xe8, 0x4b,
166 0xd6, 0x32, 0xd8, 0xfd, 0x37, 0x71, 0xf1, 0xe1, 0x30, 0x0f, 0xf8, 0x1b, 0x87, 0xfa, 0x06, 0x3f,
167 0x5e, 0xba, 0xae, 0x5b, 0x8a, 0x00, 0xbc, 0x9d, 0x6d, 0xc1, 0xb1, 0x0e, 0x80, 0x5d, 0xd2, 0xd5,
168 0xa0, 0x84, 0x07, 0x14, 0xb5, 0x90, 0x2c, 0xa3, 0xb2, 0x73, 0x4c, 0x54, 0x92, 0x74, 0x36, 0x51,
169 0x38, 0xb0, 0xbd, 0x5a, 0xfc, 0x60, 0x62, 0x96, 0x6c, 0x42, 0xf7, 0x10, 0x7c, 0x28, 0x27, 0x8c,
170 0x13, 0x95, 0x9c, 0xc7, 0x24, 0x46, 0x3b, 0x70, 0xca, 0xe3, 0x85, 0xcb, 0x11, 0xd0, 0x93, 0xb8,
171 0xa6, 0x83, 0x20, 0xff, 0x9f, 0x77, 0xc3, 0xcc, 0x03, 0x6f, 0x08, 0xbf, 0x40, 0xe7, 0x2b, 0xe2,
172 0x79, 0x0c, 0xaa, 0x82, 0x41, 0x3a, 0xea, 0xb9, 0xe4, 0x9a, 0xa4, 0x97, 0x7e, 0xda, 0x7a, 0x17,
173 0x66, 0x94, 0xa1, 0x1d, 0x3d, 0xf0, 0xde, 0xb3, 0x0b, 0x72, 0xa7, 0x1c, 0xef, 0xd1, 0x53, 0x3e,
174 0x8f, 0x33, 0x26, 0x5f, 0xec, 0x76, 0x2a, 0x49, 0x81, 0x88, 0xee, 0x21, 0xc4, 0x1a, 0xeb, 0xd9,
175 0xc5, 0x39, 0x99, 0xcd, 0xad, 0x31, 0x8b, 0x01, 0x18, 0x23, 0xdd, 0x1f, 0x4e, 0x2d, 0xf9, 0x48,
176 0x4f, 0xf2, 0x65, 0x8e, 0x78, 0x5c, 0x58, 0x19, 0x8d, 0xe5, 0x98, 0x57, 0x67, 0x7f, 0x05, 0x64,
177 0xaf, 0x63, 0xb6, 0xfe, 0xf5, 0xb7, 0x3c, 0xa5, 0xce, 0xe9, 0x68, 0x44, 0xe0, 0x4d, 0x43, 0x69,
178 0x29, 0x2e, 0xac, 0x15, 0x59, 0xa8, 0x0a, 0x9e, 0x6e, 0x47, 0xdf, 0x34, 0x35, 0x6a, 0xcf, 0xdc,
179 0x22, 0xc9, 0xc0, 0x9b, 0x89, 0xd4, 0xed, 0xab, 0x12, 0xa2, 0x0d, 0x52, 0xbb, 0x02, 0x2f, 0xa9,
180 0xd7, 0x61, 0x1e, 0xb4, 0x50, 0x04, 0xf6, 0xc2, 0x16, 0x25, 0x86, 0x56, 0x55, 0x09, 0xbe, 0x91,
184 // gfMult returns a·b in GF(2^8)/p
185 func gfMult(a, b byte, p uint32) byte {
186 B := [2]uint32{0, uint32(b)}
190 // branchless GF multiplier
191 for i := 0; i < 7; i++ {
194 B[1] = P[B[1]>>7] ^ (B[1] << 1)
200 // mdsColumnMult calculates y{col} where [y0 y1 y2 y3] = MDS · [x0]
201 func mdsColumnMult(in byte, col int) uint32 {
203 mul5B := gfMult(in, 0x5B, mdsPolynomial)
204 mulEF := gfMult(in, 0xEF, mdsPolynomial)
208 return uint32(mul01) | uint32(mul5B)<<8 | uint32(mulEF)<<16 | uint32(mulEF)<<24
210 return uint32(mulEF) | uint32(mulEF)<<8 | uint32(mul5B)<<16 | uint32(mul01)<<24
212 return uint32(mul5B) | uint32(mulEF)<<8 | uint32(mul01)<<16 | uint32(mulEF)<<24
214 return uint32(mul5B) | uint32(mul01)<<8 | uint32(mulEF)<<16 | uint32(mul5B)<<24
220 // h implements the S-box generation function. See [TWOFISH] 4.3.5
221 func h(in, key []byte, offset int) uint32 {
226 switch len(key) / 8 {
228 y[0] = sbox[1][y[0]] ^ key[4*(6+offset)+0]
229 y[1] = sbox[0][y[1]] ^ key[4*(6+offset)+1]
230 y[2] = sbox[0][y[2]] ^ key[4*(6+offset)+2]
231 y[3] = sbox[1][y[3]] ^ key[4*(6+offset)+3]
234 y[0] = sbox[1][y[0]] ^ key[4*(4+offset)+0]
235 y[1] = sbox[1][y[1]] ^ key[4*(4+offset)+1]
236 y[2] = sbox[0][y[2]] ^ key[4*(4+offset)+2]
237 y[3] = sbox[0][y[3]] ^ key[4*(4+offset)+3]
240 y[0] = sbox[1][sbox[0][sbox[0][y[0]]^key[4*(2+offset)+0]]^key[4*(0+offset)+0]]
241 y[1] = sbox[0][sbox[0][sbox[1][y[1]]^key[4*(2+offset)+1]]^key[4*(0+offset)+1]]
242 y[2] = sbox[1][sbox[1][sbox[0][y[2]]^key[4*(2+offset)+2]]^key[4*(0+offset)+2]]
243 y[3] = sbox[0][sbox[1][sbox[1][y[3]]^key[4*(2+offset)+3]]^key[4*(0+offset)+3]]
245 // [y0 y1 y2 y3] = MDS . [x0 x1 x2 x3]
248 mdsMult ^= mdsColumnMult(y[i], i)
253 // Encrypt encrypts a 16-byte block from src to dst, which may overlap.
254 // Note that for amounts of data larger than a block,
255 // it is not safe to just call Encrypt on successive blocks;
256 // instead, use an encryption mode like CBC (see crypto/cipher/cbc.go).
257 func (c *Cipher) Encrypt(dst, src []byte) {
264 ia := load32l(src[0:4])
265 ib := load32l(src[4:8])
266 ic := load32l(src[8:12])
267 id := load32l(src[12:16])
275 for i := 0; i < 8; i++ {
276 k := c.k[8+i*4 : 12+i*4]
277 t2 := S2[byte(ib)] ^ S3[byte(ib>>8)] ^ S4[byte(ib>>16)] ^ S1[byte(ib>>24)]
278 t1 := S1[byte(ia)] ^ S2[byte(ia>>8)] ^ S3[byte(ia>>16)] ^ S4[byte(ia>>24)] + t2
279 ic = ror(ic^(t1+k[0]), 1)
280 id = rol(id, 1) ^ (t2 + t1 + k[1])
282 t2 = S2[byte(id)] ^ S3[byte(id>>8)] ^ S4[byte(id>>16)] ^ S1[byte(id>>24)]
283 t1 = S1[byte(ic)] ^ S2[byte(ic>>8)] ^ S3[byte(ic>>16)] ^ S4[byte(ic>>24)] + t2
284 ia = ror(ia^(t1+k[2]), 1)
285 ib = rol(ib, 1) ^ (t2 + t1 + k[3])
288 // Output with "undo last swap"
294 store32l(dst[0:4], ta)
295 store32l(dst[4:8], tb)
296 store32l(dst[8:12], tc)
297 store32l(dst[12:16], td)
300 // Decrypt decrypts a 16-byte block from src to dst, which may overlap.
301 func (c *Cipher) Decrypt(dst, src []byte) {
308 ta := load32l(src[0:4])
309 tb := load32l(src[4:8])
310 tc := load32l(src[8:12])
311 td := load32l(src[12:16])
313 // Undo undo final swap
319 for i := 8; i > 0; i-- {
320 k := c.k[4+i*4 : 8+i*4]
321 t2 := S2[byte(id)] ^ S3[byte(id>>8)] ^ S4[byte(id>>16)] ^ S1[byte(id>>24)]
322 t1 := S1[byte(ic)] ^ S2[byte(ic>>8)] ^ S3[byte(ic>>16)] ^ S4[byte(ic>>24)] + t2
323 ia = rol(ia, 1) ^ (t1 + k[2])
324 ib = ror(ib^(t2+t1+k[3]), 1)
326 t2 = S2[byte(ib)] ^ S3[byte(ib>>8)] ^ S4[byte(ib>>16)] ^ S1[byte(ib>>24)]
327 t1 = S1[byte(ia)] ^ S2[byte(ia>>8)] ^ S3[byte(ia>>16)] ^ S4[byte(ia>>24)] + t2
328 ic = rol(ic, 1) ^ (t1 + k[0])
329 id = ror(id^(t2+t1+k[1]), 1)
332 // Undo pre-whitening
338 store32l(dst[0:4], ia)
339 store32l(dst[4:8], ib)
340 store32l(dst[8:12], ic)
341 store32l(dst[12:16], id)