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