UNPKG

26.1 kBJavaScriptView Raw
1var crypto = require("crypto");
2
3var BCRYPT_SALT_LEN = 16;
4
5var GENSALT_DEFAULT_LOG2_ROUNDS = 10;
6var BLOWFISH_NUM_ROUNDS = 16;
7
8var MAX_EXECUTION_TIME = 100;
9var P_orig = [0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822,
10 0x299f31d0, 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377,
11 0xbe5466cf, 0x34e90c6c, 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5,
12 0xb5470917, 0x9216d5d9, 0x8979fb1b];
13var S_orig = [0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed,
14 0x6a267e96, 0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7,
15 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3,
16 0xf4933d7e, 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
17 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, 0xc5d1b023,
18 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e,
19 0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda,
20 0x55605c60, 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
21 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af,
22 0x7c72e993, 0xb3ee1411, 0x636fbc2a, 0x2ba9c55d, 0x741831f6,
23 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, 0x7a325381,
24 0x28958677, 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
25 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, 0xef845d5d,
26 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5,
27 0x0f6d6ff3, 0x83f44239, 0x2e0b4482, 0xa4842004, 0x69c8f04a,
28 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
29 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, 0x6eef0b6c,
30 0x137a3be4, 0xba3bf050, 0x7efb2a98, 0xa1f1651d, 0x39af0176,
31 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3,
32 0x3b8b5ebe, 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
33 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, 0x37d0d724,
34 0xd00a1248, 0xdb0fead3, 0x49f1c09b, 0x075372c9, 0x80991b7b,
35 0x25d479d8, 0xf6e8def7, 0xe3fe501a, 0xb6794c3b, 0x976ce0bd,
36 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
37 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f,
38 0x9b30952c, 0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd,
39 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39,
40 0xb9d3fbdb, 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
41 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, 0x3c7516df,
42 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760,
43 0x53317b48, 0x3e00df82, 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e,
44 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
45 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98,
46 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, 0x9a53e479, 0xb6f84565,
47 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341,
48 0xcee4c6e8, 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
49 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, 0xd08ed1d0,
50 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64,
51 0x8888b812, 0x900df01c, 0x4fad5ea0, 0x688fc31c, 0xd1cff191,
52 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
53 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, 0xb4a84fe0,
54 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, 0x165fa266, 0x80957705,
55 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5,
56 0xfb9d35cf, 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
57 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, 0x2464369b,
58 0xf009b91e, 0x5563911d, 0x59dfa6aa, 0x78c14389, 0xd95a537f,
59 0x207d5ba2, 0x02e5b9c5, 0x83260376, 0x6295cfa9, 0x11c81968,
60 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
61 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5,
62 0x571be91f, 0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6,
63 0xff34052e, 0xc5855664, 0x53b02d5d, 0xa99f8fa1, 0x08ba4799,
64 0x6e85076a, 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
65 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, 0xecaa8c71,
66 0x699a17ff, 0x5664526c, 0xc2b19ee1, 0x193602a5, 0x75094c29,
67 0xa0591340, 0xe4183a3e, 0x3f54989a, 0x5b429d65, 0x6b8fe4d6,
68 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
69 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f,
70 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, 0x687f3584, 0x52a0e286,
71 0xb79c5305, 0xaa500737, 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec,
72 0x5716f2b8, 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
73 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, 0xd19113f9,
74 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc,
75 0xc8b57634, 0x9af3dda7, 0xa9446146, 0x0fd0030e, 0xecc8c73e,
76 0xa4751e41, 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
77 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, 0x2cb81290,
78 0x24977c79, 0x5679b072, 0xbcaf89af, 0xde9a771f, 0xd9930810,
79 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, 0x501adde6,
80 0x9f84cd87, 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
81 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, 0xef1c1847,
82 0x3215d908, 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451,
83 0x50940002, 0x133ae4dd, 0x71dff89e, 0x10314e55, 0x81ac77d6,
84 0x5f11199b, 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
85 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, 0x86e34570,
86 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, 0x771fe71c, 0x4e3d06fa,
87 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978,
88 0x9c10b36a, 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
89 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, 0x5223a708,
90 0xf71312b6, 0xebadfe6e, 0xeac31f66, 0xe3bc4595, 0xa67bc883,
91 0xb17f37d1, 0x018cff28, 0xc332ddef, 0xbe6c5aa5, 0x65582185,
92 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
93 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830,
94 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, 0xb5735c90, 0x4c70a239,
95 0xd59e9e0b, 0xcbaade14, 0xeecc86bc, 0x60622ca7, 0x9cab5cab,
96 0xb2f3846e, 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
97 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, 0x9b540b19,
98 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77,
99 0x11ed935f, 0x16681281, 0x0e358829, 0xc7e61fd6, 0x96dedfa1,
100 0x7858ba99, 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
101 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef,
102 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, 0x5d4a14d9, 0xe864b7e3,
103 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15,
104 0xfacb4fd0, 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
105 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, 0xcf62a1f2,
106 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492,
107 0x47848a0b, 0x5692b285, 0x095bbf00, 0xad19489d, 0x1462b174,
108 0x23820e00, 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
109 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, 0x7cde3759,
110 0xcbee7460, 0x4085f2a7, 0xce77326e, 0xa6078084, 0x19f8509e,
111 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc,
112 0x800bcadc, 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
113 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, 0xc5c43465,
114 0x713e38d8, 0x3d28f89e, 0xf16dff20, 0x153e21e7, 0x8fb03d4a,
115 0xe6e39f2b, 0xdb83adf7, 0xe93d5a68, 0x948140f7, 0xf64c261c,
116 0x94692934, 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
117 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, 0x1e39f62e,
118 0x97244546, 0x14214f74, 0xbf8b8840, 0x4d95fc1d, 0x96b591af,
119 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0,
120 0x31cb8504, 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
121 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, 0x68dc1462,
122 0xd7486900, 0x680ec0a4, 0x27a18dee, 0x4f3ffea2, 0xe887ad8c,
123 0xb58ce006, 0x7af4d6b6, 0xaace1e7c, 0xd3375fec, 0xce78a399,
124 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
125 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74,
126 0xdd5b4332, 0x6841e7f7, 0xca7820fb, 0xfb0af54e, 0xd8feb397,
127 0x454056ac, 0xba489527, 0x55533a3a, 0x20838d87, 0xfe6ba9b7,
128 0xd096954b, 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
129 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, 0xfdf8e802,
130 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22,
131 0x48c1133f, 0xc70f86dc, 0x07f9c9ee, 0x41041f0f, 0x404779a4,
132 0x5d886e17, 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
133 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2,
134 0x02e1329e, 0xaf664fd1, 0xcad18115, 0x6b2395e0, 0x333e92e1,
135 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, 0xde720c8c,
136 0x2da2f728, 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
137 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, 0x0a476341,
138 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8,
139 0x991be14c, 0xdb6e6b0d, 0xc67b5510, 0x6d672c37, 0x2765d43b,
140 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
141 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, 0xbb132f88,
142 0x515bad24, 0x7b9479bf, 0x763bd6eb, 0x37392eb3, 0xcc115979,
143 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc,
144 0x782ef11c, 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
145 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, 0x44421659,
146 0x0a121386, 0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f,
147 0xbebfe988, 0x64e4c3fe, 0x9dbc8057, 0xf0f7c086, 0x60787bf8,
148 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
149 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be,
150 0xbde8ae24, 0x55464299, 0xbf582e61, 0x4e58f48f, 0xf2ddfda2,
151 0xf474ef38, 0x8789bdc2, 0x5366f9c3, 0xc8b38e74, 0xb475f255,
152 0x46fcd9b9, 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
153 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, 0xb90bace1,
154 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09,
155 0x662d09a1, 0xc4324633, 0xe85a1f02, 0x09f0be8c, 0x4a99a025,
156 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
157 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01,
158 0xa70683fa, 0xa002b5c4, 0x0de6d027, 0x9af88c27, 0x773f8641,
159 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, 0x006058aa,
160 0x30dc7d62, 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
161 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, 0x6f05e409,
162 0x4b7c0188, 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9,
163 0x1ac15bb4, 0xd39eb8fc, 0xed545578, 0x08fca5b5, 0xd83d7cd3,
164 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
165 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, 0xd79a3234,
166 0x92638212, 0x670efa8e, 0x406000e0, 0x3a39ce37, 0xd3faf5cf,
167 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, 0xd3822740,
168 0x99bc9bbe, 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
169 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, 0x5748ab2f,
170 0xbc946e79, 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d,
171 0xd5730a1d, 0x4cd04dc6, 0x2939bbdb, 0xa9ba4650, 0xac9526e8,
172 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
173 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, 0x83c061ba,
174 0x9be96a4d, 0x8fe51550, 0xba645bd6, 0x2826a2f9, 0xa73a3ae1,
175 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69,
176 0x77fa0a59, 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
177 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, 0x96d5ac3a,
178 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, 0x1f9f25cf, 0xadf2b89b,
179 0x5ad6b472, 0x5a88f54c, 0xe029ac71, 0xe019a5e6, 0x47b0acfd,
180 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
181 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4,
182 0x88f46dba, 0x03a16125, 0x0564f0bd, 0xc3eb9e15, 0x3c9057a2,
183 0x97271aec, 0xa93a072a, 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb,
184 0x26dcf319, 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
185 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, 0x4de81751,
186 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce,
187 0x5121ce64, 0x774fbe32, 0xa8b6e37e, 0xc3293d46, 0x48de5369,
188 0x6413e680, 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
189 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd,
190 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, 0xdda26a7e, 0x3a59ff45,
191 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, 0x8d6612ae,
192 0xbf3c6f47, 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
193 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, 0x4040cb08,
194 0x4eb4e2cc, 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d,
195 0x06b89fb4, 0xce6ea048, 0x6f3f3b82, 0x3520ab82, 0x011a1d4b,
196 0x277227f8, 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
197 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, 0xe01cc87e,
198 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, 0x1a908749, 0xd44fbd9a,
199 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c,
200 0xe0b12b4f, 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
201 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, 0xfae59361,
202 0xceb69ceb, 0xc2a86459, 0x12baa8d1, 0xb6c1075e, 0xe3056a0c,
203 0x10d25065, 0xcb03a442, 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be,
204 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
205 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d,
206 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, 0xe54cda54, 0x1edad891,
207 0xce6279cf, 0xcd3e7e6f, 0x1618b166, 0xfd2c1d05, 0x848fd2c5,
208 0xf6fb2299, 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
209 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, 0xde966292,
210 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a,
211 0x45e1d006, 0xc3f27b9a, 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2,
212 0x35bdd2f6, 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
213 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, 0xba38209c,
214 0xf746ce76, 0x77afa1c5, 0x20756060, 0x85cbfe4e, 0x8ae88dd8,
215 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, 0x01c36ae4,
216 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
217 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6];
218var bf_crypt_ciphertext = [0x4f727068, 0x65616e42, 0x65686f6c, 0x64657253,
219 0x63727944, 0x6f756274];
220var base64_code = ['.', '/', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
221 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
222 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
223 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
224 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8',
225 '9'];
226var index_64 = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
227 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
228 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1,
229 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, -1, -1, -1, -1, -1, -1, -1,
230 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
231 21, 22, 23, 24, 25, 26, 27, -1, -1, -1, -1, -1, -1, 28, 29, 30, 31,
232 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
233 49, 50, 51, 52, 53, -1, -1, -1, -1, -1];
234
235function getByte(c) {
236 var ret = 0;
237 try {
238 var b = c.charCodeAt(0);
239 } catch (err) {
240 b = c;
241 }
242 if (b > 127) {
243 return -128 + (b % 128);
244 } else {
245 return b;
246 }
247};
248
249function encode_base64(d, len) {
250 var off = 0;
251 var rs = [];
252 var c1;
253 var c2;
254 if (len <= 0 || len > d.length)
255 throw "Invalid len";
256 while (off < len) {
257 c1 = d[off++] & 0xff;
258 rs.push(base64_code[(c1 >> 2) & 0x3f]);
259 c1 = (c1 & 0x03) << 4;
260 if (off >= len) {
261 rs.push(base64_code[c1 & 0x3f]);
262 break;
263 }
264 c2 = d[off++] & 0xff;
265 c1 |= (c2 >> 4) & 0x0f;
266 rs.push(base64_code[c1 & 0x3f]);
267 c1 = (c2 & 0x0f) << 2;
268 if (off >= len) {
269 rs.push(base64_code[c1 & 0x3f]);
270 break;
271 }
272 c2 = d[off++] & 0xff;
273 c1 |= (c2 >> 6) & 0x03;
274 rs.push(base64_code[c1 & 0x3f]);
275 rs.push(base64_code[c2 & 0x3f]);
276 }
277 return rs.join('');
278};
279
280function char64(x) {
281 var code = x.charCodeAt(0);
282 if (code < 0 || code > index_64.length) {
283 return -1;
284 }
285 return index_64[code];
286};
287
288function decode_base64(s, maxolen) {
289 var off = 0;
290 var slen = s.length;
291 var olen = 0;
292 var rs = [];
293 var c1, c2, c3, c4, o;
294 if (maxolen <= 0) throw "Invalid maxolen";
295 while (off < slen - 1 && olen < maxolen) {
296 c1 = char64(s.charAt(off++));
297 c2 = char64(s.charAt(off++));
298 if (c1 == -1 || c2 == -1) {
299 break;
300 }
301 o = getByte(c1 << 2);
302 o |= (c2 & 0x30) >> 4;
303 rs.push(String.fromCharCode(o));
304 if (++olen >= maxolen || off >= slen) {
305 break;
306 }
307 c3 = char64(s.charAt(off++));
308 if (c3 == -1) {
309 break;
310 }
311 o = getByte((c2 & 0x0f) << 4);
312 o |= (c3 & 0x3c) >> 2;
313 rs.push(String.fromCharCode(o));
314 if (++olen >= maxolen || off >= slen) {
315 break;
316 }
317 c4 = char64(s.charAt(off++));
318 o = getByte((c3 & 0x03) << 6);
319 o |= c4;
320 rs.push(String.fromCharCode(o));
321 ++olen;
322 }
323 var ret = [];
324 for (off = 0; off < olen; off++) {
325 ret.push(getByte(rs[off]));
326 }
327 return ret;
328};
329
330function encipher(lr, off, P, S) {
331 var i;
332 var n;
333 var l = lr[off];
334 var r = lr[off + 1];
335
336 l ^= P[0];
337 for (i = 0; i <= BLOWFISH_NUM_ROUNDS - 2;) {
338 // Feistel substitution on left word
339 n = S[(l >> 24) & 0xff];
340 n += S[0x100 | ((l >> 16) & 0xff)];
341 n ^= S[0x200 | ((l >> 8) & 0xff)];
342 n += S[0x300 | (l & 0xff)];
343 r ^= n ^ P[++i];
344
345 // Feistel substitution on right word
346 n = S[(r >> 24) & 0xff];
347 n += S[0x100 | ((r >> 16) & 0xff)];
348 n ^= S[0x200 | ((r >> 8) & 0xff)];
349 n += S[0x300 | (r & 0xff)];
350 l ^= n ^ P[++i];
351 }
352 lr[off] = r ^ P[BLOWFISH_NUM_ROUNDS + 1];
353 lr[off + 1] = l;
354 return lr;
355};
356
357function streamtoword(data, offp) {
358 var i;
359 var word = 0;
360 for (i = 0; i < 4; i++) {
361 word = (word << 8) | (data[offp] & 0xff);
362 offp = (offp + 1) % data.length;
363 }
364 return {key:word, offp:offp};
365};
366
367function key(key, P, S) {
368 var i;
369 var offp = 0;
370 var lr = new Array(0x00000000, 0x00000000);
371 var plen = P.length;
372 var slen = S.length;
373
374 for (i = 0; i < plen; i++) {
375 var sw = streamtoword(key, offp);
376 offp = sw.offp;
377 P[i] = P[i] ^ sw.key;
378 }
379 for (i = 0; i < plen; i += 2) {
380 lr = encipher(lr, 0, P, S);
381 P[i] = lr[0];
382 P[i + 1] = lr[1];
383 }
384
385 for (i = 0; i < slen; i += 2) {
386 lr = encipher(lr, 0, P, S);
387 S[i] = lr[0];
388 S[i + 1] = lr[1];
389 }
390};
391
392function ekskey(data, key, P, S) {
393 var i;
394 var offp = 0;
395 var lr = new Array(0x00000000, 0x00000000);
396 var plen = P.length;
397 var slen = S.length;
398 var sw;
399
400 for (i = 0; i < plen; i++) {
401 sw = streamtoword(key, offp);
402 offp = sw.offp;
403 P[i] = P[i] ^ sw.key;
404 }
405 offp = 0;
406 for (i = 0; i < plen; i += 2) {
407 sw = streamtoword(data, offp);
408 offp = sw.offp;
409 lr[0] ^= sw.key;
410
411 sw = streamtoword(data, offp);
412 offp = sw.offp;
413 lr[1] ^= sw.key;
414
415 lr = encipher(lr, 0, P, S);
416 P[i] = lr[0];
417 P[i + 1] = lr[1];
418 }
419 for (i = 0; i < slen; i += 2) {
420 sw = streamtoword(data, offp);
421 offp = sw.offp;
422 lr[0] ^= sw.key;
423
424 sw = streamtoword(data, offp);
425 offp = sw.offp;
426 lr[1] ^= sw.key;
427
428 lr = encipher(lr, 0, P, S);
429 S[i] = lr[0];
430 S[i + 1] = lr[1];
431 }
432};
433
434function crypt_raw(password, salt, log_rounds, progress) {
435 var rounds;
436 var j;
437 var cdata = bf_crypt_ciphertext.slice();
438 var clen = cdata.length;
439 var one_percent;
440
441 if (log_rounds < 4 || log_rounds > 31)
442 throw "Bad number of rounds";
443 if (salt.length != BCRYPT_SALT_LEN)
444 throw "Bad salt length";
445
446 rounds = 1 << log_rounds;
447 one_percent = Math.floor(rounds / 100) + 1;
448
449 var P = P_orig.slice();
450 var S = S_orig.slice();
451
452 ekskey(salt, password, P, S);
453
454 var i = 0;
455
456 while(true) {
457 if(i < rounds){
458 var start = new Date();
459 for (; i < rounds;) {
460 i = i + 1;
461 key(password, P, S);
462 key(salt, P, S);
463 if(i % one_percent == 0){
464 progress();
465 }
466 if((new Date() - start) > MAX_EXECUTION_TIME){
467 break;
468 }
469 }
470 } else {
471 for (i = 0; i < 64; i++) {
472 for (j = 0; j < (clen >> 1); j++) {
473 lr = encipher(cdata, j << 1, P, S);
474 }
475 }
476 var ret = [];
477 for (i = 0; i < clen; i++) {
478 ret.push(getByte((cdata[i] >> 24) & 0xff));
479 ret.push(getByte((cdata[i] >> 16) & 0xff));
480 ret.push(getByte((cdata[i] >> 8) & 0xff));
481 ret.push(getByte(cdata[i] & 0xff));
482 }
483 return(ret);
484 }
485 }
486};
487
488function hashpw(password, salt, progress) {
489 var real_salt;
490 var passwordb = [];
491 var saltb = [];
492 var hashed = [];
493 var minor = String.fromCharCode(0);
494 var rounds = 0;
495 var off = 0;
496
497 if (!progress){
498 var progress = function() {};
499 }
500
501 if (salt.charAt(0) != '$' || salt.charAt(1) != '2')
502 throw "Invalid salt version";
503 if (salt.charAt(2) == '$')
504 off = 3;
505 else {
506 minor = salt.charAt(2);
507 if (minor != 'a' || salt.charAt(3) != '$')
508 throw "Invalid salt revision";
509 off = 4;
510 }
511
512 // Extract number of rounds
513 if (salt.charAt(off + 2) > '$')
514 throw "Missing salt rounds";
515 var r1 = parseInt(salt.substring(off, off + 1)) * 10;
516 var r2 = parseInt(salt.substring(off + 1, off + 2));
517 rounds = r1 + r2;
518 real_salt = salt.substring(off + 3, off + 25);
519 password = password + (minor >= 'a' ? "\000" : "");
520
521 var buf = new Buffer(password);
522 for (var r = 0; r < buf.length; r++) {
523 passwordb.push(buf[r]);
524 }
525 saltb = decode_base64(real_salt, BCRYPT_SALT_LEN);
526 var hashed = crypt_raw(passwordb, saltb, rounds, progress);
527
528 var rs = [];
529 rs.push("$2");
530 if (minor >= 'a')
531 rs.push(minor);
532 rs.push("$");
533 if (rounds < 10)
534 rs.push("0");
535 rs.push(rounds.toString());
536 rs.push("$");
537 rs.push(encode_base64(saltb, saltb.length));
538 rs.push(encode_base64(hashed, bf_crypt_ciphertext.length * 4 - 1));
539
540 return(rs.join(''));
541};
542
543function gensalt(rounds) {
544 var iteration_count = rounds;
545 if (iteration_count < 4 || iteration_count > 31) {
546 iteration_count = GENSALT_DEFAULT_LOG2_ROUNDS;
547 }
548 var output = [];
549 output.push("$2a$");
550 if (iteration_count < 10)
551 output.push("0");
552 output.push(iteration_count.toString());
553 output.push('$');
554
555 var rand_buf;
556 try {
557 rand_buf = crypto.randomBytes(BCRYPT_SALT_LEN);
558 } catch (ex) {
559 throw ex;
560 }
561
562 output.push(encode_base64(rand_buf, BCRYPT_SALT_LEN));
563 return output.join('');
564};
565
566function genSaltSync(rounds) {
567 /*
568 rounds - [OPTIONAL] - the number of rounds to process the data for. (default - 10)
569 seed_length - [OPTIONAL] - RAND_bytes wants a length. to make that a bit flexible, you can specify a seed_length. (default - 20)
570 */
571 if(!rounds) {
572 rounds = GENSALT_DEFAULT_LOG2_ROUNDS;
573 }
574 return gensalt(rounds);
575}
576
577function genSalt(rounds, callback) {
578 /*
579 rounds - [OPTIONAL] - the number of rounds to process the data for. (default - 10)
580 seed_length - [OPTIONAL] - RAND_bytes wants a length. to make that a bit flexible, you can specify a seed_length. (default - 20)
581 callback - [REQUIRED] - a callback to be fired once the salt has been generated. uses eio making it asynchronous.
582 error - First parameter to the callback detailing any errors.
583 salt - Second parameter to the callback providing the generated salt.
584 */
585 if(!callback) {
586 throw "No callback function was given."
587 }
588 process.nextTick(function() {
589 var result = null;
590 var error = null;
591 try {
592 result = genSaltSync(rounds)
593 } catch(err) {
594 error = err;
595 }
596 callback(error, result);
597 });
598}
599
600function hashSync(data, salt, progress) {
601 /*
602 data - [REQUIRED] - the data to be encrypted.
603 salt - [REQUIRED] - the salt to be used in encryption.
604 */
605 if(!salt) {
606 salt = genSaltSync();
607 }
608 return hashpw(data, salt, progress);
609}
610
611function hash(data, salt, progress, callback) {
612 /*
613 data - [REQUIRED] - the data to be encrypted.
614 salt - [REQUIRED] - the salt to be used to hash the password. if specified as a number then a salt will be generated and used (see examples).
615 progress - a callback to be called during the hash calculation to signify progress
616 callback - [REQUIRED] - a callback to be fired once the data has been encrypted. uses eio making it asynchronous.
617 error - First parameter to the callback detailing any errors.
618 encrypted - Second parameter to the callback providing the encrypted form.
619 */
620 if(!callback) {
621 throw "No callback function was given."
622 }
623 process.nextTick(function() {
624 var result = null;
625 var error = null;
626 try {
627 result = hashSync(data, salt, progress)
628 } catch(err) {
629 error = err;
630 }
631 callback(error, result);
632 });
633}
634
635function compareSync(data, encrypted) {
636 /*
637 data - [REQUIRED] - data to compare.
638 encrypted - [REQUIRED] - data to be compared to.
639 */
640
641 if(typeof data != "string" || typeof encrypted != "string") {
642 throw "Incorrect arguments";
643 }
644
645 var encrypted_length = encrypted.length;
646
647 if(encrypted_length != 60) {
648 throw "Not a valid BCrypt hash.";
649 }
650
651 var same = true;
652 var hash_data = hashSync(data, encrypted.substr(0, encrypted_length-31));
653 var hash_data_length = hash_data.length;
654
655 same = hash_data_length == encrypted_length;
656
657 var max_length = (hash_data_length < encrypted_length) ? hash_data_length : encrypted_length;
658
659 // to prevent timing attacks, should check entire string
660 // don't exit after found to be false
661 for (var i = 0; i < max_length; ++i) {
662 if (hash_data_length >= i && encrypted_length >= i && hash_data[i] != encrypted[i]) {
663 same = false;
664 }
665 }
666
667 return same;
668}
669
670function compare(data, encrypted, callback) {
671 /*
672 data - [REQUIRED] - data to compare.
673 encrypted - [REQUIRED] - data to be compared to.
674 callback - [REQUIRED] - a callback to be fired once the data has been compared. uses eio making it asynchronous.
675 error - First parameter to the callback detailing any errors.
676 same - Second parameter to the callback providing whether the data and encrypted forms match [true | false].
677 */
678 if(!callback) {
679 throw "No callback function was given."
680 }
681 process.nextTick(function() {
682 var result = null;
683 var error = null;
684 try {
685 result = compareSync(data, encrypted)
686 } catch(err) {
687 error = err;
688 }
689 callback(error, result);
690 });
691}
692
693function getRounds(encrypted) {
694 //encrypted - [REQUIRED] - hash from which the number of rounds used should be extracted.
695 if(typeof encrypted != "string") {
696 throw "Incorrect arguments";
697 }
698 return Number(encrypted.split("$")[2]);
699}
700
701exports.genSaltSync = genSaltSync;
702exports.genSalt = genSalt;
703exports.hashSync = hashSync;
704exports.hash = hash;
705exports.compareSync = compareSync;
706exports.compare = compare;
707exports.getRounds = getRounds;