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)); }
public void TestOrderBitLength() { Assert.That(groupAlgebra !.OrderBitLength == NumberLength.GetLength(order).InBits); }
public void TestElementBitLength() { Assert.That(groupAlgebra !.ElementBitLength == NumberLength.GetLength(prime).InBits); }