computeExchangeHash function

Uint8List computeExchangeHash(
  1. bool server,
  2. int kexMethod,
  3. Digest algo,
  4. String verC,
  5. String verS,
  6. Uint8List kexInitC,
  7. Uint8List kexInitS,
  8. Uint8List kS,
  9. BigInt K,
  10. DiffieHellman dh,
  11. EllipticCurveDiffieHellman ecdh,
  12. X25519DiffieHellman x25519dh
)

The exchange hash is used to authenticate the key exchange and SHOULD be kept secret.

Implementation

Uint8List computeExchangeHash(
    bool server,
    int kexMethod,
    Digest algo,
    String verC,
    String verS,
    Uint8List kexInitC,
    Uint8List kexInitS,
    Uint8List kS,
    BigInt K,
    DiffieHellman dh,
    EllipticCurveDiffieHellman ecdh,
    X25519DiffieHellman x25519dh) {
  BinaryPacket kexCPacket = BinaryPacket(kexInitC),
      kexSPacket = BinaryPacket(kexInitS);
  int kexCPacketLen = 4 + kexCPacket.length,
      kexSPacketLen = 4 + kexSPacket.length;

  Digester H = Digester(algo);
  if (server) H.updateString(verS);
  H.updateString(verC);
  if (!server) H.updateString(verS);
  H.updateOffset(kexInitC, 5, kexCPacketLen - 5 - kexCPacket.padding);
  H.updateOffset(kexInitS, 5, kexSPacketLen - 5 - kexSPacket.padding);
  H.update(kS);

  if (KEX.diffieHellmanGroupExchange(kexMethod)) {
    H.updateInt(dh.gexMin);
    H.updateInt(dh.gexPref);
    H.updateInt(dh.gexMax);
    H.updateBigInt(dh.p);
    H.updateBigInt(dh.g);
  }
  if (KEX.x25519DiffieHellman(kexMethod)) {
    if (server) H.update(x25519dh.remotePubKey);
    H.update(x25519dh.myPubKey);
    if (!server) H.update(x25519dh.remotePubKey);
  } else if (KEX.ellipticCurveDiffieHellman(kexMethod)) {
    if (server) H.update(ecdh.sText);
    H.update(ecdh.cText);
    if (!server) H.update(ecdh.sText);
  } else {
    if (server) H.updateBigInt(dh.f);
    H.updateBigInt(dh.e);
    if (!server) H.updateBigInt(dh.f);
  }
  H.updateBigInt(K);
  return H.finish();
}