Exemple #1
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
         * BigInteger 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
         *  */
        public static byte[] step1(SMState astate)
        {
            /* Initialize the sm state or update the secret */
            astate.x2 = randomExponent();
            astate.x3 = randomExponent();

            BigInteger[] msg1 = new BigInteger[6];
            msg1[0] = modPower(astate.g1, astate.x2, biModulus);
            BigInteger[] res = proofKnowLog(astate.g1, astate.x2, 1);
            msg1[1] = res[0];
            msg1[2] = res[1];

            msg1[3] = modPower(astate.g1, astate.x3, biModulus);
            res = proofKnowLog(astate.g1, astate.x3, 2);
            msg1[4] = res[0];
            msg1[5] = res[1];

            byte[] ret = serializeBigIntegerArray(msg1);
            astate.ProgState = ProgState.OK;

            return ret;
        }
Exemple #2
0
        /* Proof of knowledge of coordinates with first components being equal */
        private static BigInteger[] proofEqualCoords(SMState state, BigInteger r, int version)
        {
            BigInteger r1 = randomExponent();
            BigInteger r2 = randomExponent();

            /* Compute the value of c, as c = h(g3^r1, g1^r1 g2^r2) */
            BigInteger temp1 = modPower(state.g1, r1, biModulus);
            BigInteger temp2 = modPower(state.g2, r2, biModulus);
            temp2 = multipleMod(temp1, temp2, biModulus);
            temp1 = modPower(state.g3, r1, biModulus);
            BigInteger c = hash(version, temp1, temp2);

            /* Compute the d values, as d1 = r1 - r c, d2 = r2 - secret c */
            temp1 = multipleMod(r, c, biOrder);
            BigInteger d1 = subtractMod(r1, temp1, biOrder);

            temp1 = multipleMod(state.secret, c, biOrder);
            BigInteger d2 = subtractMod(r2, temp1, biOrder);

            BigInteger[] ret = new BigInteger[3];
            ret[0] = c;
            ret[1] = d1;
            ret[2] = d2;
            return ret;
        }
Exemple #3
0
        /* Proof of knowledge of logs with exponents being equal */
        private static BigInteger[] proofEqualLogs(SMState state, int version)
        {
            BigInteger r = randomExponent();

            /* Compute the value of c, as c = h(g1^r, (Qa/Qb)^r) */
            BigInteger temp1 = modPower(state.g1, r, biModulus);
            BigInteger temp2 = modPower(state.qab, r, biModulus);
            BigInteger c = hash(version, temp1, temp2);

            /* Compute the d values, as d = r - x3 c */
            temp1 = multipleMod(state.x3, c, biOrder);
            BigInteger d = subtractMod(r, temp1, biOrder);

            BigInteger[] ret = new BigInteger[2];
            ret[0] = c;
            ret[1] = d;
            return ret;
        }
Exemple #4
0
        /* Verify a proof of knowledge of coordinates with first components being equal */
        private static bool checkEqualCoords(BigInteger c, BigInteger d1, BigInteger d2, BigInteger p,
            BigInteger q, SMState state, int version)
        {
            /* To verify, we test that hash(g3^d1 * p^c, g1^d1 * g2^d2 * q^c) = c
             * If indeed c = hash(g3^r1, g1^r1 g2^r2), d1 = r1 - r*c,
             * d2 = r2 - secret*c.  And if indeed p = g3^r, q = g1^r * g2^secret
             * Then we should have that:
             *   hash(g3^d1 * p^c, g1^d1 * g2^d2 * q^c)
             * = hash(g3^(r1 - r*c + r*c), g1^(r1 - r*c + q*c) *
             *      g2^(r2 - secret*c + secret*c))
             * = hash(g3^r1, g1^r1 g2^r2)
             * = c
             */
            BigInteger temp2 = modPower(state.g3, d1, biModulus);
            BigInteger temp3 = modPower(p, c, biModulus);
            BigInteger temp1 = multipleMod(temp2, temp3, biModulus);

            temp2 = modPower(state.g1, d1, biModulus);
            temp3 = modPower(state.g2, d2, biModulus);
            temp2 = multipleMod(temp2, temp3, biModulus);
            temp3 = modPower(q, c, biModulus);
            temp2 = multipleMod(temp3, temp2, biModulus);

            BigInteger cprime = hash(version, temp1, temp2);

            return c != cprime;
        }
Exemple #5
0
        /* Verify a proof of knowledge of logs with exponents being equal */
        private static bool checkEqualLogs(BigInteger c, BigInteger d, BigInteger r, SMState state, int version)
        {
            /* Here, we recall the exponents used to create g3.
             * If we have previously seen g3o = g1^x where x is unknown
             * during the DH exchange to produce g3, then we may proceed with:
             *
             * To verify, we test that hash(g1^d * g3o^c, qab^d * r^c) = c
             * If indeed c = hash(g1^r1, qab^r1), d = r1- x * c
             * And if indeed r = qab^x
             * Then we should have that:
             *   hash(g1^d * g3o^c, qab^d r^c)
             * = hash(g1^(r1 - x*c + x*c), qab^(r1 - x*c + x*c))
             * = hash(g1^r1, qab^r1)
             * = c
             */

            BigInteger temp2 = modPower(state.g1, d, biModulus);
            BigInteger temp3 = modPower(state.g3o, c, biModulus);
            BigInteger temp1 = multipleMod(temp2, temp3, biModulus);

            temp3 = modPower(state.qab, d, biModulus);
            temp2 = modPower(r, c, biModulus);
            temp2 = multipleMod(temp3, temp2, biModulus);

            BigInteger cprime = hash(version, temp1, temp2);

            return c != cprime;
        }
Exemple #6
0
        /** Receives the readonly 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.
         *  */
        public static void step5(SMState astate, byte[] input)
        {
            /* Read from input to find the BigIntegers */
            BigInteger[] msg4 = unserializeBigIntegerArray(input);
            astate.ProgState = ProgState.Cheated;

            if (checkGroupElem(msg4[0]) || checkExpon(msg4[2]))
            {
                astate.ProgStateInformation = "Invalid Parameter"; return;
            }

            /* Verify Bob's log equality proof */
            if (checkEqualLogs(msg4[1], msg4[2], msg4[0], astate, 8))
            {
                astate.ProgStateInformation = "Invalid Parameter"; return;
            }

            /* Calculate Rab and verify that secrets match */
            BigInteger rab = modPower(msg4[0], astate.x3, biModulus);

            astate.ProgState = (rab != astate.pab) ? ProgState.Failed : ProgState.Succeeded;
        }
Exemple #7
0
        /** Create readonly message in SMP exchange.  Input is a message generated
         * by otrl_sm_step3. Output is a serialized BigInteger 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.
         *  */
        public static byte[] step4(SMState bstate, byte[] input)
        {
            /* Read from input to find the BigIntegers */
            BigInteger[] msg3 = unserializeBigIntegerArray(input);

            bstate.ProgState = ProgState.Cheated;

            BigInteger[] msg4 = new BigInteger[3];

            if (checkGroupElem(msg3[0]) || checkGroupElem(msg3[1]) ||
                checkGroupElem(msg3[5]) || checkExpon(msg3[3]) ||
                checkExpon(msg3[4]) || checkExpon(msg3[7]))
            {
                bstate.ProgStateInformation = "Invalid Parameter"; return new byte[0];
            }

            /* Verify Alice's coordinate equality proof */
            if (checkEqualCoords(msg3[2], msg3[3], msg3[4], msg3[0], msg3[1], bstate, 6))
            {
                bstate.ProgStateInformation = "Invalid Parameter"; return new byte[0];
            }

            /* Find Pa/Pb and Qa/Qb */
            BigInteger inv = modInverse(bstate.p, biModulus);
            bstate.pab = multipleMod(msg3[0], inv, biModulus);
            inv = modInverse(bstate.q, biModulus);
            bstate.qab = multipleMod(msg3[1], inv, biModulus);

            /* Verify Alice's log equality proof */
            if (checkEqualLogs(msg3[6], msg3[7], msg3[5], bstate, 7))
            {
                bstate.ProgStateInformation = "Proof checking failed"; return new byte[0];
            }

            /* Calculate Rb and proof */
            msg4[0] = modPower(bstate.qab, bstate.x3, biModulus);
            BigInteger[] res = proofEqualLogs(bstate, 8);
            msg4[1] = res[0];
            msg4[2] = res[1];

            byte[] output = serializeBigIntegerArray(msg4);

            /* Calculate Rab and verify that secrets match */

            BigInteger rab = modPower(msg3[5], bstate.x3, biModulus);

            bstate.ProgState = (rab != bstate.pab) ? ProgState.Failed : ProgState.Succeeded;

            return output;
        }
Exemple #8
0
        /** Create third message in SMP exchange.  Input is a message generated
         * by otrl_sm_step2b. Output is a serialized BigInteger 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
         *  */
        public static byte[] step3(SMState astate, byte[] input)
        {
            /* Read from input to find the BigIntegers */
            astate.ProgState = ProgState.Cheated;

            BigInteger[] msg2 = unserializeBigIntegerArray(input);
            if (checkGroupElem(msg2[0]) || checkGroupElem(msg2[3]) ||
                checkGroupElem(msg2[6]) || checkGroupElem(msg2[7]) ||
                checkExpon(msg2[2]) || checkExpon(msg2[5]) ||
                checkExpon(msg2[9]) || checkExpon(msg2[10]))
            {
                astate.ProgStateInformation = "Invalid Parameter"; return new byte[0];
            }

            BigInteger[] msg3 = new BigInteger[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) ||
                checkKnowLog(msg2[4], msg2[5], astate.g1, msg2[3], 4))
            {
                astate.ProgStateInformation = "Proof checking failed"; return new byte[0];
            }

            /* Combine the two halves from Bob and Alice and determine g2 and g3 */
            astate.g2 = modPower(msg2[0], astate.x2, biModulus);
            astate.g3 = modPower(msg2[3], astate.x3, biModulus);

            /* Verify Bob's coordinate equality proof */
            if (checkEqualCoords(msg2[8], msg2[9], msg2[10], msg2[6], msg2[7], astate, 5))
            {
                astate.ProgStateInformation = "Invalid Parameter"; return new byte[0];
            }

            /* Calculate P and Q values for Alice */
            BigInteger r = randomExponent();

            astate.p = modPower(astate.g3, r, biModulus);
            msg3[0] = astate.p;
            BigInteger qa1 = modPower(astate.g1, r, biModulus);
            BigInteger qa2 = modPower(astate.g2, astate.secret, biModulus);
            astate.q = multipleMod(qa1, qa2, biModulus);
            msg3[1] = astate.q;

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

            /* Calculate Ra and proof */
            BigInteger inv = modInverse(msg2[6], biModulus);
            astate.pab = multipleMod(astate.p, inv, biModulus);
            inv = modInverse(msg2[7], biModulus);
            astate.qab = multipleMod(astate.q, inv, biModulus);
            msg3[5] = modPower(astate.qab, astate.x3, biModulus);
            res = proofEqualLogs(astate, 7);
            msg3[6] = res[0];
            msg3[7] = res[1];

            byte[] output = serializeBigIntegerArray(msg3);

            astate.ProgState = ProgState.OK;
            return output;
        }
Exemple #9
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 BigInteger 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
         *  */
        public static byte[] step2b(SMState bstate)
        {
            BigInteger[] msg2 = new BigInteger[11];
            msg2[0] = modPower(bstate.g1, bstate.x2, biModulus);
            BigInteger[] res = proofKnowLog(bstate.g1, bstate.x2, 3);
            msg2[1] = res[0];
            msg2[2] = res[1];

            msg2[3] = modPower(bstate.g1, bstate.x3, biModulus);
            res = proofKnowLog(bstate.g1, bstate.x3, 4);
            msg2[4] = res[0];
            msg2[5] = res[1];

            /* Calculate P and Q values for Bob */
            BigInteger r = randomExponent();

            bstate.p = modPower(bstate.g3, r, biModulus);
            msg2[6] = bstate.p;
            BigInteger qb1 = modPower(bstate.g1, r, biModulus);
            BigInteger qb2 = modPower(bstate.g2, bstate.secret, biModulus);
            bstate.q = multipleMod(qb1, qb2, biModulus);
            msg2[7] = bstate.q;

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

            /* Convert to serialized form */
            return serializeBigIntegerArray(msg2);
        }
Exemple #10
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.
         *  */
        public static void step2a(SMState bstate, byte[] input)
        {
            /* Initialize the sm state if needed */
            bstate.ProgState = ProgState.Cheated;

            /* Read from input to find the BigIntegers */
            BigInteger[] msg1 = unserializeBigIntegerArray(input);

            if (checkGroupElem(msg1[0]) || checkExpon(msg1[2]) ||
                    checkGroupElem(msg1[3]) || checkExpon(msg1[5]))
            {
                bstate.ProgStateInformation = "Invalid parameter"; return;
            }

            /* 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)
                || checkKnowLog(msg1[4], msg1[5], bstate.g1, msg1[3], 2))
            {
                bstate.ProgStateInformation = "Proof checking failed"; return;
            }

            /* Create Bob's half of the generators g2 and g3 */

            bstate.x2 = randomExponent();
            bstate.x3 = randomExponent();

            /* Combine the two halves from Bob and Alice and determine g2 and g3 */
            bstate.g2 = modPower(msg1[0], bstate.x2, biModulus);
            bstate.g3 = modPower(msg1[3], bstate.x3, biModulus);

            bstate.ProgState = ProgState.OK;
        }