block.go (6161B)
1 // Copyright 2010 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 blowfish 6 7 // getNextWord returns the next big-endian uint32 value from the byte slice 8 // at the given position in a circular manner, updating the position. 9 func getNextWord(b []byte, pos *int) uint32 { 10 var w uint32 11 j := *pos 12 for i := 0; i < 4; i++ { 13 w = w<<8 | uint32(b[j]) 14 j++ 15 if j >= len(b) { 16 j = 0 17 } 18 } 19 *pos = j 20 return w 21 } 22 23 // ExpandKey performs a key expansion on the given *Cipher. Specifically, it 24 // performs the Blowfish algorithm's key schedule which sets up the *Cipher's 25 // pi and substitution tables for calls to Encrypt. This is used, primarily, 26 // by the bcrypt package to reuse the Blowfish key schedule during its 27 // set up. It's unlikely that you need to use this directly. 28 func ExpandKey(key []byte, c *Cipher) { 29 j := 0 30 for i := 0; i < 18; i++ { 31 // Using inlined getNextWord for performance. 32 var d uint32 33 for k := 0; k < 4; k++ { 34 d = d<<8 | uint32(key[j]) 35 j++ 36 if j >= len(key) { 37 j = 0 38 } 39 } 40 c.p[i] ^= d 41 } 42 43 var l, r uint32 44 for i := 0; i < 18; i += 2 { 45 l, r = encryptBlock(l, r, c) 46 c.p[i], c.p[i+1] = l, r 47 } 48 49 for i := 0; i < 256; i += 2 { 50 l, r = encryptBlock(l, r, c) 51 c.s0[i], c.s0[i+1] = l, r 52 } 53 for i := 0; i < 256; i += 2 { 54 l, r = encryptBlock(l, r, c) 55 c.s1[i], c.s1[i+1] = l, r 56 } 57 for i := 0; i < 256; i += 2 { 58 l, r = encryptBlock(l, r, c) 59 c.s2[i], c.s2[i+1] = l, r 60 } 61 for i := 0; i < 256; i += 2 { 62 l, r = encryptBlock(l, r, c) 63 c.s3[i], c.s3[i+1] = l, r 64 } 65 } 66 67 // This is similar to ExpandKey, but folds the salt during the key 68 // schedule. While ExpandKey is essentially expandKeyWithSalt with an all-zero 69 // salt passed in, reusing ExpandKey turns out to be a place of inefficiency 70 // and specializing it here is useful. 71 func expandKeyWithSalt(key []byte, salt []byte, c *Cipher) { 72 j := 0 73 for i := 0; i < 18; i++ { 74 c.p[i] ^= getNextWord(key, &j) 75 } 76 77 j = 0 78 var l, r uint32 79 for i := 0; i < 18; i += 2 { 80 l ^= getNextWord(salt, &j) 81 r ^= getNextWord(salt, &j) 82 l, r = encryptBlock(l, r, c) 83 c.p[i], c.p[i+1] = l, r 84 } 85 86 for i := 0; i < 256; i += 2 { 87 l ^= getNextWord(salt, &j) 88 r ^= getNextWord(salt, &j) 89 l, r = encryptBlock(l, r, c) 90 c.s0[i], c.s0[i+1] = l, r 91 } 92 93 for i := 0; i < 256; i += 2 { 94 l ^= getNextWord(salt, &j) 95 r ^= getNextWord(salt, &j) 96 l, r = encryptBlock(l, r, c) 97 c.s1[i], c.s1[i+1] = l, r 98 } 99 100 for i := 0; i < 256; i += 2 { 101 l ^= getNextWord(salt, &j) 102 r ^= getNextWord(salt, &j) 103 l, r = encryptBlock(l, r, c) 104 c.s2[i], c.s2[i+1] = l, r 105 } 106 107 for i := 0; i < 256; i += 2 { 108 l ^= getNextWord(salt, &j) 109 r ^= getNextWord(salt, &j) 110 l, r = encryptBlock(l, r, c) 111 c.s3[i], c.s3[i+1] = l, r 112 } 113 } 114 115 func encryptBlock(l, r uint32, c *Cipher) (uint32, uint32) { 116 xl, xr := l, r 117 xl ^= c.p[0] 118 xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[1] 119 xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[2] 120 xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[3] 121 xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[4] 122 xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[5] 123 xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[6] 124 xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[7] 125 xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[8] 126 xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[9] 127 xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[10] 128 xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[11] 129 xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[12] 130 xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[13] 131 xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[14] 132 xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[15] 133 xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[16] 134 xr ^= c.p[17] 135 return xr, xl 136 } 137 138 func decryptBlock(l, r uint32, c *Cipher) (uint32, uint32) { 139 xl, xr := l, r 140 xl ^= c.p[17] 141 xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[16] 142 xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[15] 143 xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[14] 144 xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[13] 145 xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[12] 146 xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[11] 147 xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[10] 148 xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[9] 149 xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[8] 150 xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[7] 151 xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[6] 152 xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[5] 153 xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[4] 154 xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[3] 155 xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[2] 156 xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[1] 157 xr ^= c.p[0] 158 return xr, xl 159 }