public void sendFirst() {
    System.out.println("-- Alice --");
    if (MitM) {
      System.out.println("ACHTUNG: MitM aktiv!!!");
    }

    // fingerprint werte aus datei auslesen
    fingerprint = new Fingerprint(new File("HashParameter"));

    // alice wählt p und g und sendet diese an bob
    getPrimeAndGenerator();
    System.out.println("p: " + p);
    System.out.println("g: " + g);
    Com.sendTo(1, p.toString(16)); // S1
    Com.sendTo(1, g.toString(16)); // S2

    // alice sendet öffentlichen schlüssel an bob
    RSA rsa_A = new RSA();
    System.out.println("RSA Alice e: " + rsa_A.e);
    System.out.println("RSA Alice n: " + rsa_A.n);
    System.out.println("RSA Alice d: " + rsa_A.d);
    Com.sendTo(1, rsa_A.e.toString(16)); // S3
    Com.sendTo(1, rsa_A.n.toString(16)); // S4

    // alice empfängt öffentlichen schlüssel von bob
    BigInteger e_B = new BigInteger(Com.receive(), 16); // R5
    BigInteger n_B = new BigInteger(Com.receive(), 16); // R6
    System.out.println("Bob e: " + e_B);
    System.out.println("Bob n: " + n_B);

    // zufällige zahl x_A in {1,...,p-2} -> randomBetween 1 <= x_A < p-1
    BigInteger x_A = BigIntegerUtil.randomBetween(ONE, p.subtract(ONE));
    // alice wählt x_A = g^(x_A) mod p
    BigInteger y_A = g.modPow(x_A, p);
    // y_A an bob senden

    BigInteger y_W = null;
    BigInteger x_W = null;
    if (MitM) {
      x_W = BigIntegerUtil.randomBetween(ONE, p.subtract(ONE)); // x_W in {1,...,p-2}
      y_W = g.modPow(x_W, p);
      Com.sendTo(1, y_W.toString(16)); // S7
    } else {
      Com.sendTo(1, y_A.toString(16)); // S7
    }

    System.out.println("Alice: Receive cert");

    // alice empfängt certificate in einzelteilen
    Certificate Z_B = buildCertificateBasedOnStrings(Com.receive(), Com.receive(), Com.receive()); // R8,9,10
    System.out.println("Z_B");
    printCertificate(Z_B);

    // alice empfängt y_B, S_B_encrypted
    BigInteger y_B = new BigInteger(Com.receive(), 16); // R11
    BigInteger S_B_encrypted = new BigInteger(Com.receive(), 16); // R12

    // alice berechnet k
    BigInteger k = y_B.modPow(x_A, p);

    if (MitM) {
      k = y_B.modPow(x_W, p);
    }

    // check certificate
    if (checkCertificate(Z_B) == true) {
      System.out.println("Zertifikat Check: Zertifikat von Bob ist korrekt!");
    } else {
      System.out.println("Zertifikat Check: Zertifikat von Bob ist NICHT korrekt! ABBRUCH!");
      System.exit(0);
    }

    // decrypt S_B_encrypted with idea
    BigInteger key = getIDEAKeyBasedOnK(k);
    BigInteger iv = new BigInteger(IV, 16);
    idea = new IDEA(key, iv);
    BigInteger S_B = idea.decipher(S_B_encrypted);

    // generate hash
    BigInteger hash = hash(y_B, y_A);

    if (MitM) {
      hash = hash(y_B, y_W);
    }

    // alice überprüft die gültigkeit von S_B
    if (checkSignature(hash, S_B, e_B, n_B) == true) {
      System.out.println("Signature Check: hashs h(y_B, y_A) sind gleich! Alice akzeptiert k!");
    } else {
      System.out.println("Signature Check: Hashs nicht gleich! ABBRUCH!");
      System.exit(0);
    }

    // signatur von alice S_A generieren
    // generate hash
    BigInteger hash2 = hash(y_A, y_B);
    BigInteger S_A = rsa_A.getSignatur(hash2); // S_A = hash^d_A mod n_A

    System.out.println("Signatur S_A: " + S_A);

    // zertifikat generieren
    Certificate Z_A = generateCertificate(rsa_A.e, rsa_A.n);

    // signatur encrypted
    BigInteger S_A_encrypted = idea.encipher(S_A);

    // alice sendet Z_A in einzelteilen
    Com.sendTo(1, Z_A.getID()); // send ID // S13
    // String data_send = new String(Z_A.getData());
    String data_send = serialize(Z_A.getData());
    System.out.println("data send: " + data_send);
    Com.sendTo(1, data_send); // send data (pub key) // S14
    Com.sendTo(1, Z_A.getSignature().toString(16)); // send signature // S15

    // und S_A_encrypted (ohne y_A, das wurde schon gesendet)
    Com.sendTo(1, S_A_encrypted.toString(16)); // S16

    // Chat Start
    BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
    String input = "";

    while (true) {
      System.out.print("Enter your message (Enter q for quit): ");
      System.out.flush(); // empties buffer, before you input text
      try {
        input = stdin.readLine();
      } catch (IOException e) {
        e.printStackTrace();
      }

      System.out.println("Your message: " + input);

      if (input.equalsIgnoreCase("q")) {
        System.exit(0);
      }

      BigInteger inputInteger = new BigInteger(input.getBytes());
      BigInteger inputInteger_encrypted = idea.encipher(inputInteger);

      Com.sendTo(1, inputInteger_encrypted.toString(16));

      String receive = Com.receive();
      BigInteger receiveInteger = new BigInteger(receive, 16);
      BigInteger receiveInteger_decrypted = idea.decipher(receiveInteger);

      System.out.println("Message from Bob: " + new String(receiveInteger_decrypted.toByteArray()));
    }

  }