private void runProtocolAsPlayerA() // Player A is Server { if (PP.msgProtocolAborted) { protocolAborted(); } if (PP.msgProtocolRestarted) { initializeNewPairing(); } // Step 0: once player B has connected, send the shared protocol parameters. // For now, we send: // -- which type of confirmation step are we using: secretColors or secretNumbers // -- how many secret elements should there be if (PP.currentStep == 0 && NM.numPlayers == 2) { // Choose the number of secret elements System.Random rand = new System.Random(); PP.cnfgNumberOfSecretElements = secretElementSizes[rand.Next(0, secretElementSizes.Length)]; RpcPlayerASendProtocolParameters(PP.cnfgShouldUseSecretColors, PP.cnfgNumberOfSecretElements, PP.shouldAttackHappen()); PP.currentStep = 1; } // Step 1: User A sends his public key if (PP.currentStep == 1 && PP.msgPublicKeyA == "") { PP.AddTimeStampsToSteps(PP.currentStep); // generate userA's key pair CryptoManager.generateNewKeyPair(); // send it to the server who will broadcast it to everyone else RpcPlayerASendPublicKey(CryptoManager.getPublicKey()); PP.currentStep = 3; // go to the next step in the protocol } // Step 3: After receiving B's public key, user A makes a commitment on some value K if (PP.currentStep == 3 && PP.msgPublicKeyB != "") { PP.AddTimeStampsToSteps(PP.currentStep); // Player A generates those himself PP.myPrivateK = CryptoManager.generateRandomNonce(); PP.myHashOfK = CryptoManager.generateHashFromString(PP.myPrivateK); RpcPlayerASendHashOfK(PP.myHashOfK); instructionsDisplay.setText("1. When other user waves, click on their cube."); PP.currentStep = 5; } // Step 5: After user A confirms that he has received an ACK from user B on the visual channel, we proceed if (PP.currentStep == 5 && PP.userAConfirmedVisualACK) { PP.AddTimeStampsToSteps(PP.currentStep); // Encrypt the plaintext K using B's public key string myEncryptedK = CryptoManager.encrypt(PP.myPrivateK, PP.msgPublicKeyB); RpcPlayerASendEncryptedK(myEncryptedK); PP.msgEncryptedK = myEncryptedK; // I can now also set all the colors PP.myFinalSharedKey = PP.msgPublicKeyA + PP.msgPublicKeyB + PP.myPrivateK; setupSharedSecretVisualisation(PP.cnfgShouldUseSecretColors, PP.cnfgNumberOfSecretElements, PP.myFinalSharedKey); instructionsDisplay.setText("2. If gestures are correct, click on their cube.\nIf they make a mistake, say \"Abort\""); PP.currentStep = 7; } if (PP.currentStep == 7 && PP.userAConfirmedPairingSuccessful) { PP.AddTimeStampsToSteps(PP.currentStep); // Send a message in which a hash of our shared key is encrypted with B's private key string hashedSharedKey = CryptoManager.generateHashFromString(PP.myFinalSharedKey); RpcPlayerASendFinalMessage(hashedSharedKey); protocolSuccessful(); } }