bcrypt_pbkdf function

int bcrypt_pbkdf(
  1. Uint8List pass,
  2. int passlen,
  3. Uint8List salt,
  4. int saltlen,
  5. Uint8List key,
  6. int keylen,
  7. int rounds,
)

Implementation

int bcrypt_pbkdf(
  Uint8List pass,
  int passlen,
  Uint8List salt,
  int saltlen,
  Uint8List key,
  int keylen,
  int rounds,
) {
  final sha2pass = Uint8List(64);
  final sha2salt = Uint8List(64);
  final out = Uint8List(BCRYPT_HASHSIZE);
  final tmpout = Uint8List(BCRYPT_HASHSIZE);
  final countsalt = Uint8List(saltlen + 4);
  final origkeylen = keylen;

  if (rounds < 1) {
    return -1;
  }

  if (passlen == 0 ||
      saltlen == 0 ||
      keylen == 0 ||
      keylen > (out.lengthInBytes * out.lengthInBytes) ||
      saltlen > (1 << 20)) {
    return -1;
  }

  var stride = ((keylen + out.lengthInBytes - 1) / out.lengthInBytes).floor();
  var amt = ((keylen + stride - 1) / stride).floor();

  // console.log('stride', stride);
  // console.log('amt', amt);

  for (var i = 0; i < saltlen; i++) {
    countsalt[i] = salt[i];
  }

  crypto_hash_sha512(sha2pass, pass, passlen);

  for (var count = 1; keylen > 0; count++) {
    countsalt[saltlen + 0] = count >>> 24;
    countsalt[saltlen + 1] = count >>> 16;
    countsalt[saltlen + 2] = count >>> 8;
    countsalt[saltlen + 3] = count;

    crypto_hash_sha512(sha2salt, countsalt, saltlen + 4);

    bcrypt_hash(sha2pass, sha2salt, tmpout);

    for (var i = 0; i < tmpout.lengthInBytes; i++) {
      out[i] = tmpout[i];
    }

    for (var i = 1; i < rounds; i++) {
      crypto_hash_sha512(sha2salt, tmpout, tmpout.lengthInBytes);
      bcrypt_hash(sha2pass, sha2salt, tmpout);

      for (var j = 0; j < out.lengthInBytes; j++) {
        out[j] ^= tmpout[j];
      }
    }

    amt = math.min(amt, keylen);

    var i = 0;
    for (i = 0; i < amt; i++) {
      final dest = i * stride + (count - 1);
      if (dest >= origkeylen) break;
      key[dest] = out[i];
    }
    keylen -= i;
  }

  return 0;
}