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); }
/// <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; }