deriveKeySync method

SecretKeyData deriveKeySync({
  1. required SecretKeyData secretKeyData,
  2. required List<int> nonce,
})

Implementation

SecretKeyData deriveKeySync({
  required SecretKeyData secretKeyData,
  required List<int> nonce,
}) {
  final secretKeyBytes = secretKeyData.bytes;
  if (secretKeyBytes.length != 32) {
    throw ArgumentError.value(
      secretKeyData,
      'secretKey',
      'Must be 32 bytes',
    );
  }
  if (nonce.length != 16) {
    throw ArgumentError.value(
      nonce,
      'nonce',
      'Must be 16 bytes',
    );
  }
  final nonceBytes = Uint8List.fromList(nonce);
  final nonceByteData = ByteData.view(nonceBytes.buffer);

  // Initialize state
  final state = Uint32List(16);
  DartChacha20.initializeChacha(
    state,
    key: secretKeyBytes,
    nonce: Uint8List.view(nonceBytes.buffer, 4, 12),
    keyStreamIndex: 64 * nonceByteData.getUint32(0, Endian.little),
  );

  // Chacha20 without the final addition
  DartChacha20.chachaRounds(state, 0, state, rounds: 20, addAndXor: false);

  // Last 128 bits of the 256-bit key are last 128 bits of the 512-bit state
  state[4] = state[12];
  state[5] = state[13];
  state[6] = state[14];
  state[7] = state[15];

  // Ensure that the integers are little endian
  flipUint32ListEndianUnless(state, Endian.little);

  // Our 256-bit key is ready
  // Copy the first 32 bytes to a new list.
  final copyOfFirst32Bytes = Uint8List.fromList(Uint8List.view(
    state.buffer,
    state.offsetInBytes,
    32,
  ));
  state.fillRange(0, state.length, 0);
  return SecretKeyData(
    copyOfFirst32Bytes,
    overwriteWhenDestroyed: true,
  );
}