internal void InitializeState() { Array.Copy(blowfish_pbox, 0, P, 0, 18); Array.Copy(blowfish_sbox, 0, S0, 0, 256); Array.Copy(blowfish_sbox, 256, S1, 0, 256); Array.Copy(blowfish_sbox, 512, S2, 0, 256); Array.Copy(blowfish_sbox, 768, S3, 0, 256); }
/// <summary> /// bcrypt_hash /// </summary> /// <param name="blowfish">blowfish object to use</param> /// <param name="sha2pass">SHA512 of password</param> /// <param name="sha2salt">SHA512 of salt</param> /// <returns></returns> private byte[] BcryptHash(Blowfish blowfish, byte[] sha2pass, byte[] sha2salt) { // this code is based on OpenBSD's bcrypt_pbkdf.c const int BLOCKSIZE = 8; // key expansion blowfish.InitializeState(); blowfish.ExpandState(sha2pass, sha2salt); for (int i = 0; i < 64; ++i) { blowfish.ExpandState(sha2salt); blowfish.ExpandState(sha2pass); } // encryption byte[] cdata = (byte[])_bcryptCipherText.Clone(); for (int i = 0; i < 64; ++i) { for (int j = 0; j < 32; j += BLOCKSIZE) { blowfish.BlockEncrypt(cdata, j, cdata, j); } } // copy out for (int i = 0; i < 32; i += 4) { byte b0 = cdata[i + 0]; byte b1 = cdata[i + 1]; byte b2 = cdata[i + 2]; byte b3 = cdata[i + 3]; cdata[i + 3] = b0; cdata[i + 2] = b1; cdata[i + 1] = b2; cdata[i + 0] = b3; } return cdata; }