Beispiel #1
0
        /// <summary>
        ///     Creates a round 1 (zero-knowledge proof) DTO to send to the partner participant.
        /// </summary>
        public ECJpakeRound1 CreateRound1ToSend()
        {
            Contract.Requires(ProtocolState < State.Round1Created, "Round 1 payload already created.");

            BigInteger x1 = BigInteger.CreateRandomInRange(BigInteger.One, _domain.N.Subtract(BigInteger.One),
                                                           EntropySupply);

            _x2  = BigInteger.CreateRandomInRange(BigInteger.One, _domain.N.Subtract(BigInteger.One), EntropySupply);
            _gx1 = BasePointMultiplier.Multiply(_domain.G, x1);
            _gx2 = BasePointMultiplier.Multiply(_domain.G, _x2);

            ECPoint    V1, V2;
            BigInteger r1, r2;

            CreateZeroKnowledgeProof(_domain.G, x1, _gx1, ParticipantId, out V1, out r1);
            CreateZeroKnowledgeProof(_domain.G, _x2, _gx2, ParticipantId, out V2, out r2);

            var dto = new ECJpakeRound1 {
                ParticipantId = ParticipantId,
                GX1           = _gx1.GetEncoded(),
                X1V           = V1.GetEncoded(),
                X1R           = r1.ToByteArray(),
                GX2           = _gx2.GetEncoded(),
                X2V           = V2.GetEncoded(),
                X2R           = r2.ToByteArray()
            };

            ProtocolState = State.Round1Created;
            return(dto);
        }
Beispiel #2
0
        /// <summary>
        ///     Validates the round 1 (zero-knowledge proof) DTO received from the partner participant.
        /// </summary>
        /// <param name="round1Received">Round 1 DTO received from partner participant.</param>
        public void ValidateRound1Received(ECJpakeRound1 round1Received)
        {
            Contract.Requires <InvalidOperationException>(ProtocolState < State.Round1Validated,
                                                          "Validation already attempted for round 1 payload.");

            Contract.Requires <ConfigurationInvalidException>(String.IsNullOrEmpty(round1Received.ParticipantId) == false,
                                                              "Partner participant ID in round 1 DTO received is null or empty.");

            PartnerParticipantId = round1Received.ParticipantId;
            _gx3 = _domain.Curve.DecodePoint(round1Received.GX1);
            _gx4 = _domain.Curve.DecodePoint(round1Received.GX2);

            ECPoint X3V = _domain.Curve.DecodePoint(round1Received.X1V);
            var     X3R = new BigInteger(round1Received.X1R);
            ECPoint X4V = _domain.Curve.DecodePoint(round1Received.X2V);
            var     X4R = new BigInteger(round1Received.X2R);

            if (ZeroKnowledgeProofValid(_domain.G, _gx3, X3V, X3R,
                                        PartnerParticipantId) == false ||
                ZeroKnowledgeProofValid(_domain.G, _gx4, X4V, X4R,
                                        PartnerParticipantId) == false)
            {
                throw new CryptoException("Verification of zero-knowledge proof in round 1 failed.");
            }

            ProtocolState = State.Round1Validated;
        }
Beispiel #3
0
        /// <summary>
        ///     Restores the state of an incomplete J-PAKE session,
        ///     given private keys and DTO objects created/received from that session.
        /// </summary>
        /// <param name="x2">Private key.</param>
        /// <param name="round1Created">Round 1 created/sent.</param>
        /// <param name="round1Received">Round 1 received.</param>
        /// <param name="round2Created">Round 2 created/sent.</param>
        /// <param name="round2Received">Round 2 received.</param>
        /// <param name="round3Created">Round 3 created/sent.</param>
        public void RestoreState(byte[] x2, ECJpakeRound1 round1Created, ECJpakeRound1 round1Received = null,
                                 ECJpakeRound2 round2Created = null, ECJpakeRound2 round2Received = null, JpakeRound3 round3Created = null)
        {
            Contract.Requires(ProtocolState == State.Initialised, "Cannot restore state of already-active protocol session!");
            Contract.Requires(round1Created != null);

            _gx1          = _domain.Curve.DecodePoint(round1Created.GX1);
            _gx2          = _domain.Curve.DecodePoint(round1Created.GX2);
            ProtocolState = State.Round1Created;

            if (round1Received != null)
            {
                if (String.IsNullOrEmpty(round1Received.ParticipantId))
                {
                    throw new ArgumentException("Partner participant ID in round 1 received is null or empty.");
                }
                PartnerParticipantId = round1Received.ParticipantId;
                _gx3          = _domain.Curve.DecodePoint(round1Received.GX1);
                _gx4          = _domain.Curve.DecodePoint(round1Received.GX2);
                ProtocolState = State.Round1Validated;
            }
            else
            {
                return;
            }

            if (round2Created != null)
            {
                ProtocolState = State.Round2Created;
            }
            else
            {
                return;
            }

            if (round2Received != null)
            {
                if (PartnerParticipantId.Equals(round2Received.ParticipantId, StringComparison.Ordinal) == false)
                {
                    throw new ArgumentException("Partner participant ID of round 2 does not match value from round 1.");
                }
                _b            = _domain.Curve.DecodePoint(round2Received.A);
                ProtocolState = State.Round2Validated;
            }
            else
            {
                return;
            }

            if (round3Created != null)
            {
                // Keying material has been calculated
                _b            = _domain.Curve.DecodePoint(round2Received.A);
                ProtocolState = State.Round3Created;
            }
            else
            {
                if (x2.IsNullOrZeroLength())
                {
                    throw new ArgumentException("Session cannot be resumed without private key x2Export. Aborting.");
                }
            }
        }