diff options
Diffstat (limited to 'crypto/src/math')
-rw-r--r-- | crypto/src/math/ec/ECCurve.cs | 82 |
1 files changed, 81 insertions, 1 deletions
diff --git a/crypto/src/math/ec/ECCurve.cs b/crypto/src/math/ec/ECCurve.cs index f011b1baf..2b193ba06 100644 --- a/crypto/src/math/ec/ECCurve.cs +++ b/crypto/src/math/ec/ECCurve.cs @@ -677,6 +677,9 @@ namespace Org.BouncyCastle.Math.EC { private const int FP_DEFAULT_COORDS = COORD_JACOBIAN_MODIFIED; + private static readonly IDictionary knownQs = Platform.CreateHashtable(); + private static readonly SecureRandom random = new SecureRandom(); + protected readonly BigInteger m_q, m_r; protected readonly FpPoint m_infinity; @@ -687,9 +690,42 @@ namespace Org.BouncyCastle.Math.EC } public FpCurve(BigInteger q, BigInteger a, BigInteger b, BigInteger order, BigInteger cofactor) + : this(q, a, b, order, cofactor, false) + { + } + + internal FpCurve(BigInteger q, BigInteger a, BigInteger b, BigInteger order, BigInteger cofactor, bool isInternal) : base(q) { - this.m_q = q; + if (isInternal) + { + this.m_q = q; + knownQs.add(q); + } + else if (knownQs.contains(q)) + { + this.m_q = q; + } + else + { + int maxBitLength = AsInteger("Org.BouncyCastle.EC.Fp_MaxSize", 1042); // 2 * 521 + int certainty = AsInteger("Org.BouncyCastle.EC.Fp_Certainty", 100); + + int qBitLength = q.BitLength; + if (maxBitLength < qBitLength) + { + throw new ArgumentException("Fp q value out of range"); + } + + if (Primes.HasAnySmallFactors(q) || !Primes.IsMRProbablePrime( + q, random, getNumberOfIterations(qBitLength, certainty))) + { + throw new ArgumentException("Fp q value not prime"); + } + + this.m_q = q; + } + this.m_r = FpFieldElement.CalculateResidue(q); this.m_infinity = new FpPoint(this, null, null, false); @@ -790,6 +826,50 @@ namespace Org.BouncyCastle.Math.EC return base.ImportPoint(p); } + + private int GetNumberOfIterations(int bits, int certainty) + { + /* + * NOTE: We enforce a minimum 'certainty' of 100 for bits >= 1024 (else 80). Where the + * certainty is higher than the FIPS 186-4 tables (C.2/C.3) cater to, extra iterations + * are added at the "worst case rate" for the excess. + */ + if (bits >= 1536) + { + return certainty <= 100 ? 3 + : certainty <= 128 ? 4 + : 4 + (certainty - 128 + 1) / 2; + } + else if (bits >= 1024) + { + return certainty <= 100 ? 4 + : certainty <= 112 ? 5 + : 5 + (certainty - 112 + 1) / 2; + } + else if (bits >= 512) + { + return certainty <= 80 ? 5 + : certainty <= 100 ? 7 + : 7 + (certainty - 100 + 1) / 2; + } + else + { + return certainty <= 80 ? 40 + : 40 + (certainty - 80 + 1) / 2; + } + } + + int AsInteger(string envVariable, int defaultValue) + { + String v = Platform.GetEnvironmentVariable(envVariable); + + if (v == null) + { + return defaultValue; + } + + return Int32.Parse(v); + } } public abstract class AbstractF2mCurve |