public void TestLength() { var number = SecureBigNumber.FromBigNumber(new BigNumber(0x548f07)); var expected = NumberLength.FromBitLength(23);; Assert.That(number.Length.Equals(expected)); }
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)); }
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); }
/// <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); }