convert method
Generate a derived key using the Bcrypt algorithm.
Implementation
@override
BcryptHashDigest convert(List<int> password) {
int i, j, l, h, t;
int s0, s1, s2, s3;
int nb = 1 << _ctx.cost;
var pass32 = _ctx.makePassword(password);
var salt32 = _makeSaltKey(_ctx.salt);
// Initialize state: P (Subkeys) + S (Substitution boxes)
var state = Uint32List.fromList(_sv);
var p = Uint32List.view(state.buffer, 0, 18);
var s = Uint32List.view(state.buffer, 18 << 2, 1024);
// Blowfish encrypt routine
l = 0;
h = 0;
void encrypt() {
l ^= p[0];
h ^= _fsub(s, l) ^ p[1];
l ^= _fsub(s, h) ^ p[2];
h ^= _fsub(s, l) ^ p[3];
l ^= _fsub(s, h) ^ p[4];
h ^= _fsub(s, l) ^ p[5];
l ^= _fsub(s, h) ^ p[6];
h ^= _fsub(s, l) ^ p[7];
l ^= _fsub(s, h) ^ p[8];
h ^= _fsub(s, l) ^ p[9];
l ^= _fsub(s, h) ^ p[10];
h ^= _fsub(s, l) ^ p[11];
l ^= _fsub(s, h) ^ p[12];
h ^= _fsub(s, l) ^ p[13];
l ^= _fsub(s, h) ^ p[14];
h ^= _fsub(s, l) ^ p[15];
l ^= _fsub(s, h) ^ p[16];
h ^= p[17];
// swap
t = l;
l = h;
h = t;
}
// Key Expansion
l = 0;
h = 0;
s0 = salt32[0];
s1 = salt32[1];
s2 = salt32[2];
s3 = salt32[3];
for (i = 0; i < 18; ++i) {
p[i] ^= pass32[i];
}
for (i = 0; i < state.length; i += 2) {
// block ^= salt
l ^= s0;
h ^= s1;
// blowfish encrypt
encrypt();
// set state
state[i] = l;
state[i + 1] = h;
// s0 <-> s2
t = s0;
s0 = s2;
s2 = t;
// s1 <-> s3
t = s1;
s1 = s3;
s3 = t;
}
// Bcrypt Rounds
for (j = 0; j < nb; ++j) {
// mix with password
l = 0;
h = 0;
for (i = 0; i < 18; ++i) {
p[i] ^= pass32[i];
}
for (i = 0; i < state.length;) {
encrypt();
state[i++] = l;
state[i++] = h;
}
// mix with salt
l = 0;
h = 0;
for (i = 0; i < 18; ++i) {
p[i] ^= salt32[i];
}
for (i = 0; i < state.length;) {
encrypt();
state[i++] = l;
state[i++] = h;
}
}
// Encrypt IV
var result = Uint32List.fromList(_iv);
for (i = 0; i < 64; i++) {
l = result[0];
h = result[1];
encrypt();
result[0] = l;
result[1] = h;
l = result[2];
h = result[3];
encrypt();
result[2] = l;
result[3] = h;
l = result[4];
h = result[5];
encrypt();
result[4] = l;
result[5] = h;
}
// Transform to bytes
for (i = 0; i < result.length; ++i) {
result[i] = _swap32(result[i]);
}
var output = Uint8List.view(result.buffer, 0, derivedKeyLength);
return BcryptHashDigest(_ctx, output);
}