BlowfishEngine.java revision e6bf3e8dfa2804891a82075cb469b736321b4827
1package org.bouncycastle.crypto.engines;
2
3import org.bouncycastle.crypto.BlockCipher;
4import org.bouncycastle.crypto.CipherParameters;
5import org.bouncycastle.crypto.DataLengthException;
6import org.bouncycastle.crypto.params.KeyParameter;
7
8/**
9 * A class that provides Blowfish key encryption operations,
10 * such as encoding data and generating keys.
11 * All the algorithms herein are from Applied Cryptography
12 * and implement a simplified cryptography interface.
13 */
14public final class BlowfishEngine
15implements BlockCipher
16{
17    private final static int[]
18        KP = {
19                0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344,
20                0xA4093822, 0x299F31D0, 0x082EFA98, 0xEC4E6C89,
21                0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C,
22                0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917,
23                0x9216D5D9, 0x8979FB1B
24             },
25
26        KS0 = {
27                0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7,
28                0xB8E1AFED, 0x6A267E96, 0xBA7C9045, 0xF12C7F99,
29                0x24A19947, 0xB3916CF7, 0x0801F2E2, 0x858EFC16,
30                0x636920D8, 0x71574E69, 0xA458FEA3, 0xF4933D7E,
31                0x0D95748F, 0x728EB658, 0x718BCD58, 0x82154AEE,
32                0x7B54A41D, 0xC25A59B5, 0x9C30D539, 0x2AF26013,
33                0xC5D1B023, 0x286085F0, 0xCA417918, 0xB8DB38EF,
34                0x8E79DCB0, 0x603A180E, 0x6C9E0E8B, 0xB01E8A3E,
35                0xD71577C1, 0xBD314B27, 0x78AF2FDA, 0x55605C60,
36                0xE65525F3, 0xAA55AB94, 0x57489862, 0x63E81440,
37                0x55CA396A, 0x2AAB10B6, 0xB4CC5C34, 0x1141E8CE,
38                0xA15486AF, 0x7C72E993, 0xB3EE1411, 0x636FBC2A,
39                0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E,
40                0xAFD6BA33, 0x6C24CF5C, 0x7A325381, 0x28958677,
41                0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, 0x66282193,
42                0x61D809CC, 0xFB21A991, 0x487CAC60, 0x5DEC8032,
43                0xEF845D5D, 0xE98575B1, 0xDC262302, 0xEB651B88,
44                0x23893E81, 0xD396ACC5, 0x0F6D6FF3, 0x83F44239,
45                0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E,
46                0x21C66842, 0xF6E96C9A, 0x670C9C61, 0xABD388F0,
47                0x6A51A0D2, 0xD8542F68, 0x960FA728, 0xAB5133A3,
48                0x6EEF0B6C, 0x137A3BE4, 0xBA3BF050, 0x7EFB2A98,
49                0xA1F1651D, 0x39AF0176, 0x66CA593E, 0x82430E88,
50                0x8CEE8619, 0x456F9FB4, 0x7D84A5C3, 0x3B8B5EBE,
51                0xE06F75D8, 0x85C12073, 0x401A449F, 0x56C16AA6,
52                0x4ED3AA62, 0x363F7706, 0x1BFEDF72, 0x429B023D,
53                0x37D0D724, 0xD00A1248, 0xDB0FEAD3, 0x49F1C09B,
54                0x075372C9, 0x80991B7B, 0x25D479D8, 0xF6E8DEF7,
55                0xE3FE501A, 0xB6794C3B, 0x976CE0BD, 0x04C006BA,
56                0xC1A94FB6, 0x409F60C4, 0x5E5C9EC2, 0x196A2463,
57                0x68FB6FAF, 0x3E6C53B5, 0x1339B2EB, 0x3B52EC6F,
58                0x6DFC511F, 0x9B30952C, 0xCC814544, 0xAF5EBD09,
59                0xBEE3D004, 0xDE334AFD, 0x660F2807, 0x192E4BB3,
60                0xC0CBA857, 0x45C8740F, 0xD20B5F39, 0xB9D3FBDB,
61                0x5579C0BD, 0x1A60320A, 0xD6A100C6, 0x402C7279,
62                0x679F25FE, 0xFB1FA3CC, 0x8EA5E9F8, 0xDB3222F8,
63                0x3C7516DF, 0xFD616B15, 0x2F501EC8, 0xAD0552AB,
64                0x323DB5FA, 0xFD238760, 0x53317B48, 0x3E00DF82,
65                0x9E5C57BB, 0xCA6F8CA0, 0x1A87562E, 0xDF1769DB,
66                0xD542A8F6, 0x287EFFC3, 0xAC6732C6, 0x8C4F5573,
67                0x695B27B0, 0xBBCA58C8, 0xE1FFA35D, 0xB8F011A0,
68                0x10FA3D98, 0xFD2183B8, 0x4AFCB56C, 0x2DD1D35B,
69                0x9A53E479, 0xB6F84565, 0xD28E49BC, 0x4BFB9790,
70                0xE1DDF2DA, 0xA4CB7E33, 0x62FB1341, 0xCEE4C6E8,
71                0xEF20CADA, 0x36774C01, 0xD07E9EFE, 0x2BF11FB4,
72                0x95DBDA4D, 0xAE909198, 0xEAAD8E71, 0x6B93D5A0,
73                0xD08ED1D0, 0xAFC725E0, 0x8E3C5B2F, 0x8E7594B7,
74                0x8FF6E2FB, 0xF2122B64, 0x8888B812, 0x900DF01C,
75                0x4FAD5EA0, 0x688FC31C, 0xD1CFF191, 0xB3A8C1AD,
76                0x2F2F2218, 0xBE0E1777, 0xEA752DFE, 0x8B021FA1,
77                0xE5A0CC0F, 0xB56F74E8, 0x18ACF3D6, 0xCE89E299,
78                0xB4A84FE0, 0xFD13E0B7, 0x7CC43B81, 0xD2ADA8D9,
79                0x165FA266, 0x80957705, 0x93CC7314, 0x211A1477,
80                0xE6AD2065, 0x77B5FA86, 0xC75442F5, 0xFB9D35CF,
81                0xEBCDAF0C, 0x7B3E89A0, 0xD6411BD3, 0xAE1E7E49,
82                0x00250E2D, 0x2071B35E, 0x226800BB, 0x57B8E0AF,
83                0x2464369B, 0xF009B91E, 0x5563911D, 0x59DFA6AA,
84                0x78C14389, 0xD95A537F, 0x207D5BA2, 0x02E5B9C5,
85                0x83260376, 0x6295CFA9, 0x11C81968, 0x4E734A41,
86                0xB3472DCA, 0x7B14A94A, 0x1B510052, 0x9A532915,
87                0xD60F573F, 0xBC9BC6E4, 0x2B60A476, 0x81E67400,
88                0x08BA6FB5, 0x571BE91F, 0xF296EC6B, 0x2A0DD915,
89                0xB6636521, 0xE7B9F9B6, 0xFF34052E, 0xC5855664,
90                0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A
91            },
92
93        KS1 = {
94                0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623,
95                0xAD6EA6B0, 0x49A7DF7D, 0x9CEE60B8, 0x8FEDB266,
96                0xECAA8C71, 0x699A17FF, 0x5664526C, 0xC2B19EE1,
97                0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E,
98                0x3F54989A, 0x5B429D65, 0x6B8FE4D6, 0x99F73FD6,
99                0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1,
100                0x4CDD2086, 0x8470EB26, 0x6382E9C6, 0x021ECC5E,
101                0x09686B3F, 0x3EBAEFC9, 0x3C971814, 0x6B6A70A1,
102                0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737,
103                0x3E07841C, 0x7FDEAE5C, 0x8E7D44EC, 0x5716F2B8,
104                0xB03ADA37, 0xF0500C0D, 0xF01C1F04, 0x0200B3FF,
105                0xAE0CF51A, 0x3CB574B2, 0x25837A58, 0xDC0921BD,
106                0xD19113F9, 0x7CA92FF6, 0x94324773, 0x22F54701,
107                0x3AE5E581, 0x37C2DADC, 0xC8B57634, 0x9AF3DDA7,
108                0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41,
109                0xE238CD99, 0x3BEA0E2F, 0x3280BBA1, 0x183EB331,
110                0x4E548B38, 0x4F6DB908, 0x6F420D03, 0xF60A04BF,
111                0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF,
112                0xDE9A771F, 0xD9930810, 0xB38BAE12, 0xDCCF3F2E,
113                0x5512721F, 0x2E6B7124, 0x501ADDE6, 0x9F84CD87,
114                0x7A584718, 0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C,
115                0xEC7AEC3A, 0xDB851DFA, 0x63094366, 0xC464C3D2,
116                0xEF1C1847, 0x3215D908, 0xDD433B37, 0x24C2BA16,
117                0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD,
118                0x71DFF89E, 0x10314E55, 0x81AC77D6, 0x5F11199B,
119                0x043556F1, 0xD7A3C76B, 0x3C11183B, 0x5924A509,
120                0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E,
121                0x86E34570, 0xEAE96FB1, 0x860E5E0A, 0x5A3E2AB3,
122                0x771FE71C, 0x4E3D06FA, 0x2965DCB9, 0x99E71D0F,
123                0x803E89D6, 0x5266C825, 0x2E4CC978, 0x9C10B36A,
124                0xC6150EBA, 0x94E2EA78, 0xA5FC3C53, 0x1E0A2DF4,
125                0xF2F74EA7, 0x361D2B3D, 0x1939260F, 0x19C27960,
126                0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66,
127                0xE3BC4595, 0xA67BC883, 0xB17F37D1, 0x018CFF28,
128                0xC332DDEF, 0xBE6C5AA5, 0x65582185, 0x68AB9802,
129                0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84,
130                0x1521B628, 0x29076170, 0xECDD4775, 0x619F1510,
131                0x13CCA830, 0xEB61BD96, 0x0334FE1E, 0xAA0363CF,
132                0xB5735C90, 0x4C70A239, 0xD59E9E0B, 0xCBAADE14,
133                0xEECC86BC, 0x60622CA7, 0x9CAB5CAB, 0xB2F3846E,
134                0x648B1EAF, 0x19BDF0CA, 0xA02369B9, 0x655ABB50,
135                0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7,
136                0x9B540B19, 0x875FA099, 0x95F7997E, 0x623D7DA8,
137                0xF837889A, 0x97E32D77, 0x11ED935F, 0x16681281,
138                0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99,
139                0x57F584A5, 0x1B227263, 0x9B83C3FF, 0x1AC24696,
140                0xCDB30AEB, 0x532E3054, 0x8FD948E4, 0x6DBC3128,
141                0x58EBF2EF, 0x34C6FFEA, 0xFE28ED61, 0xEE7C3C73,
142                0x5D4A14D9, 0xE864B7E3, 0x42105D14, 0x203E13E0,
143                0x45EEE2B6, 0xA3AAABEA, 0xDB6C4F15, 0xFACB4FD0,
144                0xC742F442, 0xEF6ABBB5, 0x654F3B1D, 0x41CD2105,
145                0xD81E799E, 0x86854DC7, 0xE44B476A, 0x3D816250,
146                0xCF62A1F2, 0x5B8D2646, 0xFC8883A0, 0xC1C7B6A3,
147                0x7F1524C3, 0x69CB7492, 0x47848A0B, 0x5692B285,
148                0x095BBF00, 0xAD19489D, 0x1462B174, 0x23820E00,
149                0x58428D2A, 0x0C55F5EA, 0x1DADF43E, 0x233F7061,
150                0x3372F092, 0x8D937E41, 0xD65FECF1, 0x6C223BDB,
151                0x7CDE3759, 0xCBEE7460, 0x4085F2A7, 0xCE77326E,
152                0xA6078084, 0x19F8509E, 0xE8EFD855, 0x61D99735,
153                0xA969A7AA, 0xC50C06C2, 0x5A04ABFC, 0x800BCADC,
154                0x9E447A2E, 0xC3453484, 0xFDD56705, 0x0E1E9EC9,
155                0xDB73DBD3, 0x105588CD, 0x675FDA79, 0xE3674340,
156                0xC5C43465, 0x713E38D8, 0x3D28F89E, 0xF16DFF20,
157                0x153E21E7, 0x8FB03D4A, 0xE6E39F2B, 0xDB83ADF7
158            },
159
160        KS2 = {
161                0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934,
162                0x411520F7, 0x7602D4F7, 0xBCF46B2E, 0xD4A20068,
163                0xD4082471, 0x3320F46A, 0x43B7D4B7, 0x500061AF,
164                0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840,
165                0x4D95FC1D, 0x96B591AF, 0x70F4DDD3, 0x66A02F45,
166                0xBFBC09EC, 0x03BD9785, 0x7FAC6DD0, 0x31CB8504,
167                0x96EB27B3, 0x55FD3941, 0xDA2547E6, 0xABCA0A9A,
168                0x28507825, 0x530429F4, 0x0A2C86DA, 0xE9B66DFB,
169                0x68DC1462, 0xD7486900, 0x680EC0A4, 0x27A18DEE,
170                0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6,
171                0xAACE1E7C, 0xD3375FEC, 0xCE78A399, 0x406B2A42,
172                0x20FE9E35, 0xD9F385B9, 0xEE39D7AB, 0x3B124E8B,
173                0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2,
174                0x3A6EFA74, 0xDD5B4332, 0x6841E7F7, 0xCA7820FB,
175                0xFB0AF54E, 0xD8FEB397, 0x454056AC, 0xBA489527,
176                0x55533A3A, 0x20838D87, 0xFE6BA9B7, 0xD096954B,
177                0x55A867BC, 0xA1159A58, 0xCCA92963, 0x99E1DB33,
178                0xA62A4A56, 0x3F3125F9, 0x5EF47E1C, 0x9029317C,
179                0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3,
180                0x95C11548, 0xE4C66D22, 0x48C1133F, 0xC70F86DC,
181                0x07F9C9EE, 0x41041F0F, 0x404779A4, 0x5D886E17,
182                0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564,
183                0x257B7834, 0x602A9C60, 0xDFF8E8A3, 0x1F636C1B,
184                0x0E12B4C2, 0x02E1329E, 0xAF664FD1, 0xCAD18115,
185                0x6B2395E0, 0x333E92E1, 0x3B240B62, 0xEEBEB922,
186                0x85B2A20E, 0xE6BA0D99, 0xDE720C8C, 0x2DA2F728,
187                0xD0127845, 0x95B794FD, 0x647D0862, 0xE7CCF5F0,
188                0x5449A36F, 0x877D48FA, 0xC39DFD27, 0xF33E8D1E,
189                0x0A476341, 0x992EFF74, 0x3A6F6EAB, 0xF4F8FD37,
190                0xA812DC60, 0xA1EBDDF8, 0x991BE14C, 0xDB6E6B0D,
191                0xC67B5510, 0x6D672C37, 0x2765D43B, 0xDCD0E804,
192                0xF1290DC7, 0xCC00FFA3, 0xB5390F92, 0x690FED0B,
193                0x667B9FFB, 0xCEDB7D9C, 0xA091CF0B, 0xD9155EA3,
194                0xBB132F88, 0x515BAD24, 0x7B9479BF, 0x763BD6EB,
195                0x37392EB3, 0xCC115979, 0x8026E297, 0xF42E312D,
196                0x6842ADA7, 0xC66A2B3B, 0x12754CCC, 0x782EF11C,
197                0x6A124237, 0xB79251E7, 0x06A1BBE6, 0x4BFB6350,
198                0x1A6B1018, 0x11CAEDFA, 0x3D25BDD8, 0xE2E1C3C9,
199                0x44421659, 0x0A121386, 0xD90CEC6E, 0xD5ABEA2A,
200                0x64AF674E, 0xDA86A85F, 0xBEBFE988, 0x64E4C3FE,
201                0x9DBC8057, 0xF0F7C086, 0x60787BF8, 0x6003604D,
202                0xD1FD8346, 0xF6381FB0, 0x7745AE04, 0xD736FCCC,
203                0x83426B33, 0xF01EAB71, 0xB0804187, 0x3C005E5F,
204                0x77A057BE, 0xBDE8AE24, 0x55464299, 0xBF582E61,
205                0x4E58F48F, 0xF2DDFDA2, 0xF474EF38, 0x8789BDC2,
206                0x5366F9C3, 0xC8B38E74, 0xB475F255, 0x46FCD9B9,
207                0x7AEB2661, 0x8B1DDF84, 0x846A0E79, 0x915F95E2,
208                0x466E598E, 0x20B45770, 0x8CD55591, 0xC902DE4C,
209                0xB90BACE1, 0xBB8205D0, 0x11A86248, 0x7574A99E,
210                0xB77F19B6, 0xE0A9DC09, 0x662D09A1, 0xC4324633,
211                0xE85A1F02, 0x09F0BE8C, 0x4A99A025, 0x1D6EFE10,
212                0x1AB93D1D, 0x0BA5A4DF, 0xA186F20F, 0x2868F169,
213                0xDCB7DA83, 0x573906FE, 0xA1E2CE9B, 0x4FCD7F52,
214                0x50115E01, 0xA70683FA, 0xA002B5C4, 0x0DE6D027,
215                0x9AF88C27, 0x773F8641, 0xC3604C06, 0x61A806B5,
216                0xF0177A28, 0xC0F586E0, 0x006058AA, 0x30DC7D62,
217                0x11E69ED7, 0x2338EA63, 0x53C2DD94, 0xC2C21634,
218                0xBBCBEE56, 0x90BCB6DE, 0xEBFC7DA1, 0xCE591D76,
219                0x6F05E409, 0x4B7C0188, 0x39720A3D, 0x7C927C24,
220                0x86E3725F, 0x724D9DB9, 0x1AC15BB4, 0xD39EB8FC,
221                0xED545578, 0x08FCA5B5, 0xD83D7CD3, 0x4DAD0FC4,
222                0x1E50EF5E, 0xB161E6F8, 0xA28514D9, 0x6C51133C,
223                0x6FD5C7E7, 0x56E14EC4, 0x362ABFCE, 0xDDC6C837,
224                0xD79A3234, 0x92638212, 0x670EFA8E, 0x406000E0
225            },
226
227        KS3 = {
228                0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B,
229                0x5CB0679E, 0x4FA33742, 0xD3822740, 0x99BC9BBE,
230                0xD5118E9D, 0xBF0F7315, 0xD62D1C7E, 0xC700C47B,
231                0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4,
232                0x5748AB2F, 0xBC946E79, 0xC6A376D2, 0x6549C2C8,
233                0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6,
234                0x2939BBDB, 0xA9BA4650, 0xAC9526E8, 0xBE5EE304,
235                0xA1FAD5F0, 0x6A2D519A, 0x63EF8CE2, 0x9A86EE22,
236                0xC089C2B8, 0x43242EF6, 0xA51E03AA, 0x9CF2D0A4,
237                0x83C061BA, 0x9BE96A4D, 0x8FE51550, 0xBA645BD6,
238                0x2826A2F9, 0xA73A3AE1, 0x4BA99586, 0xEF5562E9,
239                0xC72FEFD3, 0xF752F7DA, 0x3F046F69, 0x77FA0A59,
240                0x80E4A915, 0x87B08601, 0x9B09E6AD, 0x3B3EE593,
241                0xE990FD5A, 0x9E34D797, 0x2CF0B7D9, 0x022B8B51,
242                0x96D5AC3A, 0x017DA67D, 0xD1CF3ED6, 0x7C7D2D28,
243                0x1F9F25CF, 0xADF2B89B, 0x5AD6B472, 0x5A88F54C,
244                0xE029AC71, 0xE019A5E6, 0x47B0ACFD, 0xED93FA9B,
245                0xE8D3C48D, 0x283B57CC, 0xF8D56629, 0x79132E28,
246                0x785F0191, 0xED756055, 0xF7960E44, 0xE3D35E8C,
247                0x15056DD4, 0x88F46DBA, 0x03A16125, 0x0564F0BD,
248                0xC3EB9E15, 0x3C9057A2, 0x97271AEC, 0xA93A072A,
249                0x1B3F6D9B, 0x1E6321F5, 0xF59C66FB, 0x26DCF319,
250                0x7533D928, 0xB155FDF5, 0x03563482, 0x8ABA3CBB,
251                0x28517711, 0xC20AD9F8, 0xABCC5167, 0xCCAD925F,
252                0x4DE81751, 0x3830DC8E, 0x379D5862, 0x9320F991,
253                0xEA7A90C2, 0xFB3E7BCE, 0x5121CE64, 0x774FBE32,
254                0xA8B6E37E, 0xC3293D46, 0x48DE5369, 0x6413E680,
255                0xA2AE0810, 0xDD6DB224, 0x69852DFD, 0x09072166,
256                0xB39A460A, 0x6445C0DD, 0x586CDECF, 0x1C20C8AE,
257                0x5BBEF7DD, 0x1B588D40, 0xCCD2017F, 0x6BB4E3BB,
258                0xDDA26A7E, 0x3A59FF45, 0x3E350A44, 0xBCB4CDD5,
259                0x72EACEA8, 0xFA6484BB, 0x8D6612AE, 0xBF3C6F47,
260                0xD29BE463, 0x542F5D9E, 0xAEC2771B, 0xF64E6370,
261                0x740E0D8D, 0xE75B1357, 0xF8721671, 0xAF537D5D,
262                0x4040CB08, 0x4EB4E2CC, 0x34D2466A, 0x0115AF84,
263                0xE1B00428, 0x95983A1D, 0x06B89FB4, 0xCE6EA048,
264                0x6F3F3B82, 0x3520AB82, 0x011A1D4B, 0x277227F8,
265                0x611560B1, 0xE7933FDC, 0xBB3A792B, 0x344525BD,
266                0xA08839E1, 0x51CE794B, 0x2F32C9B7, 0xA01FBAC9,
267                0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7,
268                0x1A908749, 0xD44FBD9A, 0xD0DADECB, 0xD50ADA38,
269                0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F,
270                0xF79E59B7, 0x43F5BB3A, 0xF2D519FF, 0x27D9459C,
271                0xBF97222C, 0x15E6FC2A, 0x0F91FC71, 0x9B941525,
272                0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1,
273                0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442,
274                0xE0EC6E0E, 0x1698DB3B, 0x4C98A0BE, 0x3278E964,
275                0x9F1F9532, 0xE0D392DF, 0xD3A0342B, 0x8971F21E,
276                0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8,
277                0xDF359F8D, 0x9B992F2E, 0xE60B6F47, 0x0FE3F11D,
278                0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F,
279                0x1618B166, 0xFD2C1D05, 0x848FD2C5, 0xF6FB2299,
280                0xF523F357, 0xA6327623, 0x93A83531, 0x56CCCD02,
281                0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC,
282                0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614,
283                0xE6C6C7BD, 0x327A140A, 0x45E1D006, 0xC3F27B9A,
284                0xC9AA53FD, 0x62A80F00, 0xBB25BFE2, 0x35BDD2F6,
285                0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B,
286                0x53113EC0, 0x1640E3D3, 0x38ABBD60, 0x2547ADF0,
287                0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060,
288                0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0, 0x4CF9AA7E,
289                0x1948C25C, 0x02FB8A8C, 0x01C36AE4, 0xD6EBE1F9,
290                0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F,
291                0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6
292            };
293
294    //====================================
295    // Useful constants
296    //====================================
297
298    private static final int    ROUNDS = 16;
299    private static final int    BLOCK_SIZE = 8;  // bytes = 64 bits
300    private static final int    SBOX_SK = 256;
301    private static final int    P_SZ = ROUNDS+2;
302
303    private final int[] S0, S1, S2, S3;     // the s-boxes
304    private final int[] P;                  // the p-array
305
306    private boolean encrypting = false;
307
308    private byte[] workingKey = null;
309
310    public BlowfishEngine()
311    {
312        S0 = new int[SBOX_SK];
313        S1 = new int[SBOX_SK];
314        S2 = new int[SBOX_SK];
315        S3 = new int[SBOX_SK];
316        P = new int[P_SZ];
317    }
318
319    /**
320     * initialise a Blowfish cipher.
321     *
322     * @param encrypting whether or not we are for encryption.
323     * @param params the parameters required to set up the cipher.
324     * @exception IllegalArgumentException if the params argument is
325     * inappropriate.
326     */
327    public void init(
328        boolean             encrypting,
329        CipherParameters    params)
330    {
331        if (params instanceof KeyParameter)
332        {
333            this.encrypting = encrypting;
334            this.workingKey = ((KeyParameter)params).getKey();
335            setKey(this.workingKey);
336
337            return;
338        }
339
340        throw new IllegalArgumentException("invalid parameter passed to Blowfish init - " + params.getClass().getName());
341    }
342
343    public String getAlgorithmName()
344    {
345        return "Blowfish";
346    }
347
348    public final int processBlock(
349        byte[] in,
350        int inOff,
351        byte[] out,
352        int outOff)
353    {
354        if (workingKey == null)
355        {
356            throw new IllegalStateException("Blowfish not initialised");
357        }
358
359        if ((inOff + BLOCK_SIZE) > in.length)
360        {
361            throw new DataLengthException("input buffer too short");
362        }
363
364        if ((outOff + BLOCK_SIZE) > out.length)
365        {
366            throw new DataLengthException("output buffer too short");
367        }
368
369        if (encrypting)
370        {
371            encryptBlock(in, inOff, out, outOff);
372        }
373        else
374        {
375            decryptBlock(in, inOff, out, outOff);
376        }
377
378        return BLOCK_SIZE;
379    }
380
381    public void reset()
382    {
383    }
384
385    public int getBlockSize()
386    {
387        return BLOCK_SIZE;
388    }
389
390    //==================================
391    // Private Implementation
392    //==================================
393
394    private int F(int x)
395    {
396        return (((S0[(x >>> 24)] + S1[(x >>> 16) & 0xff])
397                            ^ S2[(x >>> 8) & 0xff]) + S3[x & 0xff]);
398    }
399
400    /**
401     * apply the encryption cycle to each value pair in the table.
402     */
403    private void processTable(
404        int     xl,
405        int     xr,
406        int[]   table)
407    {
408        int size = table.length;
409
410        for (int s = 0; s < size; s += 2)
411        {
412            xl ^= P[0];
413
414            for (int i = 1; i < ROUNDS; i += 2)
415            {
416                xr ^= F(xl) ^ P[i];
417                xl ^= F(xr) ^ P[i + 1];
418            }
419
420            xr ^= P[ROUNDS + 1];
421
422            table[s] = xr;
423            table[s + 1] = xl;
424
425            xr = xl;            // end of cycle swap
426            xl = table[s];
427        }
428    }
429
430    private void setKey(byte[] key)
431    {
432        /*
433         * - comments are from _Applied Crypto_, Schneier, p338
434         * please be careful comparing the two, AC numbers the
435         * arrays from 1, the enclosed code from 0.
436         *
437         * (1)
438         * Initialise the S-boxes and the P-array, with a fixed string
439         * This string contains the hexadecimal digits of pi (3.141...)
440         */
441        System.arraycopy(KS0, 0, S0, 0, SBOX_SK);
442        System.arraycopy(KS1, 0, S1, 0, SBOX_SK);
443        System.arraycopy(KS2, 0, S2, 0, SBOX_SK);
444        System.arraycopy(KS3, 0, S3, 0, SBOX_SK);
445
446        System.arraycopy(KP, 0, P, 0, P_SZ);
447
448        /*
449         * (2)
450         * Now, XOR P[0] with the first 32 bits of the key, XOR P[1] with the
451         * second 32-bits of the key, and so on for all bits of the key
452         * (up to P[17]).  Repeatedly cycle through the key bits until the
453         * entire P-array has been XOR-ed with the key bits
454         */
455        int keyLength = key.length;
456        int keyIndex = 0;
457
458        for (int i=0; i < P_SZ; i++)
459        {
460            // get the 32 bits of the key, in 4 * 8 bit chunks
461            int data = 0x0000000;
462            for (int j=0; j < 4; j++)
463            {
464                // create a 32 bit block
465                data = (data << 8) | (key[keyIndex++] & 0xff);
466
467                // wrap when we get to the end of the key
468                if (keyIndex >= keyLength)
469                {
470                    keyIndex = 0;
471                }
472            }
473            // XOR the newly created 32 bit chunk onto the P-array
474            P[i] ^= data;
475        }
476
477        /*
478         * (3)
479         * Encrypt the all-zero string with the Blowfish algorithm, using
480         * the subkeys described in (1) and (2)
481         *
482         * (4)
483         * Replace P1 and P2 with the output of step (3)
484         *
485         * (5)
486         * Encrypt the output of step(3) using the Blowfish algorithm,
487         * with the modified subkeys.
488         *
489         * (6)
490         * Replace P3 and P4 with the output of step (5)
491         *
492         * (7)
493         * Continue the process, replacing all elements of the P-array
494         * and then all four S-boxes in order, with the output of the
495         * continuously changing Blowfish algorithm
496         */
497
498        processTable(0, 0, P);
499        processTable(P[P_SZ - 2], P[P_SZ - 1], S0);
500        processTable(S0[SBOX_SK - 2], S0[SBOX_SK - 1], S1);
501        processTable(S1[SBOX_SK - 2], S1[SBOX_SK - 1], S2);
502        processTable(S2[SBOX_SK - 2], S2[SBOX_SK - 1], S3);
503    }
504
505    /**
506     * Encrypt the given input starting at the given offset and place
507     * the result in the provided buffer starting at the given offset.
508     * The input will be an exact multiple of our blocksize.
509     */
510    private void encryptBlock(
511        byte[]  src,
512        int     srcIndex,
513        byte[]  dst,
514        int     dstIndex)
515    {
516        int xl = BytesTo32bits(src, srcIndex);
517        int xr = BytesTo32bits(src, srcIndex+4);
518
519        xl ^= P[0];
520
521        for (int i = 1; i < ROUNDS; i += 2)
522        {
523            xr ^= F(xl) ^ P[i];
524            xl ^= F(xr) ^ P[i + 1];
525        }
526
527        xr ^= P[ROUNDS + 1];
528
529        Bits32ToBytes(xr, dst, dstIndex);
530        Bits32ToBytes(xl, dst, dstIndex + 4);
531    }
532
533    /**
534     * Decrypt the given input starting at the given offset and place
535     * the result in the provided buffer starting at the given offset.
536     * The input will be an exact multiple of our blocksize.
537     */
538    private void decryptBlock(
539        byte[] src,
540        int srcIndex,
541        byte[] dst,
542        int dstIndex)
543    {
544        int xl = BytesTo32bits(src, srcIndex);
545        int xr = BytesTo32bits(src, srcIndex + 4);
546
547        xl ^= P[ROUNDS + 1];
548
549        for (int i = ROUNDS; i > 0 ; i -= 2)
550        {
551            xr ^= F(xl) ^ P[i];
552            xl ^= F(xr) ^ P[i - 1];
553        }
554
555        xr ^= P[0];
556
557        Bits32ToBytes(xr, dst, dstIndex);
558        Bits32ToBytes(xl, dst, dstIndex+4);
559    }
560
561    private int BytesTo32bits(byte[] b, int i)
562    {
563        return ((b[i]   & 0xff) << 24) |
564             ((b[i+1] & 0xff) << 16) |
565             ((b[i+2] & 0xff) << 8) |
566             ((b[i+3] & 0xff));
567    }
568
569    private void Bits32ToBytes(int in,  byte[] b, int offset)
570    {
571        b[offset + 3] = (byte)in;
572        b[offset + 2] = (byte)(in >> 8);
573        b[offset + 1] = (byte)(in >> 16);
574        b[offset]     = (byte)(in >> 24);
575    }
576}
577