001//Copyright (c) 2006 Damien Miller <djm@mindrot.org>
002//
003//Permission to use, copy, modify, and distribute this software for any
004//purpose with or without fee is hereby granted, provided that the above
005//copyright notice and this permission notice appear in all copies.
006//
007//THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
008//WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
009//MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
010//ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
011//WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
012//ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
013//OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
014
015package org.apache.directory.api.ldap.model.password;
016
017
018import java.nio.charset.StandardCharsets;
019import java.security.SecureRandom;
020
021import org.apache.directory.api.i18n.I18n;
022
023
024/**
025* BCrypt implements OpenBSD-style Blowfish password hashing using
026* the scheme described in "A Future-Adaptable Password Scheme" by
027* Niels Provos and David Mazieres.
028* <p>
029* This password hashing system tries to thwart off-line password
030* cracking using a computationally-intensive hashing algorithm,
031* based on Bruce Schneier's Blowfish cipher. The work factor of
032* the algorithm is parameterised, so it can be increased as
033* computers get faster.
034* <p>
035* Usage is really simple. To hash a password for the first time,
036* call the hashpw method with a random salt, like this:
037* <p>
038* <code>
039* String pw_hash = BCrypt.hashpw(plain_password, BCrypt.gensalt()); <br>
040* </code>
041* <p>
042* To check whether a plaintext password matches one that has been
043* hashed previously, use the checkpw method:
044* <p>
045* <code>
046* if (BCrypt.checkpw(candidate_password, stored_hash))<br>
047* &nbsp;&nbsp;&nbsp;&nbsp;System.out.println("It matches");<br>
048* else<br>
049* &nbsp;&nbsp;&nbsp;&nbsp;System.out.println("It does not match");<br>
050* </code>
051* <p>
052* The gensalt() method takes an optional parameter (log_rounds)
053* that determines the computational complexity of the hashing:
054* <p>
055* <code>
056* String strong_salt = BCrypt.gensalt(10)<br>
057* String stronger_salt = BCrypt.gensalt(12)<br>
058* </code>
059* <p>
060* The amount of work increases exponentially (2**log_rounds), so 
061* each increment is twice as much work. The default log_rounds is
062* 10, and the valid range is 4 to 30.
063*
064* @author Damien Miller
065* @version 0.2
066*/
067public class BCrypt
068{
069    // BCrypt parameters
070    private static final int GENSALT_DEFAULT_LOG2_ROUNDS = 10;
071    private static final int BCRYPT_SALT_LEN = 16;
072
073    // Blowfish parameters
074    private static final int BLOWFISH_NUM_ROUNDS = 16;
075
076    // Initial contents of key schedule
077    private static final int[] P_ORIG =
078        {
079            0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
080            0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
081            0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
082            0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
083            0x9216d5d9, 0x8979fb1b
084        };
085
086    private static final int[] S_ORIG =
087        {
088            0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
089            0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
090            0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
091            0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
092            0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
093            0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
094            0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
095            0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
096            0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
097            0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
098            0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
099            0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
100            0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
101            0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
102            0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
103            0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
104            0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
105            0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
106            0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
107            0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
108            0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
109            0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
110            0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
111            0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
112            0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
113            0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
114            0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
115            0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
116            0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
117            0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
118            0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
119            0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
120            0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
121            0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
122            0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
123            0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
124            0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
125            0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
126            0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
127            0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
128            0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
129            0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
130            0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
131            0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
132            0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
133            0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
134            0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
135            0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
136            0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
137            0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
138            0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
139            0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
140            0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
141            0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
142            0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
143            0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
144            0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
145            0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
146            0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
147            0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
148            0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
149            0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
150            0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
151            0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a,
152            0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
153            0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
154            0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
155            0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
156            0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
157            0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
158            0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
159            0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
160            0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
161            0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
162            0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
163            0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
164            0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
165            0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
166            0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
167            0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
168            0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
169            0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
170            0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
171            0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
172            0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
173            0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
174            0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
175            0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
176            0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
177            0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
178            0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
179            0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
180            0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
181            0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
182            0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
183            0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
184            0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
185            0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
186            0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
187            0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
188            0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
189            0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
190            0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
191            0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
192            0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
193            0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
194            0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
195            0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
196            0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
197            0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
198            0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
199            0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
200            0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
201            0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
202            0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
203            0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
204            0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
205            0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
206            0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
207            0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
208            0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
209            0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
210            0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
211            0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
212            0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
213            0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
214            0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
215            0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7,
216            0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
217            0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
218            0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
219            0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
220            0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
221            0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
222            0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
223            0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
224            0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
225            0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
226            0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
227            0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
228            0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
229            0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
230            0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
231            0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
232            0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
233            0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
234            0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
235            0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
236            0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
237            0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
238            0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
239            0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
240            0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
241            0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
242            0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
243            0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
244            0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
245            0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
246            0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
247            0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
248            0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
249            0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
250            0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
251            0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
252            0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
253            0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
254            0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
255            0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
256            0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
257            0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
258            0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
259            0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
260            0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
261            0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
262            0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
263            0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
264            0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
265            0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
266            0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
267            0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
268            0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
269            0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
270            0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
271            0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
272            0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
273            0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
274            0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
275            0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
276            0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
277            0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
278            0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
279            0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0,
280            0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
281            0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
282            0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
283            0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
284            0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
285            0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
286            0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
287            0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
288            0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
289            0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
290            0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
291            0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
292            0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
293            0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
294            0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
295            0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
296            0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
297            0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
298            0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
299            0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
300            0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
301            0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
302            0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
303            0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
304            0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
305            0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
306            0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
307            0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
308            0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
309            0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
310            0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
311            0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
312            0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
313            0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
314            0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
315            0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
316            0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
317            0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
318            0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
319            0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
320            0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
321            0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
322            0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
323            0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
324            0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
325            0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
326            0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
327            0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
328            0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
329            0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
330            0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
331            0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
332            0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
333            0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
334            0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
335            0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
336            0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
337            0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
338            0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
339            0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
340            0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
341            0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
342            0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
343            0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
344        };
345
346    // bcrypt IV: "OrpheanBeholderScryDoubt". The C implementation calls
347    // this "ciphertext", but it is really plaintext or an IV. We keep
348    // the name to make code comparison easier.
349    private static final int[] BF_CRYPT_CIPHERTEXT =
350        {
351            0x4f727068,
352            0x65616e42,
353            0x65686f6c,
354            0x64657253,
355            0x63727944,
356            0x6f756274
357        };
358
359    // Table for Base64 encoding
360    private static final char[] BASE_64_CHAR =
361        {
362            '.', '/', 'A', 'B', 'C', 'D', 'E', 'F', 
363            'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 
364            'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 
365            'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 
366            'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 
367            'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 
368            'u', 'v', 'w', 'x', 'y', 'z', '0', '1', 
369            '2', '3', '4', '5', '6', '7', '8', '9' 
370        };
371
372    // Table for Base64 decoding
373    private static final byte[] INDEX_64 =
374        {
375            -1, -1, -1, -1, -1, -1, -1, -1, 
376            -1, -1, -1, -1, -1, -1, -1, -1, 
377            -1, -1, -1, -1, -1, -1, -1, -1, 
378            -1, -1, -1, -1, -1, -1, -1, -1, 
379            -1, -1, -1, -1, -1, -1, -1, -1, 
380            -1, -1, -1, -1, -1, -1,  0,  1, 
381            54, 55, 56, 57, 58, 59, 60, 61, 
382            62, 63, -1, -1, -1, -1, -1, -1, 
383            -1,  2,  3,  4,  5,  6,  7,  8, 
384             9, 10, 11, 12, 13, 14, 15, 16, 
385            17, 18, 19, 20, 21, 22, 23, 24, 
386            25, 26, 27, -1, -1, -1, -1, -1, 
387            -1, 28, 29, 30, 31, 32, 33, 34, 
388            35, 36, 37, 38, 39, 40, 41, 42, 
389            43, 44, 45, 46, 47, 48, 49, 50, 
390            51, 52, 53, -1, -1, -1, -1, -1
391        };
392
393    // Expanded Blowfish key
394    private int[] pKey;
395    private int[] sKey;
396
397
398    /**
399     * Encode a byte array using bcrypt's slightly-modified base64
400     * encoding scheme. Note that this is *not* compatible with
401     * the standard MIME-base64 encoding.
402     *
403     * @param d the byte array to encode
404     * @param len   the number of bytes to encode
405     * @return  base64-encoded string
406     * @exception IllegalArgumentException if the length is invalid
407     */
408    private static String encodeBase64( byte[] d, int len )
409    {
410        int off = 0;
411        StringBuilder rs = new StringBuilder();
412        int c1;
413        int c2;
414
415        if ( len <= 0 || len > d.length )
416        {
417            throw new IllegalArgumentException( I18n.err( I18n.ERR_13000_INVALID_LENGTH ) );
418        }
419
420        while ( off < len )
421        {
422            c1 = d[off++] & 0xff;
423            rs.append( BASE_64_CHAR[( c1 >> 2 ) & 0x3f] );
424            c1 = ( c1 & 0x03 ) << 4;
425            
426            if ( off >= len )
427            {
428                rs.append( BASE_64_CHAR[c1 & 0x3f] );
429                break;
430            }
431            
432            c2 = d[off++] & 0xff;
433            c1 |= ( c2 >> 4 ) & 0x0f;
434            rs.append( BASE_64_CHAR[c1 & 0x3f] );
435            c1 = ( c2 & 0x0f ) << 2;
436            
437            if ( off >= len )
438            {
439                rs.append( BASE_64_CHAR[c1 & 0x3f] );
440                break;
441            }
442            
443            c2 = d[off++] & 0xff;
444            c1 |= ( c2 >> 6 ) & 0x03;
445            rs.append( BASE_64_CHAR[c1 & 0x3f] );
446            rs.append( BASE_64_CHAR[c2 & 0x3f] );
447        }
448        
449        return rs.toString();
450    }
451
452
453    /**
454     * Look up the 3 bits base64-encoded by the specified character,
455     * range-checking agaisnt conversion table
456     * @param x the base64-encoded value
457     * @return  the decoded value of x
458     */
459    private static byte char64( char x )
460    {
461        if ( ( int ) x < 0 || ( int ) x > INDEX_64.length )
462        {
463            return -1;
464        }
465
466        return INDEX_64[( int ) x];
467    }
468
469
470    /**
471     * Decode a string encoded using bcrypt's base64 scheme to a
472     * byte array. Note that this is *not* compatible with
473     * the standard MIME-base64 encoding.
474     * @param s the string to decode
475     * @param maxolen   the maximum number of bytes to decode
476     * @return  an array containing the decoded bytes
477     * @throws IllegalArgumentException if maxolen is invalid
478     */
479    private static byte[] decodeBase64( String s, int maxolen )
480    {
481        StringBuilder rs = new StringBuilder();
482        int off = 0;
483        int slen = s.length();
484        int olen = 0;
485        byte[] ret;
486        byte c1;
487        byte c2;
488        byte c3;
489        byte c4;
490        byte o;
491
492        if ( maxolen <= 0 )
493        {
494            throw new IllegalArgumentException( I18n.err( I18n.ERR_13001_INVALID_MAXOLEN ) );
495        }
496
497        while ( off < slen - 1 && olen < maxolen )
498        {
499            c1 = char64( s.charAt( off++ ) );
500            c2 = char64( s.charAt( off++ ) );
501            
502            if ( c1 == -1 || c2 == -1 )
503            {
504                break;
505            }
506            
507            o = ( byte ) ( c1 << 2 );
508            o |= ( c2 & 0x30 ) >> 4;
509            rs.append( ( char ) o );
510            
511            if ( ++olen >= maxolen || off >= slen )
512            {
513                break;
514            }
515            
516            c3 = char64( s.charAt( off++ ) );
517            
518            if ( c3 == -1 )
519            {
520                break;
521            }
522            
523            o = ( byte ) ( ( c2 & 0x0f ) << 4 );
524            o |= ( c3 & 0x3c ) >> 2;
525            rs.append( ( char ) o );
526            
527            if ( ++olen >= maxolen || off >= slen )
528            {
529                break;
530            }
531            
532            c4 = char64( s.charAt( off++ ) );
533            o = ( byte ) ( ( c3 & 0x03 ) << 6 );
534            o |= c4;
535            rs.append( ( char ) o );
536            ++olen;
537        }
538
539        ret = new byte[olen];
540        
541        for ( off = 0; off < olen; off++ )
542        {
543            ret[off] = ( byte ) rs.charAt( off );
544        }
545        
546        return ret;
547    }
548
549
550    /**
551     * Blowfish encipher a single 64-bit block encoded as
552     * two 32-bit halves
553     * @param lr    an array containing the two 32-bit half blocks
554     * @param off   the position in the array of the blocks
555     */
556    private void encipher( int[] lr, int off )
557    {
558        int i;
559        int n;
560        int l = lr[off];
561        int r = lr[off + 1];
562
563        l ^= pKey[0];
564        
565        for ( i = 0; i <= BLOWFISH_NUM_ROUNDS - 2; )
566        {
567            // Feistel substitution on left word
568            n = sKey[( l >> 24 ) & 0xff];
569            n += sKey[0x100 | ( ( l >> 16 ) & 0xff )];
570            n ^= sKey[0x200 | ( ( l >> 8 ) & 0xff )];
571            n += sKey[0x300 | ( l & 0xff )];
572            r ^= n ^ pKey[++i];
573
574            // Feistel substitution on right word
575            n = sKey[( r >> 24 ) & 0xff];
576            n += sKey[0x100 | ( ( r >> 16 ) & 0xff )];
577            n ^= sKey[0x200 | ( ( r >> 8 ) & 0xff )];
578            n += sKey[0x300 | ( r & 0xff )];
579            l ^= n ^ pKey[++i];
580        }
581        
582        lr[off] = r ^ pKey[BLOWFISH_NUM_ROUNDS + 1];
583        lr[off + 1] = l;
584    }
585
586
587    /**
588     * Cycically extract a word of key material
589     * @param data  the string to extract the data from
590     * @param offp  a "pointer" (as a one-entry array) to the
591     * current offset into data
592     * @return  the next word of material from data
593     */
594    private static int streamToWord( byte[] data, int[] offp )
595    {
596        int i;
597        int word = 0;
598        int off = offp[0];
599
600        for ( i = 0; i < 4; i++ )
601        {
602            word = ( word << 8 ) | ( data[off] & 0xff );
603            off = ( off + 1 ) % data.length;
604        }
605
606        offp[0] = off;
607        
608        return word;
609    }
610
611
612    /**
613     * Initialise the Blowfish key schedule
614     */
615    private void initKey()
616    {
617        pKey = ( int[] ) P_ORIG.clone();
618        sKey = ( int[] ) S_ORIG.clone();
619    }
620
621
622    /**
623     * Key the Blowfish cipher
624     * @param key   an array containing the key
625     */
626    private void key( byte[] key )
627    {
628        int i;
629        int[] koffp = { 0 };
630        int[] lr = { 0, 0 };
631        int plen = pKey.length;
632        int slen = sKey.length;
633
634        for ( i = 0; i < plen; i++ )
635        {
636            pKey[i] = pKey[i] ^ streamToWord( key, koffp );
637        }
638
639        for ( i = 0; i < plen; i += 2 )
640        {
641            encipher( lr, 0 );
642            pKey[i] = lr[0];
643            pKey[i + 1] = lr[1];
644        }
645
646        for ( i = 0; i < slen; i += 2 )
647        {
648            encipher( lr, 0 );
649            sKey[i] = lr[0];
650            sKey[i + 1] = lr[1];
651        }
652    }
653
654
655    /**
656     * Perform the "enhanced key schedule" step described by
657     * Provos and Mazieres in "A Future-Adaptable Password Scheme"
658     * http://www.openbsd.org/papers/bcrypt-paper.ps
659     * @param data  salt information
660     * @param key   password information
661     */
662    private void eksKey( byte[] data, byte[] key )
663    {
664        int i;
665        int[] koffp = { 0 };
666        int[] doffp = { 0 };
667        int[] lr = { 0, 0 };
668        int plen = pKey.length;
669        int slen = sKey.length;
670
671        for ( i = 0; i < plen; i++ )
672        {
673            pKey[i] = pKey[i] ^ streamToWord( key, koffp );
674        }
675
676        for ( i = 0; i < plen; i += 2 )
677        {
678            lr[0] ^= streamToWord( data, doffp );
679            lr[1] ^= streamToWord( data, doffp );
680            encipher( lr, 0 );
681            pKey[i] = lr[0];
682            pKey[i + 1] = lr[1];
683        }
684
685        for ( i = 0; i < slen; i += 2 )
686        {
687            lr[0] ^= streamToWord( data, doffp );
688            lr[1] ^= streamToWord( data, doffp );
689            encipher( lr, 0 );
690            sKey[i] = lr[0];
691            sKey[i + 1] = lr[1];
692        }
693    }
694
695
696    /**
697     * Perform the central password hashing step in the
698     * bcrypt scheme
699     * 
700     * @param password  the password to hash
701     * @param salt  the binary salt to hash with the password
702     * @param logRounds    the binary logarithm of the number
703     * of rounds of hashing to apply
704     * @param cdata         the plaintext to encrypt
705     * @return  an array containing the binary hashed password
706     */
707    public byte[] cryptRaw( byte[] password, byte[] salt, int logRounds, int[] cdata )
708    {
709        int rounds;
710        int i;
711        int j;
712        int clen = cdata.length;
713        byte[] ret;
714
715        if ( logRounds < 4 || logRounds > 30 )
716        {
717            throw new IllegalArgumentException( I18n.err( I18n.ERR_13002_BAD_NUMBERS_OF_ROUNDS ) );
718        }
719        
720        rounds = 1 << logRounds;
721        
722        if ( salt.length != BCRYPT_SALT_LEN )
723        {
724            throw new IllegalArgumentException( I18n.err( I18n.ERR_13003_BAD_SALT_LENGTH ) );
725        }
726
727        initKey();
728        eksKey( salt, password );
729        
730        for ( i = 0; i != rounds; i++ )
731        {
732            key( password );
733            key( salt );
734        }
735
736        for ( i = 0; i < 64; i++ )
737        {
738            for ( j = 0; j < ( clen >> 1 ); j++ )
739            {
740                encipher( cdata, j << 1 );
741            }
742        }
743
744        ret = new byte[clen * 4];
745        
746        for ( i = 0, j = 0; i < clen; i++ )
747        {
748            ret[j++] = ( byte ) ( ( cdata[i] >> 24 ) & 0xff );
749            ret[j++] = ( byte ) ( ( cdata[i] >> 16 ) & 0xff );
750            ret[j++] = ( byte ) ( ( cdata[i] >> 8 ) & 0xff );
751            ret[j++] = ( byte ) ( cdata[i] & 0xff );
752        }
753        
754        return ret;
755    }
756
757
758    /**
759     * Hash a password using the OpenBSD bcrypt scheme
760     * @param password  the password to hash
761     * @param salt  the salt to hash with (perhaps generated
762     * using BCrypt.gensalt)
763     * @return  the hashed password
764     */
765    public static String hashPw( String password, String salt )
766    {
767        BCrypt bcrypt;
768        String realSalt;
769        byte[] passwordb;
770        byte[] saltb;
771        byte[] hashed;
772        char minor = ( char ) 0;
773        int rounds;
774        int off;
775        StringBuilder rs = new StringBuilder();
776
777        if ( salt.charAt( 0 ) != '$' || salt.charAt( 1 ) != '2' )
778        {
779            throw new IllegalArgumentException( I18n.err( I18n.ERR_13004_INVALID_SALT_VERSION ) );
780        }
781        
782        if ( salt.charAt( 2 ) == '$' )
783        {
784            off = 3;
785        }
786        
787        else
788        {
789            minor = salt.charAt( 2 );
790            
791            if ( minor != 'a' || salt.charAt( 3 ) != '$' )
792            {
793                throw new IllegalArgumentException( I18n.err( I18n.ERR_13005_INVALID_SALT_REVISION ) );
794            }
795            
796            off = 4;
797        }
798
799        // Extract number of rounds
800        if ( salt.charAt( off + 2 ) > '$' )
801        {
802            throw new IllegalArgumentException( I18n.err( I18n.ERR_13006_MISSING_SALT_ROUNDS ) );
803        }
804        
805        rounds = Integer.parseInt( salt.substring( off, off + 2 ) );
806
807        realSalt = salt.substring( off + 3, off + 25 );
808        
809        passwordb = ( password + ( minor >= 'a' ? "\000" : "" ) ).getBytes( StandardCharsets.UTF_8 );
810
811        saltb = decodeBase64( realSalt, BCRYPT_SALT_LEN );
812
813        bcrypt = new BCrypt();
814        hashed = bcrypt.cryptRaw( passwordb, saltb, rounds, ( int[] ) BF_CRYPT_CIPHERTEXT.clone() );
815
816        rs.append( "$2" );
817        
818        if ( minor >= 'a' )
819        {
820            rs.append( minor );
821        }
822        
823        rs.append( "$" );
824        
825        if ( rounds < 10 )
826        {
827            rs.append( "0" );
828        }
829        
830        if ( rounds > 30 )
831        {
832            throw new IllegalArgumentException( I18n.err( I18n.ERR_13008_ROUNDS_EXCEEDED_MAXIMUM ) );
833        }
834        
835        rs.append( Integer.toString( rounds ) );
836        rs.append( "$" );
837        rs.append( encodeBase64( saltb, saltb.length ) );
838        rs.append( encodeBase64( hashed, BF_CRYPT_CIPHERTEXT.length * 4 - 1 ) );
839        
840        return rs.toString();
841    }
842
843
844    /**
845     * Generate a salt for use with the BCrypt.hashpw() method
846     * 
847     * @param logRounds    the log2 of the number of rounds of
848     * hashing to apply - the work factor therefore increases as
849     * 2**log_rounds.
850     * @param random        an instance of SecureRandom to use
851     * @return  an encoded salt value
852     */
853    public static String genSalt( int logRounds, SecureRandom random )
854    {
855        StringBuilder rs = new StringBuilder();
856        byte[] rnd = new byte[BCRYPT_SALT_LEN];
857
858        random.nextBytes( rnd );
859
860        rs.append( "$2a$" );
861        
862        if ( logRounds < 10 )
863        {
864            rs.append( "0" );
865        }
866        
867        if ( logRounds > 30 )
868        {
869            throw new IllegalArgumentException( I18n.err( I18n.ERR_13009_LOG_ROUNDS_EXCEEDED_MAXIMUM ) );
870        }
871        rs.append( Integer.toString( logRounds ) );
872        rs.append( "$" );
873        rs.append( encodeBase64( rnd, rnd.length ) );
874        
875        return rs.toString();
876    }
877
878
879    /**
880     * Generate a salt for use with the BCrypt.hashpw() method
881     * 
882     * @param logRounds    the log2 of the number of rounds of
883     * hashing to apply - the work factor therefore increases as
884     * 2**log_rounds.
885     * @return an encoded salt value
886     */
887    public static String genSalt( int logRounds )
888    {
889        return genSalt( logRounds, new SecureRandom() );
890    }
891
892
893    /**
894     * Generate a salt for use with the BCrypt.hashpw() method,
895     * selecting a reasonable default for the number of hashing
896     * rounds to apply
897     * @return  an encoded salt value
898     */
899    public static String genSalt()
900    {
901        return genSalt( GENSALT_DEFAULT_LOG2_ROUNDS );
902    }
903
904
905    /**
906     * Check that a plaintext password matches a previously hashed
907     * one
908     * @param plaintext the plaintext password to verify
909     * @param hashed    the previously-hashed password
910     * @return  true if the passwords match, false otherwise
911     */
912    public static boolean checkPw( String plaintext, String hashed )
913    {
914        byte[] hashedBytes;
915        byte[] tryBytes;
916        
917        String tryPw = hashPw( plaintext, hashed );
918        hashedBytes = hashed.getBytes( StandardCharsets.UTF_8 );
919        tryBytes = tryPw.getBytes( StandardCharsets.UTF_8 );
920        
921        if ( hashedBytes.length != tryBytes.length )
922        {
923            return false;
924        }
925        
926        byte ret = 0;
927        
928        for ( int i = 0; i < tryBytes.length; i++ )
929        {
930            ret |= hashedBytes[i] ^ tryBytes[i];
931        }
932        
933        return ret == 0;
934    }
935}