/gnu/javax/crypto/cipher/Blowfish.java
Java | 611 lines | 511 code | 20 blank | 80 comment | 11 complexity | 0434e5f89b5154bdfd4d469a2ff0eca9 MD5 | raw file
1/* Blowfish.java --
2 Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc.
3
4This file is a part of GNU Classpath.
5
6GNU Classpath is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2 of the License, or (at
9your option) any later version.
10
11GNU Classpath is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Classpath; if not, write to the Free Software
18Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
19USA
20
21Linking this library statically or dynamically with other modules is
22making a combined work based on this library. Thus, the terms and
23conditions of the GNU General Public License cover the whole
24combination.
25
26As a special exception, the copyright holders of this library give you
27permission to link this library with independent modules to produce an
28executable, regardless of the license terms of these independent
29modules, and to copy and distribute the resulting executable under
30terms of your choice, provided that you also meet, for each linked
31independent module, the terms and conditions of the license of that
32module. An independent module is a module which is not derived from
33or based on this library. If you modify this library, you may extend
34this exception to your version of the library, but you are not
35obligated to do so. If you do not wish to do so, delete this
36exception statement from your version. */
37
38// --------------------------------------------------------------------------
39//
40// Based on the C implementation from the GNU Privacy Guard.
41//
42// --------------------------------------------------------------------------
43
44package gnu.javax.crypto.cipher;
45
46import gnu.java.security.Registry;
47import gnu.java.security.util.Sequence;
48import gnu.java.security.util.Util;
49
50import java.util.Collections;
51import java.util.Iterator;
52
53/**
54 * Blowfish is a 16-round, 64-bit Feistel cipher designed by Bruce Schneier. It
55 * accepts a variable-length key of up to 448 bits.
56 * <p>
57 * References:
58 * <ol>
59 * <li>Schneier, Bruce: <i>Applied Cryptography</i>, Second Edition, 336--339,
60 * 647--654 (1996 Bruce Schneier).</li>
61 * <li><a href="http://www.counterpane.com/blowfish.html">The Blowfish
62 * Encryption Algorithm.</a></li>
63 * </ol>
64 */
65public class Blowfish
66 extends BaseCipher
67{
68 private static final int DEFAULT_BLOCK_SIZE = 8;
69 private static final int DEFAULT_KEY_SIZE = 8;
70 private static final int MAX_KEY_LENGTH = 56;
71 /** Initial value of the p-array. */
72 private static final int[] P = {
73 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0,
74 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
75 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b };
76 /** Initial value of S-box 1. */
77 static final int[] KS0 = {
78 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96,
79 0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
80 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, 0x0d95748f, 0x728eb658,
81 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
82 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e,
83 0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
84 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, 0x55ca396a, 0x2aab10b6,
85 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
86 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c,
87 0x7a325381, 0x28958677, 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
88 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, 0xef845d5d, 0xe98575b1,
89 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
90 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a,
91 0x670c9c61, 0xabd388f0, 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
92 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, 0xa1f1651d, 0x39af0176,
93 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
94 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706,
95 0x1bfedf72, 0x429b023d, 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
96 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, 0xe3fe501a, 0xb6794c3b,
97 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
98 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c,
99 0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
100 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, 0x5579c0bd, 0x1a60320a,
101 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
102 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760,
103 0x53317b48, 0x3e00df82, 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
104 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, 0x695b27b0, 0xbbca58c8,
105 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
106 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33,
107 0x62fb1341, 0xcee4c6e8, 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
108 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, 0xd08ed1d0, 0xafc725e0,
109 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
110 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777,
111 0xea752dfe, 0x8b021fa1, 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
112 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, 0x165fa266, 0x80957705,
113 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
114 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e,
115 0x226800bb, 0x57b8e0af, 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
116 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, 0x83260376, 0x6295cfa9,
117 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
118 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f,
119 0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
120 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a };
121 /** Initial value of S-box 2. */
122 private static final int[] KS1 = {
123 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d,
124 0x9cee60b8, 0x8fedb266, 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
125 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, 0x3f54989a, 0x5b429d65,
126 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
127 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9,
128 0x3c971814, 0x6b6a70a1, 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
129 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, 0xb03ada37, 0xf0500c0d,
130 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
131 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc,
132 0xc8b57634, 0x9af3dda7, 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
133 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, 0x4e548b38, 0x4f6db908,
134 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
135 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124,
136 0x501adde6, 0x9f84cd87, 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
137 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, 0xef1c1847, 0x3215d908,
138 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
139 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b,
140 0x3c11183b, 0x5924a509, 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
141 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, 0x771fe71c, 0x4e3d06fa,
142 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
143 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d,
144 0x1939260f, 0x19c27960, 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
145 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, 0xc332ddef, 0xbe6c5aa5,
146 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
147 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96,
148 0x0334fe1e, 0xaa0363cf, 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
149 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, 0x648b1eaf, 0x19bdf0ca,
150 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
151 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77,
152 0x11ed935f, 0x16681281, 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
153 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, 0xcdb30aeb, 0x532e3054,
154 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
155 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea,
156 0xdb6c4f15, 0xfacb4fd0, 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
157 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, 0xcf62a1f2, 0x5b8d2646,
158 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
159 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea,
160 0x1dadf43e, 0x233f7061, 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
161 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, 0xa6078084, 0x19f8509e,
162 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
163 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd,
164 0x675fda79, 0xe3674340, 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
165 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7 };
166 /** Initial value of S-box 3. */
167 private static final int[] KS2 = {
168 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7,
169 0xbcf46b2e, 0xd4a20068, 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
170 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, 0x4d95fc1d, 0x96b591af,
171 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
172 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4,
173 0x0a2c86da, 0xe9b66dfb, 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
174 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, 0xaace1e7c, 0xd3375fec,
175 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
176 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332,
177 0x6841e7f7, 0xca7820fb, 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
178 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, 0x55a867bc, 0xa1159a58,
179 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
180 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22,
181 0x48c1133f, 0xc70f86dc, 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
182 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, 0x257b7834, 0x602a9c60,
183 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
184 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99,
185 0xde720c8c, 0x2da2f728, 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
186 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, 0x0a476341, 0x992eff74,
187 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
188 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3,
189 0xb5390f92, 0x690fed0b, 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
190 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, 0x37392eb3, 0xcc115979,
191 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
192 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa,
193 0x3d25bdd8, 0xe2e1c3c9, 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
194 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, 0x9dbc8057, 0xf0f7c086,
195 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
196 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24,
197 0x55464299, 0xbf582e61, 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
198 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, 0x7aeb2661, 0x8b1ddf84,
199 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
200 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09,
201 0x662d09a1, 0xc4324633, 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
202 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, 0xdcb7da83, 0x573906fe,
203 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
204 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0,
205 0x006058aa, 0x30dc7d62, 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
206 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, 0x6f05e409, 0x4b7c0188,
207 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
208 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8,
209 0xa28514d9, 0x6c51133c, 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
210 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0 };
211 /** Initial value of S-box 4. */
212 private static final int[] KS3 = {
213 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742,
214 0xd3822740, 0x99bc9bbe, 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
215 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, 0x5748ab2f, 0xbc946e79,
216 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
217 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a,
218 0x63ef8ce2, 0x9a86ee22, 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
219 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, 0x2826a2f9, 0xa73a3ae1,
220 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
221 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797,
222 0x2cf0b7d9, 0x022b8b51, 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
223 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, 0xe029ac71, 0xe019a5e6,
224 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
225 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba,
226 0x03a16125, 0x0564f0bd, 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
227 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, 0x7533d928, 0xb155fdf5,
228 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
229 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce,
230 0x5121ce64, 0x774fbe32, 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
231 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, 0xb39a460a, 0x6445c0dd,
232 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
233 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb,
234 0x8d6612ae, 0xbf3c6f47, 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
235 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, 0x4040cb08, 0x4eb4e2cc,
236 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
237 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc,
238 0xbb3a792b, 0x344525bd, 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
239 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, 0x1a908749, 0xd44fbd9a,
240 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
241 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a,
242 0x0f91fc71, 0x9b941525, 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
243 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, 0xe0ec6e0e, 0x1698db3b,
244 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
245 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e,
246 0xe60b6f47, 0x0fe3f11d, 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
247 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, 0xf523f357, 0xa6327623,
248 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
249 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a,
250 0x45e1d006, 0xc3f27b9a, 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
251 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, 0x53113ec0, 0x1640e3d3,
252 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
253 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c,
254 0x01c36ae4, 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
255 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 };
256 /** Cache of the self test. */
257 private static Boolean valid;
258 /**
259 * Test vector, as published in
260 * href="http://www.counterpane.com/vectors.txt">http://www.counterpane.com/vectors.txt</a>.
261 *
262 * KEY=0000000000000000
263 * PT=0000000000000000
264 * CT=4EF997456198DD78
265 */
266 private static final byte[] TV_KEY = Util.toBytesFromString("0000000000000000");
267 private static final byte[] TV_CT = Util.toBytesFromString("4EF997456198DD78");
268
269 public Blowfish()
270 {
271 super(Registry.BLOWFISH_CIPHER, DEFAULT_BLOCK_SIZE, DEFAULT_KEY_SIZE);
272 }
273
274 public Object clone()
275 {
276 Blowfish result = new Blowfish();
277 result.currentBlockSize = currentBlockSize;
278 return result;
279 }
280
281 public Iterator keySizes()
282 {
283 return new Sequence(8, MAX_KEY_LENGTH, 8).iterator();
284 }
285
286 public Iterator blockSizes()
287 {
288 return Collections.singleton(Integer.valueOf(DEFAULT_BLOCK_SIZE)).iterator();
289 }
290
291 public Object makeKey(byte[] k, int bs)
292 {
293 Context ctx = new Context();
294 System.arraycopy(P, 0, ctx.p, 0, P.length);
295 System.arraycopy(KS0, 0, ctx.s0, 0, KS0.length);
296 System.arraycopy(KS1, 0, ctx.s1, 0, KS1.length);
297 System.arraycopy(KS2, 0, ctx.s2, 0, KS2.length);
298 System.arraycopy(KS3, 0, ctx.s3, 0, KS3.length);
299 // XOR the key with the P-box
300 int l = 0;
301 for (int i = 0; i < ctx.p.length; i++)
302 {
303 int data = 0;
304 for (int j = 0; j < 4; j++)
305 {
306 data = (data << 8) | (k[l++] & 0xff);
307 if (l >= k.length)
308 l = 0;
309 }
310 ctx.p[i] ^= data;
311 }
312 // We swap the left and right words here only, so we can avoid
313 // swapping altogether during encryption/decryption.
314 int t;
315 Block x = new Block();
316 x.left = x.right = 0;
317 for (int i = 0; i < ctx.p.length; i += 2)
318 {
319 blowfishEncrypt(x, ctx);
320 ctx.p[i] = x.right;
321 ctx.p[i + 1] = x.left;
322 t = x.right;
323 x.right = x.left;
324 x.left = t;
325 }
326 for (int i = 0; i < ctx.s0.length; i += 2)
327 {
328 blowfishEncrypt(x, ctx);
329 ctx.s0[i] = x.right;
330 ctx.s0[i + 1] = x.left;
331 t = x.right;
332 x.right = x.left;
333 x.left = t;
334 }
335 for (int i = 0; i < ctx.s1.length; i += 2)
336 {
337 blowfishEncrypt(x, ctx);
338 ctx.s1[i] = x.right;
339 ctx.s1[i + 1] = x.left;
340 t = x.right;
341 x.right = x.left;
342 x.left = t;
343 }
344 for (int i = 0; i < ctx.s2.length; i += 2)
345 {
346 blowfishEncrypt(x, ctx);
347 ctx.s2[i] = x.right;
348 ctx.s2[i + 1] = x.left;
349 t = x.right;
350 x.right = x.left;
351 x.left = t;
352 }
353 for (int i = 0; i < ctx.s3.length; i += 2)
354 {
355 blowfishEncrypt(x, ctx);
356 ctx.s3[i] = x.right;
357 ctx.s3[i + 1] = x.left;
358 t = x.right;
359 x.right = x.left;
360 x.left = t;
361 }
362 x.left = x.right = 0;
363 return ctx;
364 }
365
366 public void encrypt(byte[] in, int i, byte[] out, int o, Object k, int bs)
367 {
368 Block x = new Block();
369 x.left = (in[i ] & 0xff) << 24
370 | (in[i + 1] & 0xff) << 16
371 | (in[i + 2] & 0xff) << 8
372 | (in[i + 3] & 0xff);
373 x.right = (in[i + 4] & 0xff) << 24
374 | (in[i + 5] & 0xff) << 16
375 | (in[i + 6] & 0xff) << 8
376 | (in[i + 7] & 0xff);
377 blowfishEncrypt(x, (Context) k);
378 out[o ] = (byte)(x.right >>> 24);
379 out[o + 1] = (byte)(x.right >>> 16);
380 out[o + 2] = (byte)(x.right >>> 8);
381 out[o + 3] = (byte) x.right;
382 out[o + 4] = (byte)(x.left >>> 24);
383 out[o + 5] = (byte)(x.left >>> 16);
384 out[o + 6] = (byte)(x.left >>> 8);
385 out[o + 7] = (byte) x.left;
386 x.left = x.right = 0;
387 }
388
389 public void decrypt(byte[] in, int i, byte[] out, int o, Object k, int bs)
390 {
391 Block x = new Block();
392 x.left = (in[i ] & 0xff) << 24
393 | (in[i + 1] & 0xff) << 16
394 | (in[i + 2] & 0xff) << 8
395 | (in[i + 3] & 0xff);
396 x.right = (in[i + 4] & 0xff) << 24
397 | (in[i + 5] & 0xff) << 16
398 | (in[i + 6] & 0xff) << 8
399 | (in[i + 7] & 0xff);
400 blowfishDecrypt(x, (Context) k);
401 out[o ] = (byte)(x.right >>> 24);
402 out[o + 1] = (byte)(x.right >>> 16);
403 out[o + 2] = (byte)(x.right >>> 8);
404 out[o + 3] = (byte) x.right;
405 out[o + 4] = (byte)(x.left >>> 24);
406 out[o + 5] = (byte)(x.left >>> 16);
407 out[o + 6] = (byte)(x.left >>> 8);
408 out[o + 7] = (byte) x.left;
409 x.left = x.right = 0;
410 }
411
412 /** Encrypt a single pair of 32-bit integers. */
413 private void blowfishEncrypt(Block x, Context ctx)
414 {
415 int[] p = ctx.p;
416 int[] s0 = ctx.s0, s1 = ctx.s1, s2 = ctx.s2, s3 = ctx.s3;
417 x.left ^= p[0];
418 x.right ^= ((s0[x.left >>> 24 ]
419 + s1[x.left >>> 16 & 0xff])
420 ^ s2[x.left >>> 8 & 0xff])
421 + s3[x.left & 0xff] ^ p[1];
422 x.left ^= ((s0[x.right >>> 24 ]
423 + s1[x.right >>> 16 & 0xff])
424 ^ s2[x.right >>> 8 & 0xff])
425 + s3[x.right & 0xff] ^ p[2];
426 x.right ^= ((s0[x.left >>> 24 ]
427 + s1[x.left >>> 16 & 0xff])
428 ^ s2[x.left >>> 8 & 0xff])
429 + s3[x.left & 0xff] ^ p[3];
430 x.left ^= ((s0[x.right >>> 24 ]
431 + s1[x.right >>> 16 & 0xff])
432 ^ s2[x.right >>> 8 & 0xff])
433 + s3[x.right & 0xff] ^ p[4];
434 x.right ^= ((s0[x.left >>> 24 ]
435 + s1[x.left >>> 16 & 0xff])
436 ^ s2[x.left >>> 8 & 0xff])
437 + s3[x.left & 0xff] ^ p[5];
438 x.left ^= ((s0[x.right >>> 24 ]
439 + s1[x.right >>> 16 & 0xff])
440 ^ s2[x.right >>> 8 & 0xff])
441 + s3[x.right & 0xff] ^ p[6];
442 x.right ^= ((s0[x.left >>> 24 ]
443 + s1[x.left >>> 16 & 0xff])
444 ^ s2[x.left >>> 8 & 0xff])
445 + s3[x.left & 0xff] ^ p[7];
446 x.left ^= ((s0[x.right >>> 24 ]
447 + s1[x.right >>> 16 & 0xff])
448 ^ s2[x.right >>> 8 & 0xff])
449 + s3[x.right & 0xff] ^ p[8];
450 x.right ^= ((s0[x.left >>> 24 ]
451 + s1[x.left >>> 16 & 0xff])
452 ^ s2[x.left >>> 8 & 0xff])
453 + s3[x.left & 0xff] ^ p[9];
454 x.left ^= ((s0[x.right >>> 24 ]
455 + s1[x.right >>> 16 & 0xff])
456 ^ s2[x.right >>> 8 & 0xff])
457 + s3[x.right & 0xff] ^ p[10];
458 x.right ^= ((s0[x.left >>> 24 ]
459 + s1[x.left >>> 16 & 0xff])
460 ^ s2[x.left >>> 8 & 0xff])
461 + s3[x.left & 0xff] ^ p[11];
462 x.left ^= ((s0[x.right >>> 24 ]
463 + s1[x.right >>> 16 & 0xff])
464 ^ s2[x.right >>> 8 & 0xff])
465 + s3[x.right & 0xff] ^ p[12];
466 x.right ^= ((s0[x.left >>> 24 ]
467 + s1[x.left >>> 16 & 0xff])
468 ^ s2[x.left >>> 8 & 0xff])
469 + s3[x.left & 0xff] ^ p[13];
470 x.left ^= ((s0[x.right >>> 24 ]
471 + s1[x.right >>> 16 & 0xff])
472 ^ s2[x.right >>> 8 & 0xff])
473 + s3[x.right & 0xff] ^ p[14];
474 x.right ^= ((s0[x.left >>> 24 ]
475 + s1[x.left >>> 16 & 0xff])
476 ^ s2[x.left >>> 8 & 0xff])
477 + s3[x.left & 0xff] ^ p[15];
478 x.left ^= ((s0[x.right >>> 24 ]
479 + s1[x.right >>> 16 & 0xff])
480 ^ s2[x.right >>> 8 & 0xff])
481 + s3[x.right & 0xff] ^ p[16];
482 x.right ^= p[17];
483 }
484
485 /** Decrypt a single pair of 32-bit integers. */
486 private void blowfishDecrypt(Block x, Context ctx)
487 {
488 int[] p = ctx.p;
489 int[] s0 = ctx.s0, s1 = ctx.s1, s2 = ctx.s2, s3 = ctx.s3;
490 x.left ^= p[17];
491 x.right ^= ((s0[x.left >>> 24 ]
492 + s1[x.left >>> 16 & 0xff])
493 ^ s2[x.left >>> 8 & 0xff])
494 + s3[x.left & 0xff] ^ p[16];
495 x.left ^= ((s0[x.right >>> 24 ]
496 + s1[x.right >>> 16 & 0xff])
497 ^ s2[x.right >>> 8 & 0xff])
498 + s3[x.right & 0xff] ^ p[15];
499 x.right ^= ((s0[x.left >>> 24 ]
500 + s1[x.left >>> 16 & 0xff])
501 ^ s2[x.left >>> 8 & 0xff])
502 + s3[x.left & 0xff] ^ p[14];
503 x.left ^= ((s0[x.right >>> 24 ]
504 + s1[x.right >>> 16 & 0xff])
505 ^ s2[x.right >>> 8 & 0xff])
506 + s3[x.right & 0xff] ^ p[13];
507 x.right ^= ((s0[x.left >>> 24 ]
508 + s1[x.left >>> 16 & 0xff])
509 ^ s2[x.left >>> 8 & 0xff])
510 + s3[x.left & 0xff] ^ p[12];
511 x.left ^= ((s0[x.right >>> 24 ]
512 + s1[x.right >>> 16 & 0xff])
513 ^ s2[x.right >>> 8 & 0xff])
514 + s3[x.right & 0xff] ^ p[11];
515 x.right ^= ((s0[x.left >>> 24 ]
516 + s1[x.left >>> 16 & 0xff])
517 ^ s2[x.left >>> 8 & 0xff])
518 + s3[x.left & 0xff] ^ p[10];
519 x.left ^= ((s0[x.right >>> 24 ]
520 + s1[x.right >>> 16 & 0xff])
521 ^ s2[x.right >>> 8 & 0xff])
522 + s3[x.right & 0xff] ^ p[9];
523 x.right ^= ((s0[x.left >>> 24]
524 + s1[x.left >>> 16 & 0xff])
525 ^ s2[x.left >>> 8 & 0xff])
526 + s3[x.left & 0xff] ^ p[8];
527 x.left ^= ((s0[x.right >>> 24 ]
528 + s1[x.right >>> 16 & 0xff])
529 ^ s2[x.right >>> 8 & 0xff])
530 + s3[x.right & 0xff] ^ p[7];
531 x.right ^= ((s0[x.left >>> 24 ]
532 + s1[x.left >>> 16 & 0xff])
533 ^ s2[x.left >>> 8 & 0xff])
534 + s3[x.left & 0xff] ^ p[6];
535 x.left ^= ((s0[x.right >>> 24 ]
536 + s1[x.right >>> 16 & 0xff])
537 ^ s2[x.right >>> 8 & 0xff])
538 + s3[x.right & 0xff] ^ p[5];
539 x.right ^= ((s0[x.left >>> 24 ]
540 + s1[x.left >>> 16 & 0xff])
541 ^ s2[x.left >>> 8 & 0xff])
542 + s3[x.left & 0xff] ^ p[4];
543 x.left ^= ((s0[x.right >>> 24 ]
544 + s1[x.right >>> 16 & 0xff])
545 ^ s2[x.right >>> 8 & 0xff])
546 + s3[x.right & 0xff] ^ p[3];
547 x.right ^= ((s0[x.left >>> 24 ]
548 + s1[x.left >>> 16 & 0xff])
549 ^ s2[x.left >>> 8 & 0xff])
550 + s3[x.left & 0xff] ^ p[2];
551 x.left ^= ((s0[x.right >>> 24 ]
552 + s1[x.right >>> 16 & 0xff])
553 ^ s2[x.right >>> 8 & 0xff])
554 + s3[x.right & 0xff] ^ p[1];
555 x.right ^= p[0];
556 }
557
558 public boolean selfTest()
559 {
560 if (valid == null)
561 {
562 boolean result = super.selfTest(); // symmetry
563 if (result)
564 result = testKat(TV_KEY, TV_CT);
565 valid = Boolean.valueOf(result);
566 }
567 return valid.booleanValue();
568 }
569
570 /** A simple wrapper for the P- and S-boxes. */
571 private class Context
572 implements Cloneable
573 {
574 /** The P-array. */
575 int[] p, s0, s1, s2, s3;
576
577 /** Default 0-arguments constructor. */
578 Context()
579 {
580 p = new int[18];
581 s0 = new int[256];
582 s1 = new int[256];
583 s2 = new int[256];
584 s3 = new int[256];
585 }
586
587 /**
588 * Private constructor for cloneing.
589 *
590 * @param that The instance being cloned.
591 */
592 private Context(Context that)
593 {
594 this.p = (int[]) that.p.clone();
595 this.s0 = (int[]) that.s0.clone();
596 this.s1 = (int[]) that.s1.clone();
597 this.s2 = (int[]) that.s2.clone();
598 this.s3 = (int[]) that.s3.clone();
599 }
600
601 public Object clone()
602 {
603 return new Context(this);
604 }
605 }
606
607 private class Block
608 {
609 int left, right;
610 }
611}