/** * Create first message in SMP exchange. Input is Alice's secret value which this protocol aims to * compare to Bob's. The return value is a serialized MPI array whose elements correspond to the * following: [0] = g2a, Alice's half of DH exchange to determine g2 [1] = c2, [2] = d2, Alice's * ZK proof of knowledge of g2a exponent [3] = g3a, Alice's half of DH exchange to determine g3 * [4] = c3, [5] = d3, Alice's ZK proof of knowledge of g3a exponent * * @throws OTRException */ public static byte[] step1(SMState astate, byte[] secret, Provider prov) throws OTRException { /* Initialize the sm state or update the secret */ // Util.checkBytes("secret", secret); MPI secret_mpi = new MPI(secret); astate.secret = secret_mpi; astate.receivedQuestion = 0; astate.x2 = randomExponent(prov); astate.x3 = randomExponent(prov); MPI[] msg1 = new MPI[6]; msg1[0] = prov.powm(astate.g1, astate.x2, new MPI(MODULUS_S)); MPI[] res = proofKnowLog(astate.g1, astate.x2, 1, prov); msg1[1] = res[0]; msg1[2] = res[1]; msg1[3] = prov.powm(astate.g1, astate.x3, new MPI(MODULUS_S)); res = proofKnowLog(astate.g1, astate.x3, 2, prov); msg1[4] = res[0]; msg1[5] = res[1]; byte[] ret = serializeMPIArray(msg1); astate.smProgState = PROG_OK; return ret; }
/** * Receive the first message in SMP exchange, which was generated by step1. Input is saved until * the user inputs their secret information. No output. * * @throws OTRException */ public static void step2a(SMState bstate, byte[] input, int received_question, Provider prov) throws OTRException { /* Initialize the sm state if needed */ bstate.receivedQuestion = received_question; bstate.smProgState = PROG_CHEATED; /* Read from input to find the mpis */ MPI[] msg1 = unserializeMPIArray(input); if (checkGroupElem(msg1[0], prov) || checkExpon(msg1[2], prov) || checkGroupElem(msg1[3], prov) || checkExpon(msg1[5], prov)) { throw new OTRException("Invalid parameter"); } /* Store Alice's g3a value for later in the protocol */ bstate.g3o = msg1[3]; /* Verify Alice's proofs */ if (checkKnowLog(msg1[1], msg1[2], bstate.g1, msg1[0], 1, prov) != 0 || checkKnowLog(msg1[4], msg1[5], bstate.g1, msg1[3], 2, prov) != 0) { throw new OTRException("Proof checking failed"); } /* Create Bob's half of the generators g2 and g3 */ bstate.x2 = randomExponent(prov); bstate.x3 = randomExponent(prov); /* Combine the two halves from Bob and Alice and determine g2 and g3 */ bstate.g2 = prov.powm(msg1[0], bstate.x2, new MPI(MODULUS_S)); // Util.checkBytes("g2b", bstate.g2.getValue()); bstate.g3 = prov.powm(msg1[3], bstate.x3, new MPI(MODULUS_S)); // Util.checkBytes("g3b", bstate.g3.getValue()); bstate.smProgState = PROG_OK; }