Beispiel #1
0
  /**
   * Receives the final SMP message, which was generated in otrl_sm_step. This method checks if
   * Alice and Bob's secrets were the same. If so, it returns NO_ERROR. If the secrets differ, an
   * INV_VALUE error is returned instead.
   *
   * @throws OTRException
   */
  public static void step5(SMState astate, byte[] input, Provider prov) throws OTRException {
    /* Read from input to find the mpis */
    MPI[] msg4 = unserializeMPIArray(input);
    astate.smProgState = PROG_CHEATED;

    if (checkGroupElem(msg4[0], prov) || checkExpon(msg4[2], prov)) {
      throw new OTRException("Invalid Parameter");
    }

    /* Verify Bob's log equality proof */
    if (checkEqualLogs(msg4[1], msg4[2], msg4[0], astate, 8, prov) != 0)
      throw new OTRException("Invalid Parameter");

    /* Calculate Rab and verify that secrets match */

    MPI rab = prov.powm(msg4[0], astate.x3, new MPI(MODULUS_S));
    // Util.checkBytes("rab", rab.getValue());
    // Util.checkBytes("pab", astate.pab.getValue());
    int comp = prov.compareMPI(rab, astate.pab);
    if (comp != 0) {
      // System.out.println("checking failed");
    }

    astate.smProgState = (comp != 0) ? PROG_FAILED : PROG_SUCCEEDED;

    return;
  }
Beispiel #2
0
  /**
   * 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;
  }
Beispiel #3
0
  /**
   * Create final message in SMP exchange. Input is a message generated by otrl_sm_step3. Output is
   * a serialized mpi array whose elements correspond to the following: [0] = rb, calculated as
   * (Qa/Qb)^x3 where x3 is the exponent used in g3b [1] = cr, [2] = d7, Bob's ZK proof that rb is
   * formed correctly This method also checks if Alice and Bob's secrets were the same. If so, it
   * returns NO_ERROR. If the secrets differ, an INV_VALUE error is returned instead.
   *
   * @throws OTRException
   */
  public static byte[] step4(SMState bstate, byte[] input, Provider prov) throws OTRException {
    /* Read from input to find the mpis */
    MPI[] msg3 = unserializeMPIArray(input);

    bstate.smProgState = PROG_CHEATED;

    MPI[] msg4 = new MPI[3];

    if (checkGroupElem(msg3[0], prov)
        || checkGroupElem(msg3[1], prov)
        || checkGroupElem(msg3[5], prov)
        || checkExpon(msg3[3], prov)
        || checkExpon(msg3[4], prov)
        || checkExpon(msg3[7], prov)) {
      throw new OTRException("Invalid Parameter");
    }

    /* Verify Alice's coordinate equality proof */
    if (checkEqualCoords(msg3[2], msg3[3], msg3[4], msg3[0], msg3[1], bstate, 6, prov) != 0)
      throw new OTRException("Invalid Parameter");

    /* Find Pa/Pb and Qa/Qb */
    MPI inv = prov.invm(bstate.p, new MPI(MODULUS_S));
    bstate.pab = prov.mulm(msg3[0], inv, new MPI(MODULUS_S));
    inv = prov.invm(bstate.q, new MPI(MODULUS_S));
    bstate.qab = prov.mulm(msg3[1], inv, new MPI(MODULUS_S));

    /* Verify Alice's log equality proof */
    if (checkEqualLogs(msg3[6], msg3[7], msg3[5], bstate, 7, prov) != 0) {
      throw new OTRException("Proof checking failed");
    }

    /* Calculate Rb and proof */
    msg4[0] = prov.powm(bstate.qab, bstate.x3, new MPI(MODULUS_S));
    MPI[] res = proofEqualLogs(bstate, 8, prov);
    msg4[1] = res[0];
    msg4[2] = res[1];

    byte[] output = serializeMPIArray(msg4);

    /* Calculate Rab and verify that secrets match */

    MPI rab = prov.powm(msg3[5], bstate.x3, new MPI(MODULUS_S));
    // Util.checkBytes("rab", rab.getValue());
    // Util.checkBytes("pab", bstate.pab.getValue());
    int comp = prov.compareMPI(rab, bstate.pab);

    bstate.smProgState = (comp != 0) ? PROG_FAILED : PROG_SUCCEEDED;

    return output;
  }
Beispiel #4
0
  /**
   * Create second message in SMP exchange. Input is Bob's secret value. Information from earlier
   * steps in the exchange is taken from Bob's state. Output is a serialized mpi array whose
   * elements correspond to the following: [0] = g2b, Bob's half of DH exchange to determine g2 [1]
   * = c2, [2] = d2, Bob's ZK proof of knowledge of g2b exponent [3] = g3b, Bob's half of DH
   * exchange to determine g3 [4] = c3, [5] = d3, Bob's ZK proof of knowledge of g3b exponent [6] =
   * pb, [7] = qb, Bob's halves of the (Pa/Pb) and (Qa/Qb) values [8] = cp, [9] = d5, [10] = d6,
   * Bob's ZK proof that pb, qb formed correctly
   *
   * @throws OTRException
   */
  public static byte[] step2b(SMState bstate, byte[] secret, Provider prov) throws OTRException {
    /* Convert the given secret to the proper form and store it */
    // Util.checkBytes("secret", secret);
    MPI secret_mpi = new MPI(secret);
    bstate.secret = secret_mpi;

    MPI[] msg2 = new MPI[11];
    msg2[0] = prov.powm(bstate.g1, bstate.x2, new MPI(MODULUS_S));
    MPI[] res = proofKnowLog(bstate.g1, bstate.x2, 3, prov);
    msg2[1] = res[0];
    msg2[2] = res[1];

    msg2[3] = prov.powm(bstate.g1, bstate.x3, new MPI(MODULUS_S));
    res = proofKnowLog(bstate.g1, bstate.x3, 4, prov);
    msg2[4] = res[0];
    msg2[5] = res[1];

    /* Calculate P and Q values for Bob */
    MPI r = randomExponent(prov);
    // MPI r = new MPI(SM.GENERATOR_S);

    bstate.p = prov.powm(bstate.g3, r, new MPI(MODULUS_S));
    // Util.checkBytes("Pb", bstate.p.getValue());
    msg2[6] = bstate.p;
    MPI qb1 = prov.powm(bstate.g1, r, new MPI(MODULUS_S));
    // Util.checkBytes("Qb1", qb1.getValue());
    MPI qb2 = prov.powm(bstate.g2, bstate.secret, new MPI(MODULUS_S));
    // Util.checkBytes("Qb2", qb2.getValue());
    // Util.checkBytes("g2", bstate.g2.getValue());
    // Util.checkBytes("secret", bstate.secret.getValue());
    bstate.q = prov.mulm(qb1, qb2, new MPI(MODULUS_S));
    // Util.checkBytes("Qb", bstate.q.getValue());
    msg2[7] = bstate.q;

    res = proofEqualCoords(bstate, r, 5, prov);
    msg2[8] = res[0];
    msg2[9] = res[1];
    msg2[10] = res[2];

    /* Convert to serialized form */
    return serializeMPIArray(msg2);
  }
Beispiel #5
0
  /**
   * 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;
  }
Beispiel #6
0
  /**
   * Create third message in SMP exchange. Input is a message generated by otrl_sm_step2b. Output is
   * a serialized mpi array whose elements correspond to the following: [0] = pa, [1] = qa, Alice's
   * halves of the (Pa/Pb) and (Qa/Qb) values [2] = cp, [3] = d5, [4] = d6, Alice's ZK proof that
   * pa, qa formed correctly [5] = ra, calculated as (Qa/Qb)^x3 where x3 is the exponent used in g3a
   * [6] = cr, [7] = d7, Alice's ZK proof that ra is formed correctly
   *
   * @throws OTRException
   */
  public static byte[] step3(SMState astate, byte[] input, Provider prov) throws OTRException {
    /* Read from input to find the mpis */
    astate.smProgState = PROG_CHEATED;

    MPI[] msg2 = unserializeMPIArray(input);
    if (checkGroupElem(msg2[0], prov)
        || checkGroupElem(msg2[3], prov)
        || checkGroupElem(msg2[6], prov)
        || checkGroupElem(msg2[7], prov)
        || checkExpon(msg2[2], prov)
        || checkExpon(msg2[5], prov)
        || checkExpon(msg2[9], prov)
        || checkExpon(msg2[10], prov)) {
      throw new OTRException("Invalid Parameter");
    }

    MPI[] msg3 = new MPI[8];

    /* Store Bob's g3a value for later in the protocol */
    astate.g3o = msg2[3];

    /* Verify Bob's knowledge of discreet log proofs */
    if (checkKnowLog(msg2[1], msg2[2], astate.g1, msg2[0], 3, prov) != 0
        || checkKnowLog(msg2[4], msg2[5], astate.g1, msg2[3], 4, prov) != 0) {
      throw new OTRException("Proof checking failed");
    }

    /* Combine the two halves from Bob and Alice and determine g2 and g3 */
    astate.g2 = prov.powm(msg2[0], astate.x2, new MPI(MODULUS_S));
    // Util.checkBytes("g2a", astate.g2.getValue());
    astate.g3 = prov.powm(msg2[3], astate.x3, new MPI(MODULUS_S));
    // Util.checkBytes("g3a", astate.g3.getValue());

    /* Verify Bob's coordinate equality proof */
    if (checkEqualCoords(msg2[8], msg2[9], msg2[10], msg2[6], msg2[7], astate, 5, prov) != 0)
      throw new OTRException("Invalid Parameter");

    /* Calculate P and Q values for Alice */
    MPI r = randomExponent(prov);
    // MPI r = new MPI(SM.GENERATOR_S);

    astate.p = prov.powm(astate.g3, r, new MPI(MODULUS_S));
    // Util.checkBytes("Pa", astate.p.getValue());
    msg3[0] = astate.p;
    MPI qa1 = prov.powm(astate.g1, r, new MPI(MODULUS_S));
    // Util.checkBytes("Qa1", qa1.getValue());
    MPI qa2 = prov.powm(astate.g2, astate.secret, new MPI(MODULUS_S));
    // Util.checkBytes("Qa2", qa2.getValue());
    // Util.checkBytes("g2", astate.g2.getValue());
    // Util.checkBytes("secret", astate.secret.getValue());
    astate.q = prov.mulm(qa1, qa2, new MPI(MODULUS_S));
    msg3[1] = astate.q;
    // Util.checkBytes("Qa", astate.q.getValue());

    MPI[] res = proofEqualCoords(astate, r, 6, prov);
    msg3[2] = res[0];
    msg3[3] = res[1];
    msg3[4] = res[2];

    /* Calculate Ra and proof */
    MPI inv = prov.invm(msg2[6], new MPI(MODULUS_S));
    astate.pab = prov.mulm(astate.p, inv, new MPI(MODULUS_S));
    inv = prov.invm(msg2[7], new MPI(MODULUS_S));
    astate.qab = prov.mulm(astate.q, inv, new MPI(MODULUS_S));
    msg3[5] = prov.powm(astate.qab, astate.x3, new MPI(MODULUS_S));
    res = proofEqualLogs(astate, 7, prov);
    msg3[6] = res[0];
    msg3[7] = res[1];

    byte[] output = serializeMPIArray(msg3);

    astate.smProgState = PROG_OK;
    return output;
  }