Beispiel #1
0
        /// <summary>
        /// Constructs an ECCGroup.
        /// <param name="p">The p parameter, representing the prime field domain for the
        /// x and y coordinate spaces.</param>
        /// <param name="a">The a parameter for the eliptic curve.</param>
        /// <param name="b">The b parameter for the eliptic curve.</param>
        /// <param name="g_x">The x coordinate of the generator point.</param>
        /// <param name="g_y">The y coordinate of the generator point.</param>
        /// <param name="n">The order of the group.</param>
        /// <param name="groupName">The known name of the group, or null.</param>
        /// <param name="curveName">The known name of the curve, or null.</param>
        /// </summary>
        public ECGroupBCImpl(
            byte[] p,
            byte[] a,
            byte[] b,
            byte[] g_x,
            byte[] g_y,
            byte[] n,
            string groupName,
            string curveName)
            : base(p, a, b, g_x, g_y, n, groupName, curveName)
        {
            this.curve = new BouncyCastle.FpCurve(
                new BCBigInt(1, p),
                new BCBigInt(1, a),
                new BCBigInt(1, b));

            BouncyCastle.ECPoint generator = this.curve.CreatePoint(
                new BCBigInt(1, g_x),
                new BCBigInt(1, g_y),
                false);

            this.domainParams = new BouncyCastle.ECDomainParameters(
                this.curve,
                generator,
                new BCBigInt(1, n));

            this.g = new ECGroupElementBCImpl(
                this.domainParams.G as BouncyCastle.FpPoint);
        }
Beispiel #2
0
        /// <summary>
        /// Derives an unpredictable element of the group, using the input. Each
        /// construction defines its own derivation mechanism, but each takes an
        /// optional context string and an index, and returns a counter. Calling
        /// this method with the same parameter values returns the same element
        /// and counter, calling it with a different context or index value must
        /// return a different element.
        /// </summary>
        /// <param name="context">An optional context used by the derivation
        /// mechanism, can be null.</param>
        /// <param name="index">An 8-bit integer index value.</param>
        /// <param name="counter">A counter value indicating the state at which the
        /// derivation mechanism stopped.</param>
        /// <returns>A random group element.</returns>
        public override GroupElement DeriveElement(byte[] context, byte index, out int counter)
        {
            // concatenate context and curve name
            BouncyCastle.FpCurve curve = this.domainParams.Curve as BouncyCastle.FpCurve;
            int count = 0;

            BouncyCastle.ECFieldElement x = null, y = null;
            while (y == null)
            {
                x = GetX(context, curve, index, count);

                BouncyCastle.ECFieldElement alpha = x.Multiply(x.Square().Add(curve.A)).Add(curve.B);
                if (alpha.ToBigInteger() == BCBigInt.Zero)
                {
                    y = alpha;
                }
                else
                {
                    y = alpha.Sqrt(); // returns null if sqrt does not exist
                }
                count++;
            }
            // determine which sqrt to return, i.e., Min(y, -y)
            BouncyCastle.ECFieldElement minusY = y.Negate();
            counter = count - 1;
            return(new ECGroupElementBCImpl(new BouncyCastle.FpPoint(curve, x, y.ToBigInteger() < minusY.ToBigInteger() ? y : minusY)));
        }
Beispiel #3
0
        private BouncyCastle.FpFieldElement GetX(
            byte[] input,
            BouncyCastle.FpCurve curve,
            int index,
            int counter)
        {
            int numIterations = (int)System.Math.Ceiling(
                (double)(curve.Q.BitLength / 8) / (double)hashByteSize);

            byte[] digest = new byte[numIterations * hashByteSize];

            for (int iteration = 0; iteration < numIterations; iteration++)
            {
                byte[] hashInput = ProtocolHelper.Concatenate(
                    input,
                    encoding.GetBytes(
                        index.ToString() + counter.ToString() + iteration.ToString()));
                hash.HashWithoutFormatting(hashInput);
                Array.Copy(hash.Digest, 0, digest, hashByteSize * iteration, hashByteSize);
            }

            BCBigInt x = new BCBigInt(1, digest).Mod(curve.Q);

            return(curve.FromBigInteger(x) as BouncyCastle.FpFieldElement);
        }
Beispiel #4
0
 /// <summary>
 /// Returns the group element encoded as two byte arrays, one for
 /// each coordinate.
 /// </summary>
 /// <param name="x">A byte array encoding the x coordinate.</param>
 /// <param name="y">A byte array encoding the y coordinate.</param>
 /// <returns>A group element.</returns>
 public override GroupElement CreateGroupElement(byte[] x, byte[] y)
 {
     BouncyCastle.FpCurve curve = (BouncyCastle.FpCurve)domainParams.Curve;
     return(new ECGroupElementBCImpl(
                new BouncyCastle.FpPoint(
                    domainParams.Curve,
                    new BouncyCastle.FpFieldElement(curve.Q, new BCBigInt(1, x)),
                    new BouncyCastle.FpFieldElement(curve.Q, new BCBigInt(1, y)))));
 }
        /// <summary>
        /// Constructs an ECCGroup.
        /// <param name="p">The p parameter, representing the prime field domain for the 
        /// x and y coordinate spaces.</param>
        /// <param name="a">The a parameter for the eliptic curve.</param>
        /// <param name="b">The b parameter for the eliptic curve.</param>
        /// <param name="g_x">The x coordinate of the generator point.</param>
        /// <param name="g_y">The y coordinate of the generator point.</param>
        /// <param name="n">The order of the group.</param>
        /// <param name="groupName">The known name of the group, or null.</param>
        /// <param name="curveName">The known name of the curve, or null.</param>
        /// </summary>
        public ECGroupBCImpl(
            byte[] p, 
            byte[] a, 
            byte[] b, 
            byte[] g_x, 
            byte[] g_y, 
            byte[] n, 
            string groupName, 
            string curveName)
            : base(p, a, b, g_x, g_y, n, groupName, curveName)
        {
            this.curve = new BouncyCastle.FpCurve(
                new BCBigInt(1, p), 
                new BCBigInt(1, a), 
                new BCBigInt(1, b));

            BouncyCastle.ECPoint generator = this.curve.CreatePoint(
                new BCBigInt(1, g_x), 
                new BCBigInt(1, g_y), 
                false);

            this.domainParams = new BouncyCastle.ECDomainParameters(
                                    this.curve,
                                    generator,
                                    new BCBigInt(1, n));

            this.g = new ECGroupElementBCImpl(
                this.domainParams.G as BouncyCastle.FpPoint);
        }