PageRenderTime 123ms CodeModel.GetById 27ms app.highlight 86ms RepoModel.GetById 1ms app.codeStats 0ms

/gnu/javax/crypto/cipher/Blowfish.java

https://github.com/penberg/classpath
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}