Esempio n. 1
0
        public void TestLength()
        {
            var number   = SecureBigNumber.FromBigNumber(new BigNumber(0x548f07));
            var expected = NumberLength.FromBitLength(23);;

            Assert.That(number.Length.Equals(expected));
        }
Esempio n. 2
0
        public void TestComputeSecurityLevel()
        {
            var mod = BigPrime.CreateWithoutChecks(BigInteger.One << 2047);

            Assert.AreEqual(115, MultiplicativeGroupAlgebra.ComputeSecurityLevel(mod, mod));

            var smallOrder = BigPrime.CreateWithoutChecks(new BigInteger(4));

            Assert.AreEqual(2 * NumberLength.GetLength(smallOrder).InBits, MultiplicativeGroupAlgebra.ComputeSecurityLevel(mod, smallOrder));
        }
Esempio n. 3
0
        public void TestConstructorAndProperties()
        {
            var algebra = new XOnlyMontgomeryCurveAlgebra(curveParameters);

            Assert.AreEqual(curveParameters.Generator.X, algebra.Generator);
            Assert.AreEqual(curveParameters.Order, algebra.Order);
            Assert.AreEqual(curveParameters.Cofactor, algebra.Cofactor);
            Assert.AreEqual(NumberLength.GetLength(curveParameters.Equation.Field.Modulo).InBits, algebra.ElementBitLength);
            Assert.AreEqual(algebra.OrderBitLength / 2, algebra.SecurityLevel);
        }
 /// <summary>
 /// Initializes a new instance of <see cref="XOnlyMontgomeryCurveAlgebra"/>
 /// with given curve parameters.
 /// </summary>
 /// <param name="parameters">The parameters of the elliptic curve.</param>
 public XOnlyMontgomeryCurveAlgebra(CurveParameters parameters)
     : base(
         parameters.Generator.X,
         parameters.Order,
         parameters.Cofactor,
         BigInteger.Zero,
         NumberLength.GetLength(parameters.Equation.Field.Modulo).InBits
         )
 {
     _parameters = parameters;
     _aConstant  = Field.Mod((_parameters.Equation.A + 2) * Field.InvertMult(4));
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="MultiplicativeGroupAlgebra"/> class
 /// given the group's parameters.
 /// </summary>
 /// <param name="prime">The prime modulo of the group.</param>
 /// <param name="order">The order of the group.</param>
 /// <param name="generator">The generator of the group.</param>
 public MultiplicativeGroupAlgebra(BigPrime prime, BigPrime order, BigInteger generator)
     : base(
         generator,
         order,
         (prime - 1) / order,
         BigInteger.One,
         NumberLength.GetLength(prime).InBits
         )
 {
     Prime = prime;
     if (!IsSafeElement(generator))
     {
         throw new ArgumentException("The generator must be an element of the group.", nameof(generator));
     }
     SecurityLevel = ComputeSecurityLevel(prime, order);
 }
Esempio n. 6
0
 /// <summary>
 /// Initializes a new instance of the <see cref="CurveGroupAlgebra"/> class.
 /// </summary>
 /// <param name="parameters">The parameters of the elliptic curve.</param>
 public CurveGroupAlgebra(CurveParameters parameters)
     : base(
         parameters.Generator,
         parameters.Order,
         parameters.Cofactor,
         CurvePoint.PointAtInfinity,
         2 * NumberLength.GetLength(parameters.Equation.Field.Modulo).InBits
         )
 {
     _curveEquation = parameters.Equation;
     if (!IsSafeElement(Generator))
     {
         throw new ArgumentException("The point given as generator is " +
                                     "not a valid point on the curve.", nameof(parameters));
     }
 }
        /// <summary>
        /// Computes the security level of the multiplicative group.
        ///
        /// The security level is determined as the minimum of the respective
        /// security levels granted by the <paramref name="prime"/> modulus of
        /// the group and the <paramref name="order"/>.
        ///
        /// The first is estimated from the cost of computing the discrete logarithm (cf. [1])
        /// using the number field sieve, the second results from Pollard's Rho algorithm
        /// for discrete logarithms [2].
        ///
        /// [1]: D. Gordon: Discrete Logarithms in GF(P) Using the Number Field Sieve, https://doi.org/10.1137/0406010
        /// [2]: J. Pollard: Monte Carlo Methods For Index Computation (mod p), https://doi.org/10.1090/S0025-5718-1978-0491431-9
        /// </summary>
        /// <param name="prime">The prime modulo of the group.</param>
        /// <param name="order">The order of the group.</param>
        /// <returns>The security level (in bits).</returns>
        public static int ComputeSecurityLevel(BigPrime prime, BigPrime order)
        {
            // number field sieve strength
            int    primeBits     = NumberLength.GetLength(prime).InBits;
            double natLogPrime   = Math.Log(2) * primeBits;
            double sieveConstant = 1.9; // note(lumip): references give ~1.91+o(1); using 1.9 for a tiny bit of slack
                                        // (cf.L. Grémy, Sieve Algorithms for the Discrete Logarithm in Medium Characteristic Finite Fields,
                                        //               https://tel.archives-ouvertes.fr/tel-01647623/document )

            double natLogSieveLevel = sieveConstant * Math.Pow(natLogPrime, 1.0 / 3.0) * Math.Pow(Math.Log(natLogPrime), 2.0 / 3.0);
            int    sieveLevel       = (int)(natLogSieveLevel / Math.Log(2));

            // pollard rho strength
            int rhoLevel = NumberLength.GetLength(order).InBits * 2;

            return(Math.Min(sieveLevel, rhoLevel));
        }
        /// <summary>
        /// Computes the required bit length for prime modulus to achieve a desired security level.
        ///
        /// The required bit length for the modulus is found by solving the equation for expected
        /// runtime of the number field sieve algorithm [1] for the security parameter.
        ///
        /// /// [1]: D. Gordon: Discrete Logarithms in GF(P) Using the Number Field Sieve, https://doi.org/10.1137/0406010
        /// </summary>
        /// <param name="securityLevel">The desired security level (measured in bits).</param>
        public static NumberLength ComputePrimeLengthForSecurityLevel(int securityLevel)
        {
            // find minimum bit length l for Number field sieve
            // 1. solve number field sieve for z = ln ln (2^l) via Newton method
            double c = Math.Log(2) * securityLevel / 1.9;
            Func <double, double> f = (double z) =>
                                      c - Math.Exp((1.0 / 3.0) * z) * Math.Pow(z, 2.0 / 3.0);
            Func <double, double> df1 = (double z) =>
                                        - Math.Exp((1.0 / 3.0) * z) * ((1.0 / 3.0) * Math.Pow(z, 2.0 / 3.0) + 2.0 / (3.0 * Math.Pow(z, 1.0 / 3.0)));

            double[] z = new double[] { Math.Log(20 * securityLevel), double.PositiveInfinity };
            int      i = 0;

            while (Math.Abs(z[1 - i] - z[i]) > 1e-7)
            {
                z[1 - i] = z[i] - f(z[i]) / df1(z[i]);
                i        = 1 - i;
            }
            // 2. compute l from z
            int l = (int)Math.Ceiling(Math.Exp(z[i]) / Math.Log(2));

            l = Math.Max(l, 2 * securityLevel); // at least 2*securityLevel from Pollard Rho
            return(NumberLength.FromBitLength(l));
        }
 public void TestOrderBitLength()
 {
     Assert.That(groupAlgebra !.OrderBitLength == NumberLength.GetLength(order).InBits);
 }
 public void TestElementBitLength()
 {
     Assert.That(groupAlgebra !.ElementBitLength == NumberLength.GetLength(prime).InBits);
 }