deriveKeySync method

Future<SecretKey> deriveKeySync({
  1. required SecretKey secretKey,
  2. required List<int> nonce,
  3. List<int> k = const <int>[],
  4. List<int> ad = const <int>[],
})

Implementation

Future<SecretKey> deriveKeySync({
  required SecretKey secretKey,
  required List<int> nonce,
  List<int> k = const <int>[],
  List<int> ad = const <int>[],
}) async {
  // h0
  final secretKeyBytes = await secretKey.extractBytes();
  final h0Sink = Blake2b().newHashSink();
  _addUint32(h0Sink, parallelism);
  _addUint32(h0Sink, hashLength);
  _addUint32(h0Sink, memorySize);
  _addUint32(h0Sink, iterations);
  _addUint32(h0Sink, version);
  _addSequence(h0Sink, secretKeyBytes);
  _addSequence(h0Sink, nonce);
  _addSequence(h0Sink, k);
  _addSequence(h0Sink, ad);
  h0Sink.close();
  final h0 = (await h0Sink.hash()).bytes;

  final blocks = List<Uint8List>.generate(
    parallelism,
    (_) => Uint8List(h0.length),
  );
  blocks[0].setAll(0, h0);
  final columnCount = memorySize ~/ parallelism;

  // Initialize parallel lanes
  for (var i = 0; i < parallelism; i++) {
    // ...
  }

  // First iteration
  for (var i = 0; i < parallelism; i++) {
    for (var j = 2; j < columnCount; j++) {
      // ...
    }
  }

  // Second and further iterations
  for (var iteration = 1; iteration < iterations; iteration++) {
    for (var i = 0; i < parallelism; i++) {
      for (var j = 0; j < columnCount; j++) {
        // ...
      }
    }
  }

  // XOR lanes
  final c = blocks[0];
  for (var i = 1; i < blocks.length; i++) {
    final block = blocks[i];
    for (var j = 0; j < block.length; j++) {
      c[j] ^= block[j];
    }
  }

  // Final hash
  SecretKey(Uint8List.fromList(await _hash(c, hashLength)));

  throw UnimplementedError('Does not pass tests yet.');
}