diff options
Diffstat (limited to 'crypto/src/math/ec/ECCurve.cs')
-rw-r--r-- | crypto/src/math/ec/ECCurve.cs | 146 |
1 files changed, 74 insertions, 72 deletions
diff --git a/crypto/src/math/ec/ECCurve.cs b/crypto/src/math/ec/ECCurve.cs index 3999ba4f0..624495051 100644 --- a/crypto/src/math/ec/ECCurve.cs +++ b/crypto/src/math/ec/ECCurve.cs @@ -675,9 +675,40 @@ namespace Org.BouncyCastle.Math.EC public abstract class AbstractFpCurve : ECCurve { + private static readonly HashSet<BigInteger> KnownQs = new HashSet<BigInteger>(); + protected AbstractFpCurve(BigInteger q) + : this(q, false) + { + } + + internal AbstractFpCurve(BigInteger q, bool isInternal) : base(FiniteFields.GetPrimeField(q)) { + if (!isInternal) + { + bool unknownQ; + lock (KnownQs) unknownQ = !KnownQs.Contains(q); + + if (unknownQ) + { + int maxBitLength = ImplGetInteger("Org.BouncyCastle.EC.Fp_MaxSize", 1042); // 2 * 521 + int certainty = ImplGetInteger("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, SecureRandom.ArbitraryRandom, + ImplGetNumberOfIterations(qBitLength, certainty))) + { + throw new ArgumentException("Fp q value not prime"); + } + } + } + + lock (KnownQs) KnownQs.Add(q); } public override bool IsValidFieldElement(BigInteger x) @@ -730,6 +761,47 @@ namespace Org.BouncyCastle.Math.EC return CreateRawPoint(x, y); } + private static int ImplGetInteger(string envVariable, int defaultValue) + { + string v = Platform.GetEnvironmentVariable(envVariable); + if (v == null) + return defaultValue; + + return int.Parse(v); + } + + private static int ImplGetNumberOfIterations(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; + } + } + private static BigInteger ImplRandomFieldElement(SecureRandom r, BigInteger p) { BigInteger x; @@ -761,8 +833,6 @@ namespace Org.BouncyCastle.Math.EC { private const int FP_DEFAULT_COORDS = COORD_JACOBIAN_MODIFIED; - private static readonly HashSet<BigInteger> KnownQs = new HashSet<BigInteger>(); - protected readonly BigInteger m_q, m_r; protected readonly FpPoint m_infinity; @@ -778,32 +848,8 @@ namespace Org.BouncyCastle.Math.EC } internal FpCurve(BigInteger q, BigInteger a, BigInteger b, BigInteger order, BigInteger cofactor, bool isInternal) - : base(q) + : base(q, isInternal) { - if (!isInternal) - { - bool unknownQ; - lock (KnownQs) unknownQ = !KnownQs.Contains(q); - - if (unknownQ) - { - 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, SecureRandom.ArbitraryRandom, - GetNumberOfIterations(qBitLength, certainty))) - { - throw new ArgumentException("Fp q value not prime"); - } - } - } - - lock (KnownQs) KnownQs.Add(q); this.m_q = q; this.m_r = FpFieldElement.CalculateResidue(q); @@ -818,7 +864,7 @@ namespace Org.BouncyCastle.Math.EC internal FpCurve(BigInteger q, BigInteger r, ECFieldElement a, ECFieldElement b, BigInteger order, BigInteger cofactor) - : base(q) + : base(q, true) { this.m_q = q; this.m_r = r; @@ -903,50 +949,6 @@ 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 int.Parse(v); - } } public abstract class AbstractF2mCurve |