public JPakeRound2Payload(string participantId, BigInteger a, BigInteger[] knowledgeProofForX2s)
        {
            JPakeUtilities.ValidateNotNull(participantId, "participantId");
            JPakeUtilities.ValidateNotNull(a, "a");
            JPakeUtilities.ValidateNotNull(knowledgeProofForX2s, "knowledgeProofForX2s");

            this.participantId        = participantId;
            this.a                    = a;
            this.knowledgeProofForX2s = new BigInteger[knowledgeProofForX2s.Length];
            knowledgeProofForX2s.CopyTo(this.knowledgeProofForX2s, 0);
        }
        public JPakeRound1Payload(string participantId, BigInteger gx1, BigInteger gx2, BigInteger[] knowledgeProofForX1, BigInteger[] knowledgeProofForX2)
        {
            JPakeUtilities.ValidateNotNull(participantId, "participantId");
            JPakeUtilities.ValidateNotNull(gx1, "gx1");
            JPakeUtilities.ValidateNotNull(gx2, "gx2");
            JPakeUtilities.ValidateNotNull(knowledgeProofForX1, "knowledgeProofForX1");
            JPakeUtilities.ValidateNotNull(knowledgeProofForX2, "knowledgeProofForX2");

            this.participantId       = participantId;
            this.gx1                 = gx1;
            this.gx2                 = gx2;
            this.knowledgeProofForX1 = new BigInteger[knowledgeProofForX1.Length];
            Array.Copy(knowledgeProofForX1, this.knowledgeProofForX1, knowledgeProofForX1.Length);
            this.knowledgeProofForX2 = new BigInteger[knowledgeProofForX2.Length];
            Array.Copy(knowledgeProofForX2, this.knowledgeProofForX2, knowledgeProofForX2.Length);
        }
Beispiel #3
0
        /// <summary>
        /// Constructor for a new JPakeParticipant.
        ///
        /// After construction, the State state will be STATE_INITIALIZED.
        ///
        /// Throws NullReferenceException if any argument is null. Throws
        /// ArgumentException if password is empty.
        /// </summary>
        /// <param name="participantId">Unique identifier of this participant.
        ///      The two participants in the exchange must NOT share the same id.</param>
        /// <param name="password">Shared secret.
        ///      A defensive copy of this array is made (and cleared once CalculateKeyingMaterial() is called).
        ///      Caller should clear the input password as soon as possible.</param>
        /// <param name="group">Prime order group. See JPakePrimeOrderGroups for standard groups.</param>
        /// <param name="digest">Digest to use during zero knowledge proofs and key confirmation
        ///     (SHA-256 or stronger preferred).</param>
        /// <param name="random">Source of secure random data for x1 and x2, and for the zero knowledge proofs.</param>
        public JPakeParticipant(string participantId, char[] password, JPakePrimeOrderGroup group, IDigest digest, SecureRandom random)
        {
            JPakeUtilities.ValidateNotNull(participantId, "participantId");
            JPakeUtilities.ValidateNotNull(password, "password");
            JPakeUtilities.ValidateNotNull(group, "p");
            JPakeUtilities.ValidateNotNull(digest, "digest");
            JPakeUtilities.ValidateNotNull(random, "random");

            if (password.Length == 0)
            {
                throw new ArgumentException("Password must not be empty.");
            }

            this.participantId = participantId;

            // Create a defensive copy so as to fully encapsulate the password.
            //
            // This array will contain the password for the lifetime of this
            // participant BEFORE CalculateKeyingMaterial() is called.
            //
            // i.e. When CalculateKeyingMaterial() is called, the array will be cleared
            // in order to remove the password from memory.
            //
            // The caller is responsible for clearing the original password array
            // given as input to this constructor.
            this.password = new char[password.Length];
            Array.Copy(password, this.password, password.Length);

            this.p = group.P;
            this.q = group.Q;
            this.g = group.G;

            this.digest = digest;
            this.random = random;

            this.state = STATE_INITIALIZED;
        }
        /// <summary>
        /// Constructor used by the pre-approved groups in JPakePrimeOrderGroups.
        /// These pre-approved groups can avoid the expensive checks.
        /// User-specified groups should not use this constructor.
        /// </summary>
        public JPakePrimeOrderGroup(BigInteger p, BigInteger q, BigInteger g, bool skipChecks)
        {
            JPakeUtilities.ValidateNotNull(p, "p");
            JPakeUtilities.ValidateNotNull(q, "q");
            JPakeUtilities.ValidateNotNull(g, "g");

            if (!skipChecks)
            {
                if (!p.Subtract(JPakeUtilities.One).Mod(q).Equals(JPakeUtilities.Zero))
                {
                    throw new ArgumentException("p-1 must be evenly divisible by q");
                }
                if (g.CompareTo(BigInteger.Two) == -1 || g.CompareTo(p.Subtract(JPakeUtilities.One)) == 1)
                {
                    throw new ArgumentException("g must be in [2, p-1]");
                }
                if (!g.ModPow(q, p).Equals(JPakeUtilities.One))
                {
                    throw new ArgumentException("g^q mod p must equal 1");
                }

                // Note these checks do not guarantee that p and q are prime.
                // We just have reasonable certainty that they are prime.
                if (!p.IsProbablePrime(20))
                {
                    throw new ArgumentException("p must be prime");
                }
                if (!q.IsProbablePrime(20))
                {
                    throw new ArgumentException("q must be prime");
                }
            }

            this.p = p;
            this.q = q;
            this.g = g;
        }